| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- #include <cstdlib>
- #include <stdexcept>
- #include <type_traits>
- #include <gmock/gmock.h>
- #include <gtest/gtest.h>
- #include <json/value.h>
- #include <jvalidate/adapters/jsoncpp.h>
- #include <jvalidate/detail/anchor.h>
- #include <jvalidate/detail/number.h>
- #include <jvalidate/detail/pointer.h>
- #include <jvalidate/detail/reference.h>
- #include <jvalidate/detail/relative_pointer.h>
- #include <jvalidate/detail/string.h>
- #include <jvalidate/detail/string_adapter.h>
- #include <jvalidate/enum.h>
- #include <jvalidate/status.h>
- #include <jvalidate/uri.h>
- #include "matchers.h"
- using namespace jvalidate::detail;
- using JsonCppAdapter = jvalidate::adapter::JsonCppAdapter<Json::Value const>;
- using jvalidate::adapter::Type;
- using testing::Eq;
- using testing::HasSubstr;
- using testing::Test;
- using testing::Types;
- using testing::VariantWith;
- TEST(AnchorTest, PermitsEmpty) { EXPECT_NO_THROW(Anchor("")); }
- TEST(AnchorTest, PermitsFirstCharWord) { EXPECT_NO_THROW(Anchor("here")); }
- TEST(AnchorTest, PermitsFirstCharUnderscore) { EXPECT_NO_THROW(Anchor("_here")); }
- TEST(AnchorTest, ForbidsFirstCharNumber) { EXPECT_THROW(Anchor("0here"), std::runtime_error); }
- TEST(AnchorTest, AllowsDotDashAlnum) { EXPECT_NO_THROW(Anchor("here.0-_")); }
- TEST(AnchorTest, ForbidsSpecial) { EXPECT_THROW(Anchor("h$"), std::runtime_error); }
- TEST(AnchorTest, CanViewString) { EXPECT_THAT(static_cast<std::string>(Anchor("here")), "here"); }
- TEST(AnchorTest, Print) { EXPECT_THAT(testing::PrintToString(Anchor("here")), "here"); }
- TEST(PointerTest, BackCoercesIntToString) {
- EXPECT_THAT("/0"_jptr.back(), "0");
- EXPECT_THAT("/A"_jptr.back(), "A");
- }
- TEST(PointerTest, BackIsEmptySafe) { EXPECT_THAT(""_jptr.back(), ""); }
- TEST(PointerTest, ForbidsBadTilde) {
- EXPECT_THAT(Pointer::parse("/~1"), Expected(testing::_));
- EXPECT_THAT(Pointer::parse("/~2"), Unexpected(HasSubstr("illegal tilde")));
- }
- TEST(PointerTest, CanConcatenate) { EXPECT_THAT("/A"_jptr / "/B"_jptr, "/A/B"_jptr); }
- TEST(PointerTest, CanGoToParent) { EXPECT_THAT("/A/B"_jptr / parent, "/A"_jptr); }
- TEST(PointerTest, Print) { EXPECT_THAT(testing::PrintToString("/B/0/A"_jptr), "/B/0/A"); }
- TEST(RelatvivePointerTest, CannotPrefixWithZero) {
- EXPECT_THAT(RelativePointer::parse("01"), Unexpected("Cannot zero-prefix a relative pointer"));
- }
- TEST(RelatvivePointerTest, Print) {
- EXPECT_THAT(testing::PrintToString("0"_relptr), "0");
- EXPECT_THAT(testing::PrintToString("1#"_relptr), "1#");
- EXPECT_THAT(testing::PrintToString("1/B/0/A"_relptr), "1/B/0/A");
- }
- TEST(RelatvivePointerTest, ZeroIsHere) {
- Json::Value json;
- json["A"] = 1;
- EXPECT_THAT("0"_relptr.inspect("/A"_jptr, JsonCppAdapter(json)),
- VariantWith<JsonCppAdapter>(JsonCppAdapter(json["A"])));
- }
- TEST(RelatvivePointerTest, CanWalkBackwards) {
- Json::Value json;
- json["A"] = 1;
- EXPECT_THAT("1"_relptr.inspect("/A"_jptr, JsonCppAdapter(json)),
- VariantWith<JsonCppAdapter>(JsonCppAdapter(json)));
- }
- TEST(RelatvivePointerTest, CanFetchKey) {
- Json::Value json;
- json["A"] = 1;
- EXPECT_THAT("0#"_relptr.inspect("/A"_jptr, JsonCppAdapter(json)),
- VariantWith<std::string>(Eq("A")));
- }
- TEST(RelatvivePointerTest, CanGoUpAndDown) {
- Json::Value json;
- json["A"] = 1;
- json["B"] = 2;
- EXPECT_THAT("1/B"_relptr.inspect("/A"_jptr, JsonCppAdapter(json)),
- VariantWith<JsonCppAdapter>(JsonCppAdapter(json["B"])));
- }
- TEST(ReferenceTest, Print) {
- EXPECT_THAT(testing::PrintToString(Reference(jvalidate::URI("file://path/to/document.json"),
- Anchor("Anchor"), "/key/1/id"_jptr)),
- "file://path/to/document.json#Anchor/key/1/id");
- }
- TEST(ReferenceTest, RelativeBasedOnURIRelative) {
- {
- jvalidate::URI uri("file://path/to/document.json");
- EXPECT_FALSE(uri.is_relative());
- EXPECT_THAT(RootReference(uri).is_relative(), uri.is_relative());
- }
- {
- jvalidate::URI uri("/path/to/document.json");
- EXPECT_FALSE(uri.is_relative());
- EXPECT_THAT(RootReference(uri).is_relative(), uri.is_relative());
- }
- {
- jvalidate::URI uri("path/to/document.json");
- EXPECT_TRUE(uri.is_relative());
- EXPECT_THAT(RootReference(uri).is_relative(), uri.is_relative());
- }
- }
- template <typename T> class NumberFromStrTest : public Test {};
- using Integers = Types<char, size_t, int>;
- TYPED_TEST_SUITE(NumberFromStrTest, Integers);
- TEST(NumberTest, ULLFitsInInteger) {
- EXPECT_TRUE(fits_in_integer(9223372036854775807ULL));
- EXPECT_FALSE(fits_in_integer(9223372036854775808ULL));
- }
- TEST(NumberTest, DoubleDoesNotFitInIntegerWhenFractional) { EXPECT_FALSE(fits_in_integer(10.5)); }
- TEST(NumberTest, DoubleFitsInIntegerWhenWhole) { EXPECT_TRUE(fits_in_integer(10.0)); }
- TEST(NumberTest, DoubleOutOfIntegerRange) {
- EXPECT_FALSE(fits_in_integer(10000000000000000000.0));
- EXPECT_FALSE(fits_in_integer(-10000000000000000000.0));
- }
- TYPED_TEST(NumberFromStrTest, NumberParsesIntegers) {
- EXPECT_THAT(parse_integer<TypeParam>("10"), Expected(10));
- }
- TYPED_TEST(NumberFromStrTest, NumberParsesNegativeIntegers) {
- if constexpr (std::is_signed_v<TypeParam>) {
- EXPECT_THAT(parse_integer<TypeParam>("-10"), Expected(-10));
- } else {
- EXPECT_THAT(parse_integer<TypeParam>("-10"), Unexpected(std::errc::invalid_argument));
- }
- }
- TYPED_TEST(NumberFromStrTest, ThrowsOnPlusSign) {
- EXPECT_THAT(parse_integer<TypeParam>("+10"), Unexpected(std::errc::invalid_argument));
- }
- TYPED_TEST(NumberFromStrTest, ThrowsOnTooManyChars) {
- EXPECT_THAT(parse_integer<TypeParam>("10 coconuts"), Unexpected(std::errc::result_out_of_range));
- }
- TYPED_TEST(NumberFromStrTest, ThrowsOnOutOfRange) {
- EXPECT_THAT(parse_integer<TypeParam>("99999999999999999999999999999"),
- Unexpected(std::errc::result_out_of_range));
- }
- TEST(StringAdapterTest, IsStringy) {
- EXPECT_THAT(StringAdapter("").type(), Type::String);
- EXPECT_THAT(StringAdapter("lorem ipsum").as_string(), "lorem ipsum");
- }
- TEST(StringAdapterTest, DiesOnAccess) {
- EXPECT_THROW(StringAdapter("").as_boolean(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").as_integer(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").as_number(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").as_array(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").array_size(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").as_object(), std::runtime_error);
- EXPECT_THROW(StringAdapter("").object_size(), std::runtime_error);
- }
- TEST(StringAdapterTest, DoesNotRunApplyArray) {
- StringAdapter("").apply_array([](auto const &) {
- ADD_FAILURE();
- return jvalidate::Status::Noop;
- });
- }
- TEST(StringAdapterTest, DoesNotRunApplyObject) {
- StringAdapter("").apply_object([](auto const &, auto const &) {
- ADD_FAILURE();
- return jvalidate::Status::Noop;
- });
- }
- TEST(UnsupportedArrayAdapterTest, Empty) {
- UnsupportedArrayAdapter<StringAdapter> array;
- EXPECT_THAT(array.size(), 0);
- EXPECT_THAT(array.begin(), array.end());
- }
- TEST(UnsupportedArrayAdapterTest, DiesWhenIndexed) {
- UnsupportedArrayAdapter<StringAdapter> array;
- EXPECT_THROW(array[0], std::runtime_error);
- }
- TEST(UnsupportedObjectAdapterTest, Empty) {
- UnsupportedObjectAdapter<StringAdapter> object;
- EXPECT_THAT(object.size(), 0);
- EXPECT_THAT(object.begin(), object.end());
- }
- TEST(UnsupportedObjectAdapterTest, DiesWhenIndexed) {
- UnsupportedObjectAdapter<StringAdapter> object;
- EXPECT_FALSE(object.contains(""));
- EXPECT_THROW(object[""], std::runtime_error);
- }
- #if JVALIDATE_HAS_ICU
- TEST(StringLengthTest, MultiCharLength) {
- // Dragon Emoji from non-bmp-regex test case
- EXPECT_THAT(length("\xF0\x9F\x90\xB2"), 1);
- }
- #endif
- #if !defined(JVALIDATE_MONOTEST)
- int main(int argc, char ** argv) {
- testing::InitGoogleMock(&argc, argv);
- return RUN_ALL_TESTS();
- }
- #endif
|