Skip to content

Commit f178bfd

Browse files
committed
More tests, allow direct comparison with empty_array/empty_object
1 parent eafddd0 commit f178bfd

File tree

3 files changed

+62
-12
lines changed

3 files changed

+62
-12
lines changed

include/tao/json/internal/totally_ordered.hh

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ namespace tao
6262
}
6363
};
6464

65-
6665
template< typename T >
6766
struct totally_ordered< T, null_t, type::NULL_ >
6867
: operators::totally_ordered< T, null_t >
@@ -315,6 +314,46 @@ namespace tao
315314
}
316315
};
317316

317+
template< typename T >
318+
struct totally_ordered< T, empty_array_t, type::ARRAY >
319+
: operators::totally_ordered< T, empty_array_t >
320+
{
321+
friend bool operator==( const T & lhs, empty_array_t rhs ) noexcept
322+
{
323+
return lhs == T( rhs );
324+
}
325+
326+
friend bool operator<( const T & lhs, empty_array_t rhs ) noexcept
327+
{
328+
return lhs < T( rhs );
329+
}
330+
331+
friend bool operator>( const T & lhs, empty_array_t rhs ) noexcept
332+
{
333+
return lhs > T( rhs );
334+
}
335+
};
336+
337+
template< typename T >
338+
struct totally_ordered< T, empty_object_t, type::OBJECT >
339+
: operators::totally_ordered< T, empty_object_t >
340+
{
341+
friend bool operator==( const T & lhs, empty_object_t rhs ) noexcept
342+
{
343+
return lhs == T( rhs );
344+
}
345+
346+
friend bool operator<( const T & lhs, empty_object_t rhs ) noexcept
347+
{
348+
return lhs < T( rhs );
349+
}
350+
351+
friend bool operator>( const T & lhs, empty_object_t rhs ) noexcept
352+
{
353+
return lhs > T( rhs );
354+
}
355+
};
356+
318357
} // internal
319358

320359
} // json

include/tao/json/value.hh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,9 @@ namespace tao
5454
internal::totally_ordered< basic_value< Traits >, std::string, type::STRING >,
5555
internal::totally_ordered< basic_value< Traits >, const char *, type::STRING >,
5656
internal::totally_ordered< basic_value< Traits >, std::vector< basic_value< Traits > >, type::ARRAY >,
57-
internal::totally_ordered< basic_value< Traits >, std::map< std::string, basic_value< Traits > >, type::OBJECT >
57+
internal::totally_ordered< basic_value< Traits >, empty_array_t, type::ARRAY >,
58+
internal::totally_ordered< basic_value< Traits >, std::map< std::string, basic_value< Traits > >, type::OBJECT >,
59+
internal::totally_ordered< basic_value< Traits >, empty_object_t, type::OBJECT >
5860
{
5961
public:
6062
basic_value() noexcept
@@ -494,6 +496,9 @@ namespace tao
494496
return v.m_union.a.back();
495497
}
496498
const auto i = internal::json_pointer_token_to_index( t );
499+
if ( i >= v.m_union.a.size() ) {
500+
throw std::out_of_range( "array index too large" );
501+
}
497502
v.m_union.a.insert( v.m_union.a.begin() + i, std::move( value ) );
498503
return v.m_union.a.at( i );
499504
}

