changeset 478:c7825b8c6145

Json: - Finalize iterators, - Add more tests, - Add more asserts.
author David Demelier <markand@malikania.fr>
date Tue, 10 Nov 2015 14:11:14 +0100
parents b681299e6987
children c7d83d2b462b
files C++/modules/Json/Json.cpp C++/modules/Json/Json.h C++/tests/Json/main.cpp
diffstat 3 files changed, 330 insertions(+), 184 deletions(-) [+]
line wrap: on
line diff
--- a/C++/modules/Json/Json.cpp	Mon Nov 09 16:52:38 2015 +0100
+++ b/C++/modules/Json/Json.cpp	Tue Nov 10 14:11:14 2015 +0100
@@ -112,26 +112,23 @@
 void Value::copy(const Value &other)
 {
 	switch (other.m_type) {
-	case Type::String:
-		new (&m_string) std::string();
-		m_string = std::move(other.m_string);
+	case Type::Array:
+		new (&m_array) std::deque<Value>(other.m_array);
 		break;
-	case Type::Real:
-		m_number = other.m_number;
+	case Type::Boolean:
+		m_boolean = other.m_boolean;
 		break;
 	case Type::Int:
 		m_integer = other.m_integer;
 		break;
-	case Type::Boolean:
-		m_boolean = other.m_boolean;
+	case Type::Object:
+		new (&m_object) std::map<std::string, Value>(other.m_object);
 		break;
-	case Type::Object:
-		new (&m_object) std::map<std::string, Value>();
-		m_object = std::move(other.m_object);
+	case Type::Real:
+		m_number = other.m_number;
 		break;
-	case Type::Array:
-		new (&m_array) std::deque<Value>();
-		m_array = std::move(other.m_array);
+	case Type::String:
+		new (&m_string) std::string(other.m_string);
 		break;
 	default:
 		break;
@@ -143,23 +140,23 @@
 void Value::move(Value &&other)
 {
 	switch (other.m_type) {
-	case Type::String:
-		new (&m_string) std::string(std::move(other.m_string));
+	case Type::Array:
+		new (&m_array) std::deque<Value>(std::move(other.m_array));
 		break;
-	case Type::Real:
-		m_number = other.m_number;
+	case Type::Boolean:
+		m_boolean = other.m_boolean;
 		break;
 	case Type::Int:
 		m_integer = other.m_integer;
 		break;
-	case Type::Boolean:
-		m_boolean = other.m_boolean;
-		break;
 	case Type::Object:
 		new (&m_object) std::map<std::string, Value>(std::move(other.m_object));
 		break;
-	case Type::Array:
-		new (&m_array) std::deque<Value>(std::move(other.m_array));
+	case Type::Real:
+		m_number = other.m_number;
+		break;
+	case Type::String:
+		new (&m_string) std::string(std::move(other.m_string));
 		break;
 	default:
 		break;
@@ -171,24 +168,24 @@
 Value::Value(Type type)
 	: m_type{type}
 {
-	switch (type) {
-	case Type::String:
-		new (&m_string) std::string();
-		break;
+	switch (m_type) {
 	case Type::Array:
 		new (&m_array) std::deque<Value>();
 		break;
+	case Type::Boolean:
+		m_boolean = false;
+		break;
+	case Type::Int:
+		m_integer = 0;
+		break;
 	case Type::Object:
 		new (&m_object) std::map<std::string, Value>();
 		break;
 	case Type::Real:
 		m_number = 0;
 		break;
-	case Type::Int:
-		m_integer = 0;
-		break;
-	case Type::Boolean:
-		m_boolean = false;
+	case Type::String:
+		new (&m_string) std::string();
 		break;
 	default:
 		break;
@@ -198,14 +195,14 @@
 Value::~Value()
 {
 	switch (m_type) {
-	case Type::String:
-		m_string.~basic_string();
+	case Type::Array:
+		m_array.~deque<Value>();
 		break;
 	case Type::Object:
 		m_object.~map<std::string, Value>();
 		break;
-	case Type::Array:
-		m_array.~deque<Value>();
+	case Type::String:
+		m_string.~basic_string();
 		break;
 	default:
 		break;
--- a/C++/modules/Json/Json.h	Mon Nov 09 16:52:38 2015 +0100
+++ b/C++/modules/Json/Json.h	Tue Nov 10 14:11:14 2015 +0100
@@ -185,9 +185,20 @@
 	void copy(const Value &);
 	void move(Value &&);
 
+	/**
+	 * @class BaseIterator
+	 * @brief This is the base class for iterator and const_iterator
+	 *
+	 * This iterator works for both arrays and objects. Because of that purpose, it is only available
+	 * as forward iterator.
+	 *
+	 * When iterator comes from an object, you can use key() otherwise you can use index().
+	 */
 	template <typename ValueType, typename ArrayIteratorType, typename ObjectIteratorType>
-	class BaseIterator {
+	class BaseIterator : public std::iterator<std::forward_iterator_tag, ValueType> {
 	private:
+		friend class Value;
+
 		ValueType &m_value;
 		ArrayIteratorType m_ita;
 		ObjectIteratorType m_itm;
@@ -201,17 +212,19 @@
 			}
 		}
 
-	public:
-		explicit BaseIterator(ValueType &value, bool end = false)
+		BaseIterator(ValueType &value, ObjectIteratorType it)
 			: m_value(value)
+			, m_itm(it)
 		{
-			if (m_value.isObject()) {
-				m_itm = (end) ? m_value.m_object.end() : m_value.m_object.begin();
-			} else {
-				m_ita = (end) ? m_value.m_array.end() : m_value.m_array.begin();
-			}
 		}
 
+		BaseIterator(ValueType &value, ArrayIteratorType it)
+			: m_value(value)
+			, m_ita(it)
+		{
+		}
+
+	public:
 		/**
 		 * Get the iterator key (for objects).
 		 *
@@ -253,11 +266,7 @@
 			assert((m_value.isArray()  && m_ita != m_value.m_array.end()) ||
 			       (m_value.isObject() && m_itm != m_value.m_object.end()));
 
-			if (m_value.isObject()) {
-				return m_itm->second;
-			}
-
-			return *m_ita;
+			return (m_value.m_type == Type::Object) ? m_itm->second : *m_ita;
 		}
 
 		/**
@@ -268,7 +277,10 @@
 		 */
 		inline ValueType *operator->() noexcept
 		{
-			return &(*this);
+			assert((m_value.isArray()  && m_ita != m_value.m_array.end()) ||
+			       (m_value.isObject() && m_itm != m_value.m_object.end()));
+
+			return (m_value.m_type == Type::Object) ? &m_itm->second : &(*m_ita);
 		}
 
 		/**
@@ -332,7 +344,14 @@
 		}
 	};
 
+	/**
+	 * Forward iterator.
+	 */
 	using iterator = BaseIterator<Value, typename std::deque<Value>::iterator, typename std::map<std::string, Value>::iterator>;
+
+	/**
+	 * Const forward iterator.
+	 */
 	using const_iterator = BaseIterator<const Value, typename std::deque<Value>::const_iterator, typename std::map<std::string, Value>::const_iterator>;
 
 public:
@@ -344,22 +363,6 @@
 	}
 
 	/**
-	 * Construct a value from a buffer.
-	 *
-	 * @param buffer the text
-	 * @throw Error on errors
-	 */
-	Value(const Buffer &buffer);
-
-	/**
-	 * Construct a value from a file.
-	 *
-	 * @param file the file
-	 * @throw Error on errors
-	 */
-	Value(const File &file);
-
-	/**
 	 * Create a value with a specified type, this is usually only needed when you want to create an object or
 	 * an array.
 	 *
@@ -407,7 +410,7 @@
 	inline Value(const char *value)
 		: m_type{Type::String}
 	{
-		new (&m_string) std::string{value};
+		new (&m_string) std::string{value ? value : ""};
 	}
 
 	/**
@@ -433,6 +436,50 @@
 	}
 
 	/**
+	 * Create an object from a map.
+	 *
+	 * @param values the values
+	 * @see fromObject
+	 */
+	inline Value(std::map<std::string, Value> values)
+		: Value{Type::Object}
+	{
+		for (const auto &pair : values) {
+			insert(pair.first, pair.second);
+		}
+	}
+
+	/**
+	 * Create an array from a deque.
+	 *
+	 * @param values the values
+	 * @see fromArray
+	 */
+	inline Value(std::deque<Value> values)
+		: Value{Type::Array}
+	{
+		for (Value value : values) {
+			append(std::move(value));
+		}
+	}
+
+	/**
+	 * Construct a value from a buffer.
+	 *
+	 * @param buffer the text
+	 * @throw Error on errors
+	 */
+	Value(const Buffer &buffer);
+
+	/**
+	 * Construct a value from a file.
+	 *
+	 * @param file the file
+	 * @throw Error on errors
+	 */
+	Value(const File &file);
+
+	/**
 	 * Move constructor.
 	 *
 	 * @param other the value to move from
@@ -482,34 +529,82 @@
 	 */
 	~Value();
 
+	/**
+	 * Get an iterator to the beginning.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline iterator begin() noexcept
 	{
-		return iterator(*this);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? iterator(*this, m_object.begin()) : iterator(*this, m_array.begin());
 	}
 
+	/**
+	 * Overloaded function.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline const_iterator begin() const noexcept
 	{
-		return const_iterator(*this);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? const_iterator(*this, m_object.begin()) : const_iterator(*this, m_array.begin());
 	}
 
+	/**
+	 * Overloaded function.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline const_iterator cbegin() const noexcept
 	{
-		return const_iterator(*this);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? const_iterator(*this, m_object.cbegin()) : const_iterator(*this, m_array.cbegin());
 	}
 
+	/**
+	 * Get an iterator to the end.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline iterator end() noexcept
 	{
-		return iterator(*this, true);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? iterator(*this, m_object.end()) : iterator(*this, m_array.end());
 	}
 
+	/**
+	 * Get an iterator to the end.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline const_iterator end() const noexcept
 	{
-		return const_iterator(*this, true);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? const_iterator(*this, m_object.end()) : const_iterator(*this, m_array.end());
 	}
 
+	/**
+	 * Get an iterator to the end.
+	 *
+	 * @pre must be an array or object
+	 * @return the iterator
+	 */
 	inline const_iterator cend() const noexcept
 	{
-		return const_iterator(*this, true);
+		assert(isArray() || isObject());
+
+		return m_type == Type::Object ? const_iterator(*this, m_object.cend()) : const_iterator(*this, m_array.cend());
 	}
 
 	/**
@@ -921,6 +1016,48 @@
 	}
 
 	/**
+	 * Get a value from the object.
+	 *
+	 * @pre must be an object
+	 * @param name the value key
+	 * @return the value
+	 */
+	inline const Value &operator[](const std::string &name) const
+	{
+		assert(isObject());
+
+		return m_object.at(name);
+	}
+
+	/**
+	 * Find a value by key.
+	 *
+	 * @pre must be an object
+	 * @param key the property key
+	 * @return the iterator or past the end if not found
+	 */
+	inline iterator find(const std::string &key)
+	{
+		assert(isObject());
+
+		return iterator(*this, m_object.find(key));
+	}
+
+	/**
+	 * Overloaded function.
+	 *
+	 * @pre must be an object
+	 * @param key the property key
+	 * @return the iterator or past the end if not found
+	 */
+	inline const_iterator find(const std::string &key) const
+	{
+		assert(isObject());
+
+		return const_iterator(*this, m_object.find(key));
+	}
+
+	/**
 	 * Insert a new value.
 	 *
 	 * @pre must be an object
@@ -929,6 +1066,8 @@
 	 */
 	inline void insert(std::string name, const Value &value)
 	{
+		assert(isObject());
+
 		m_object.insert({std::move(name), value});
 	}
 
@@ -941,27 +1080,35 @@
 	 */
 	inline void insert(std::string name, Value &&value)
 	{
+		assert(isObject());
+
 		m_object.insert({std::move(name), std::move(value)});
 	}
 
 	/**
 	 * Check if a value exists.
 	 *
+	 * @pre must be an object
 	 * @param key the key value
 	 * @return true if exists
 	 */
 	inline bool contains(const std::string &key) const noexcept
 	{
+		assert(isObject());
+
 		return m_object.find(key) != m_object.end();
 	}
 
 	/**
 	 * Remove a value of the specified key.
 	 *
+	 * @pre must be an object
 	 * @param key the value key
 	 */
 	inline void erase(const std::string &key)
 	{
+		assert(isObject());
+
 		m_object.erase(key);
 	}
 };
@@ -974,6 +1121,28 @@
  */
 std::string escape(const std::string &input);
 
+/**
+ * Convenient function for creating array from initializer list.
+ *
+ * @param values the values
+ * @return the array
+ */
+inline Value array(std::initializer_list<Value> values)
+{
+	return Value(std::deque<Value>(values.begin(), values.end()));
+}
+
+/**
+ * Convenient function for creating object from initializer list.
+ *
+ * @param values the values
+ * @return the object
+ */
+inline Value object(std::initializer_list<std::pair<std::string, Value>> values)
+{
+	return Value(std::map<std::string, Value>(values.begin(), values.end()));
+}
+
 } // !json
 
 #endif // !_JSON_H_
--- a/C++/tests/Json/main.cpp	Mon Nov 09 16:52:38 2015 +0100
+++ b/C++/tests/Json/main.cpp	Tue Nov 10 14:11:14 2015 +0100
@@ -23,9 +23,10 @@
 
 #include "Json.h"
 
-/* --------------------------------------------------------
+/*
  * Miscellaneous
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 TEST(Misc, copy)
 {
@@ -87,9 +88,10 @@
 	ASSERT_EQ(expected, json::escape(input));
 }
 
-/* --------------------------------------------------------
+/*
  * json::Value constructors
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 TEST(Constructors, null)
 {
@@ -154,9 +156,10 @@
 	}
 }
 
-/* --------------------------------------------------------
+/*
  * Object
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 TEST(Object, set)
 {
@@ -215,15 +218,13 @@
 	}
 }
 
-#if 0
-
 TEST(Object, valueOr)
 {
 	try {
-		json::Object object{
+		json::Value object = json::object({
 			{ "x", 10 },
 			{ "y", 20 }
-		};
+		});
 
 		ASSERT_EQ(10, object.valueOr("x", -9999).toInt());
 		ASSERT_EQ(20, object.valueOr("y", -9999).toInt());
@@ -236,10 +237,10 @@
 TEST(ObjectInitializer, simple)
 {
 	try {
-		json::Object object{
+		json::Value object = json::object({
 			{ "username", "jean"	},
 			{ "age", 99		}
-		};
+		});
 
 		ASSERT_EQ(2, static_cast<int>(object.size()));
 		ASSERT_EQ("jean", object["username"].toString());
@@ -252,15 +253,15 @@
 TEST(ObjectInitializer, deep)
 {
 	try {
-		json::Object object{
+		json::Value object = json::object({
 			{ "username", "jean"		},
 			{ "age", 99			},
-			{ "network", json::Object{
+			{ "network", json::object({
 					{ "port", 9999 		},
 					{ "host", "localhost"	}
-				}
+				})
 			}
-		};
+		});
 
 		// First
 		ASSERT_EQ(3, static_cast<int>(object.size()));
@@ -268,7 +269,7 @@
 		ASSERT_EQ(99, object["age"].toInt());
 
 		// Second
-		json::Object network = object["network"].toObject();
+		const json::Value &network = object["network"];
 		ASSERT_TRUE(network.isObject());
 		ASSERT_EQ(2, static_cast<int>(network.size()));
 		ASSERT_EQ(9999, network["port"].toInt());
@@ -278,11 +279,10 @@
 	}
 }
 
-#endif
-
-/* --------------------------------------------------------
+/*
  * Array
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 TEST(Array, push)
 {
@@ -380,12 +380,10 @@
 	}
 }
 
-#if 0
-
 TEST(Array, valueOr)
 {
 	try {
-		json::Array array{-10, -20};
+		json::Value array = json::array({-10, -20});
 
 		ASSERT_EQ(-10, array.valueOr(0, -9999).toInt());
 		ASSERT_EQ(-20, array.valueOr(1, -9999).toInt());
@@ -398,7 +396,7 @@
 TEST(ArrayInitializer, simple)
 {
 	try {
-		json::Array array{123, true, "hello"};
+		json::Value array = json::array({123, true, "hello"});
 
 		ASSERT_EQ(3, static_cast<int>(array.size()));
 		ASSERT_EQ(123, array[0].toInt());
@@ -412,16 +410,16 @@
 TEST(ArrayInitializer, deep)
 {
 	try {
-		json::Array array{
+		json::Value array = json::array({
 			123,
 			true,
 			"hello",
-			json::Array{
+			json::array({
 				321,
 				false,
 				"olleh"
-			}
-		};
+			})
+		});
 
 		// First
 		ASSERT_EQ(4, static_cast<int>(array.size()));
@@ -430,7 +428,7 @@
 		ASSERT_EQ("hello", array[2].toString());
 
 		// Second
-		json::Array array2 = array[3].toArray();
+		const json::Value &array2 = array[3];
 		ASSERT_TRUE(array.isArray());
 		ASSERT_EQ(3, static_cast<int>(array2.size()));
 		ASSERT_EQ(321, array2[0].toInt());
@@ -441,11 +439,10 @@
 	}
 }
 
-#endif
-
-/* --------------------------------------------------------
+/*
  * I/O
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 TEST(FileRead, simple)
 {
@@ -491,22 +488,21 @@
 	}
 }
 
-#if 0
-
-/* --------------------------------------------------------
+/*
  * Object read
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 class ObjectRead : public testing::Test {
 protected:
-	json::Object m_object;
-	json::Object m_objectAll;
+	json::Value m_object;
+	json::Value m_objectAll;
 
 public:
 	ObjectRead()
+		: m_object(json::File{"Json/object.json"})
+		, m_objectAll(json::File{"Json/object-all.json"})
 	{
-		m_object = json::Document(json::File{"Json/object.json"}).toObject();
-		m_objectAll = json::Document(json::File{"Json/object-all.json"}).toObject();
 	}
 };
 
@@ -556,20 +552,21 @@
 	}
 }
 
-/* --------------------------------------------------------
+/*
  * Array read
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 class ArrayRead : public testing::Test {
 protected:
-	json::Array m_array;
-	json::Array m_arrayAll;
+	json::Value m_array;
+	json::Value m_arrayAll;
 
 public:
 	ArrayRead()
+		: m_array(json::File{"Json/array.json"})
+		, m_arrayAll(json::File{"Json/array-all.json"})
 	{
-		m_array = json::Document(json::File{"Json/array.json"}).toArray();
-		m_arrayAll = json::Document(json::File{"Json/array-all.json"}).toArray();
 	}
 };
 
@@ -613,13 +610,14 @@
 	}
 }
 
-/* --------------------------------------------------------
+/*
  * Object iterators
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 class ObjectIteratorsTest : public testing::Test {
 protected:
-	json::Object m_object;
+	json::Value m_object{json::Type::Object};
 
 public:
 	ObjectIteratorsTest()
@@ -641,8 +639,9 @@
 		auto end = m_object.end();
 
 		while (it != end) {
-			values.insert({it->first, it->second});
-			result.insert((*it++).first);
+			values.insert({it.key(), *it});
+			result.insert(it.key());
+			it++;
 		}
 
 		ASSERT_EQ(expected, result);
@@ -660,8 +659,9 @@
 		auto end = m_object.cend();
 
 		while (it != end) {
-			values.insert({it->first, it->second});
-			result.insert((*it++).first);
+			values.insert({it.key(), *it});
+			result.insert(it.key());
+			it++;
 		}
 
 		ASSERT_EQ(expected, result);
@@ -676,23 +676,39 @@
 	// Assign (non const)
 	{
 		auto it = m_object.begin();
-		auto key = it->first;
+		auto key = it.key();
 
-		it->second = json::Value("CHANGED");
+		*it = json::Value("CHANGED");
 
 		ASSERT_EQ("CHANGED", m_object[key].toString());
-		ASSERT_EQ("CHANGED", it->second.toString());
+		ASSERT_EQ("CHANGED", it->toString());
 		ASSERT_EQ(3, static_cast<int>(m_object.size()));
 	}
 }
 
-/* --------------------------------------------------------
+TEST_F(ObjectIteratorsTest, find)
+{
+	auto it = m_object.find("integer");
+
+	ASSERT_TRUE(it != m_object.end());
+	ASSERT_EQ(1, it->toInt());
+}
+
+TEST_F(ObjectIteratorsTest, find2)
+{
+	auto it = m_object.find("not exists");
+
+	ASSERT_TRUE(it == m_object.end());
+}
+
+/*
  * Array iterators
- * -------------------------------------------------------- */
+ * ------------------------------------------------------------------
+ */
 
 class ArrayIteratorsTest : public testing::Test {
 protected:
-	json::Array m_array;
+	json::Value m_array{json::Type::Array};
 
 public:
 	ArrayIteratorsTest()
@@ -709,68 +725,34 @@
 	{
 		auto it = m_array.begin();
 
+		// 1
 		ASSERT_EQ(1, (*it).toInt());
 		ASSERT_EQ(1, it->toInt());
-		ASSERT_EQ("hello", it[1].toString());
-		ASSERT_TRUE(it[2].toBool());
-
-		auto it2 = it + 1;
-		ASSERT_EQ(1, it2[-1].toInt());
-		ASSERT_EQ("hello", it2->toString());
-		ASSERT_TRUE(it2[1].toBool());
-
-		auto it3 = it;
-		ASSERT_TRUE(it2 != it);
-		ASSERT_FALSE(it3 != it);
 
-		ASSERT_FALSE(it2 == it);
-		ASSERT_TRUE(it3 == it);
-
-		ASSERT_TRUE(it3 >= it);
-		ASSERT_TRUE(it2 >= it);
+		// "hello"
+		it++;
+		ASSERT_EQ("hello", it->toString());
 
-		ASSERT_TRUE(it2 > it);
-		ASSERT_FALSE(it3 > it);
-
-		ASSERT_FALSE(it2 <= it);
-		ASSERT_TRUE(it3 <= it);
-
-		ASSERT_FALSE(it2 < it);
-		ASSERT_FALSE(it3 < it);
+		// true
+		it++;
+		ASSERT_TRUE(it->toBool());
 	}
 
 	// Read only (const)
 	{
 		auto it = m_array.cbegin();
 
+		// 1
 		ASSERT_EQ(1, (*it).toInt());
 		ASSERT_EQ(1, it->toInt());
-		ASSERT_EQ("hello", it[1].toString());
-		ASSERT_TRUE(it[2].toBool());
-
-		auto it2 = it + 1;
-		ASSERT_EQ(1, it2[-1].toInt());
-		ASSERT_EQ("hello", it2->toString());
-		ASSERT_TRUE(it2[1].toBool());
-
-		auto it3 = it;
-		ASSERT_TRUE(it2 != it);
-		ASSERT_FALSE(it3 != it);
 
-		ASSERT_FALSE(it2 == it);
-		ASSERT_TRUE(it3 == it);
-
-		ASSERT_TRUE(it3 >= it);
-		ASSERT_TRUE(it2 >= it);
+		// "hello"
+		it++;
+		ASSERT_EQ("hello", it->toString());
 
-		ASSERT_TRUE(it2 > it);
-		ASSERT_FALSE(it3 > it);
-
-		ASSERT_FALSE(it2 <= it);
-		ASSERT_TRUE(it3 <= it);
-
-		ASSERT_FALSE(it2 < it);
-		ASSERT_FALSE(it3 < it);
+		// true
+		it++;
+		ASSERT_TRUE(it->toBool());
 	}
 }
 
@@ -790,7 +772,7 @@
 
 TEST_F(ArrayIteratorsTest, castToRef)
 {
-	json::Array array{1, 2, 3};
+	json::Value array = json::array({1, 2, 3});
 	int i = 1;
 
 	for (const json::Value &v : array) {
@@ -798,8 +780,6 @@
 	}
 }
 
-#endif
-
 int main(int argc, char **argv)
 {
 	testing::InitGoogleTest(&argc, argv);