src/test/json/json_patch.cc

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace tao
1414
void unit_test()
1515
{
1616
const value a = { { "a", { { "foo", 1 } } } };
17-
const value b = { { "b", value::array( { 1, 2, 3, 4, 5 } ) } };
17+
const value b = { { "b", value::array( { 1, 2, 3, 4 } ) } };
1818
const value q = { { "q", { { "bar", 2 } } } };
1919

2020
TEST_ASSERT( patch( {}, value::array( {} ) ) == null );
@@ -30,25 +30,31 @@ namespace tao
3030
TEST_THROWS( patch( a, value::array( { { { "op", "test" }, { "path", "" }, { "value", 42 } } } ) ) );
3131
TEST_THROWS( patch( a, value::array( { { { "op", "test" }, { "path", "/a" }, { "value", 42 } } } ) ) );
3232

33-
TEST_ASSERT( patch( a, value::array( { { { "op", "remove" }, { "path", "/a" } } } ) ) == value( empty_object ) ); // TODO: allow comparison against empty_object directly
33+
TEST_ASSERT( patch( a, value::array( { { { "op", "remove" }, { "path", "/a" } } } ) ) == empty_object );
3434
TEST_ASSERT( patch( a, value::array( { { { "op", "remove" }, { "path", "/a/foo" } } } ) ) == value( { { "a", empty_object } } ) );
3535
TEST_THROWS( patch( a, value::array( { { { "op", "remove" }, { "path", "/q" } } } ) ) );
3636
TEST_THROWS( patch( a, value::array( { { { "op", "remove" }, { "path", "" } } } ) ) ); // TODO: clarify correctness
37-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b" } } } ) ) == value( empty_object ) ); // TODO: allow comparison against empty_object directly
38-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/0" } } } ) ) == value( { { "b", value::array( { 2, 3, 4, 5 } ) } } ) );
39-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/1" } } } ) ) == value( { { "b", value::array( { 1, 3, 4, 5 } ) } } ) );
40-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/2" } } } ) ) == value( { { "b", value::array( { 1, 2, 4, 5 } ) } } ) );
41-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/3" } } } ) ) == value( { { "b", value::array( { 1, 2, 3, 5 } ) } } ) );
42-
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/4" } } } ) ) == value( { { "b", value::array( { 1, 2, 3, 4 } ) } } ) );
43-
TEST_THROWS( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/5" } } } ) ) );
37+
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b" } } } ) ) == empty_object );
38+
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/0" } } } ) ) == value( { { "b", value::array( { 2, 3, 4 } ) } } ) );
39+
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/1" } } } ) ) == value( { { "b", value::array( { 1, 3, 4 } ) } } ) );
40+
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/2" } } } ) ) == value( { { "b", value::array( { 1, 2, 4 } ) } } ) );
41+
TEST_ASSERT( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/3" } } } ) ) == value( { { "b", value::array( { 1, 2, 3 } ) } } ) );
42+
TEST_THROWS( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/4" } } } ) ) );
4443
TEST_THROWS( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/-" } } } ) ) );
4544
TEST_THROWS( patch( b, value::array( { { { "op", "remove" }, { "path", "/b/a" } } } ) ) );
4645
TEST_THROWS( patch( b, value::array( { { { "op", "remove" }, { "path", "/a" } } } ) ) );
4746
TEST_THROWS( patch( q, value::array( { { { "op", "remove" }, { "path", "/a" } } } ) ) );
4847

4948
TEST_ASSERT( patch( a, value::array( { { { "op", "add" }, { "path", "/b" }, { "value", 42 } } } ) ) == value( { { "a", { { "foo", 1 } } }, { "b", 42 } } ) );
5049
TEST_ASSERT( patch( a, value::array( { { { "op", "add" }, { "path", "/a/b" }, { "value", 42 } } } ) ) == value( { { "a", { { "foo", 1 }, { "b", 42 } } } } ) );
51-
TEST_THROWS( patch( a, value::array( { { { "op", "add" }, { "path", "" }, { "value", 42 } } } ) ) ); // TODO: clarify correctness
50+
TEST_THROWS( patch( a, value::array( { { { "op", "add" }, { "path", "" }, { "value", 42 } } } ) ) );
51+
TEST_ASSERT( patch( b, value::array( { { { "op", "add" }, { "path", "/b/0" }, { "value", 42 } } } ) ) == value( { { "b", value::array( { 42, 1, 2, 3, 4 } ) } } ) );
52+
TEST_ASSERT( patch( b, value::array( { { { "op", "add" }, { "path", "/b/1" }, { "value", 42 } } } ) ) == value( { { "b", value::array( { 1, 42, 2, 3, 4 } ) } } ) );
53+
TEST_ASSERT( patch( b, value::array( { { { "op", "add" }, { "path", "/b/2" }, { "value", 42 } } } ) ) == value( { { "b", value::array( { 1, 2, 42, 3, 4 } ) } } ) );
54+
TEST_ASSERT( patch( b, value::array( { { { "op", "add" }, { "path", "/b/3" }, { "value", 42 } } } ) ) == value( { { "b", value::array( { 1, 2, 3, 42, 4 } ) } } ) );
55+
TEST_ASSERT( patch( b, value::array( { { { "op", "add" }, { "path", "/b/-" }, { "value", 42 } } } ) ) == value( { { "b", value::array( { 1, 2, 3, 4, 42 } ) } } ) );
56+
TEST_THROWS( patch( b, value::array( { { { "op", "add" }, { "path", "/b/4" }, { "value", 42 } } } ) ) );
57+
TEST_THROWS( patch( b, value::array( { { { "op", "add" }, { "path", "/b/a" }, { "value", 42 } } } ) ) );
5258
TEST_THROWS( patch( q, value::array( { { { "op", "add" }, { "path", "/a/b" }, { "value", 42 } } } ) ) );
5359

5460
// TODO: Way more tests...

0 commit comments

Comments
 (0)