Compare commits
1 Commits
main
...
fix-cmake-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74ab21a310 |
@ -1 +0,0 @@
|
|||||||
1
|
|
||||||
4
.distro/.gitignore
vendored
4
.distro/.gitignore
vendored
@ -1,4 +0,0 @@
|
|||||||
/main.fmf
|
|
||||||
/plans/main.fmf
|
|
||||||
/tests/main.fmf
|
|
||||||
*.tar.gz
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
Name: json-schema-validator
|
|
||||||
Summary: JSON schema validator for JSON for Modern C++
|
|
||||||
Version: 0.0.0
|
|
||||||
Release: %autorelease
|
|
||||||
License: MIT
|
|
||||||
URL: https://github.com/pboettch/json-schema-validator
|
|
||||||
|
|
||||||
Source: https://github.com/pboettch/json-schema-validator/archive/refs/tags/v%{version}.tar.gz
|
|
||||||
|
|
||||||
BuildRequires: ninja-build
|
|
||||||
BuildRequires: cmake
|
|
||||||
BuildRequires: gcc-c++
|
|
||||||
BuildRequires: json-devel
|
|
||||||
|
|
||||||
%description
|
|
||||||
Json schema validator library for C++ projects using nlohmann/json
|
|
||||||
|
|
||||||
%package devel
|
|
||||||
Summary: Development files for JSON schema validator
|
|
||||||
Requires: json-schema-validator%{?_isa} = %{version}-%{release}
|
|
||||||
Requires: json-devel
|
|
||||||
|
|
||||||
%description devel
|
|
||||||
Json schema validator development files for C++ projects using nlohmann/json
|
|
||||||
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%autosetup -n json-schema-validator-%{version}
|
|
||||||
|
|
||||||
|
|
||||||
%build
|
|
||||||
%cmake \
|
|
||||||
-DJSON_VALIDATOR_SHARED_LIBS=ON \
|
|
||||||
-DJSON_VALIDATOR_INSTALL=ON \
|
|
||||||
-DJSON_VALIDATOR_BUILD_EXAMPLES=OFF \
|
|
||||||
-DJSON_VALIDATOR_BUILD_TESTS=ON
|
|
||||||
|
|
||||||
%cmake_build
|
|
||||||
|
|
||||||
|
|
||||||
%install
|
|
||||||
%cmake_install
|
|
||||||
|
|
||||||
|
|
||||||
%check
|
|
||||||
%ctest
|
|
||||||
|
|
||||||
|
|
||||||
%files
|
|
||||||
%doc README.md
|
|
||||||
%license LICENSE
|
|
||||||
%{_libdir}/libnlohmann_json_validator.so.*
|
|
||||||
|
|
||||||
%files devel
|
|
||||||
%{_libdir}/libnlohmann_json_validator.so
|
|
||||||
%{_includedir}/nlohmann/json-schema.hpp
|
|
||||||
%{_libdir}/cmake/nlohmann_json_schema_validator
|
|
||||||
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
%autochangelog
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
Filters = [
|
|
||||||
"unknown-key",
|
|
||||||
]
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
summary:
|
|
||||||
Basic importing tests
|
|
||||||
prepare+:
|
|
||||||
- name: Include minimum fetching packages
|
|
||||||
how: install
|
|
||||||
package:
|
|
||||||
- git
|
|
||||||
discover+:
|
|
||||||
how: fmf
|
|
||||||
filter: "tag: import"
|
|
||||||
execute:
|
|
||||||
how: tmt
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
discover:
|
|
||||||
how: fmf
|
|
||||||
dist-git-source: true
|
|
||||||
path: .distro
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
summary:
|
|
||||||
Perform rpmlint and rpminspect tests
|
|
||||||
prepare:
|
|
||||||
- name: Download the source rpm
|
|
||||||
how: shell
|
|
||||||
script: cd /tmp && curl -O ${PACKIT_SRPM_URL}
|
|
||||||
- name: Download rpm packages
|
|
||||||
how: shell
|
|
||||||
script: cd /tmp && dnf download ${PACKIT_COPR_RPMS}
|
|
||||||
discover+:
|
|
||||||
how: fmf
|
|
||||||
filter: "tag: rpmlint"
|
|
||||||
execute:
|
|
||||||
how: tmt
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
summary:
|
|
||||||
Basic smoke tests
|
|
||||||
discover+:
|
|
||||||
how: fmf
|
|
||||||
filter: "tag: smoke"
|
|
||||||
execute:
|
|
||||||
how: tmt
|
|
||||||
@ -1,15 +0,0 @@
|
|||||||
# This is a simple project that tests using cmake to load the installed libraries
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
|
|
||||||
project(test_fetch_content LANGUAGES CXX)
|
|
||||||
|
|
||||||
|
|
||||||
FetchContent_Declare(nlohmann_json_schema_validator
|
|
||||||
GIT_REPOSITORY https://github.com/pboettch/json-schema-validator
|
|
||||||
GIT_TAG main
|
|
||||||
)
|
|
||||||
FetchContent_MakeAvailable(nlohmann_json_schema_validator)
|
|
||||||
|
|
||||||
if (NOT TARGET nlohmann_json_schema_validator::validator)
|
|
||||||
message(FATAL_ERROR "Missing target nlohmann_json_schema_validator::validator")
|
|
||||||
endif ()
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
# This is a simple project that tests using cmake to load the installed libraries
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
|
|
||||||
project(test_find_package LANGUAGES CXX)
|
|
||||||
|
|
||||||
set(CMAKE_FIND_DEBUG_MODE ON)
|
|
||||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
|
||||||
|
|
||||||
if (NOT TARGET nlohmann_json_schema_validator::validator)
|
|
||||||
message(FATAL_ERROR "Missing target nlohmann_json_schema_validator::validator")
|
|
||||||
endif ()
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
# Common test variables
|
|
||||||
tag:
|
|
||||||
- import
|
|
||||||
tier: 0
|
|
||||||
path: /tests/import
|
|
||||||
|
|
||||||
# Define tests
|
|
||||||
/find_package:
|
|
||||||
test: ./test_find_package.sh
|
|
||||||
/FetchContent:
|
|
||||||
test: ./test_FetchContent.sh
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#!/bin/bash -eux
|
|
||||||
|
|
||||||
tmp_dir=$(mktemp -d)
|
|
||||||
cmake -S ./FetchContent -B ${tmp_dir}
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
#!/bin/bash -eux
|
|
||||||
|
|
||||||
tmp_dir=$(mktemp -d)
|
|
||||||
cmake -S ./find_package -B ${tmp_dir}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
# Common test variables
|
|
||||||
tag:
|
|
||||||
- rpmlint
|
|
||||||
tier: 0
|
|
||||||
path: /
|
|
||||||
|
|
||||||
# Define tests
|
|
||||||
/rpmlint:
|
|
||||||
summary: Rpmlint spec and rpmfiles
|
|
||||||
test: rpmlint -c packit.toml -r json-schema-validator.rpmlintrc ./*.spec /tmp/*.rpm
|
|
||||||
/rpminspect-rpms:
|
|
||||||
summary: Rpminspect the rpms
|
|
||||||
test: ls /tmp/*.rpm | xargs -L1 rpminspect-fedora -E metadata,disttag
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
# Common test variables
|
|
||||||
tag:
|
|
||||||
- smoke
|
|
||||||
tier: 0
|
|
||||||
path: /
|
|
||||||
|
|
||||||
# Define tests
|
|
||||||
/version:
|
|
||||||
test: echo "TODO: Write a minimum working example"
|
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,4 +4,3 @@ cmake-build-*
|
|||||||
venv
|
venv
|
||||||
env
|
env
|
||||||
compile_commands.json
|
compile_commands.json
|
||||||
.vs/*
|
|
||||||
|
|||||||
79
.packit.yaml
79
.packit.yaml
@ -1,79 +0,0 @@
|
|||||||
specfile_path: .distro/json-schema-validator.spec
|
|
||||||
files_to_sync:
|
|
||||||
- src: .distro/json-schema-validator.spec
|
|
||||||
dest: json-schema-validator.spec
|
|
||||||
- .packit.yaml
|
|
||||||
- src: .distro/json-schema-validator.rpmlintrc
|
|
||||||
dest: json-schema-validator.rpmlintrc
|
|
||||||
# tmt setup
|
|
||||||
- src: .distro/.fmf/
|
|
||||||
dest: .fmf/
|
|
||||||
- src: .distro/plans/
|
|
||||||
dest: plans/
|
|
||||||
filters:
|
|
||||||
- "- .distro/plans/main.fmf.dist-git"
|
|
||||||
- "- .distro/plans/rpmlint.fmf"
|
|
||||||
- src: .distro/plans/main.fmf.dist-git
|
|
||||||
dest: plans/main.fmf
|
|
||||||
upstream_package_name: json-schema-validator
|
|
||||||
downstream_package_name: json-schema-validator
|
|
||||||
update_release: false
|
|
||||||
upstream_tag_template: v{version}
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
- job: copr_build
|
|
||||||
trigger: pull_request
|
|
||||||
owner: lecris
|
|
||||||
project: json-schema-validator
|
|
||||||
update_release: true
|
|
||||||
release_suffix: "{PACKIT_RPMSPEC_RELEASE}"
|
|
||||||
targets:
|
|
||||||
- fedora-development
|
|
||||||
- job: tests
|
|
||||||
trigger: pull_request
|
|
||||||
targets:
|
|
||||||
- fedora-development
|
|
||||||
fmf_path: .distro
|
|
||||||
- job: copr_build
|
|
||||||
trigger: commit
|
|
||||||
branch: main
|
|
||||||
owner: lecris
|
|
||||||
project: nightly
|
|
||||||
# TODO: Remove when upstream issue is resolved
|
|
||||||
# https://github.com/packit/packit/issues/1924
|
|
||||||
additional_repos:
|
|
||||||
- copr://@scikit-build/release
|
|
||||||
targets:
|
|
||||||
- fedora-development-x86_64
|
|
||||||
- fedora-latest-x86_64
|
|
||||||
- fedora-development-aarch64
|
|
||||||
- fedora-latest-aarch64
|
|
||||||
- job: copr_build
|
|
||||||
trigger: release
|
|
||||||
owner: lecris
|
|
||||||
project: release
|
|
||||||
targets:
|
|
||||||
- fedora-development-x86_64
|
|
||||||
- fedora-latest-x86_64
|
|
||||||
- fedora-development-aarch64
|
|
||||||
- fedora-latest-aarch64
|
|
||||||
- job: tests
|
|
||||||
trigger: commit
|
|
||||||
branch: main
|
|
||||||
targets:
|
|
||||||
- fedora-development
|
|
||||||
- fedora-latest
|
|
||||||
fmf_path: .distro
|
|
||||||
- job: propose_downstream
|
|
||||||
trigger: release
|
|
||||||
dist_git_branches:
|
|
||||||
- fedora-development
|
|
||||||
- fedora-latest
|
|
||||||
- job: koji_build
|
|
||||||
trigger: commit
|
|
||||||
dist_git_branches:
|
|
||||||
- fedora-all
|
|
||||||
- job: bodhi_update
|
|
||||||
trigger: commit
|
|
||||||
dist_git_branches:
|
|
||||||
- fedora-branched
|
|
||||||
@ -13,7 +13,6 @@ repos:
|
|||||||
- '-Bcmake-build-pre-commit'
|
- '-Bcmake-build-pre-commit'
|
||||||
- '--preset'
|
- '--preset'
|
||||||
- 'pre-commit'
|
- 'pre-commit'
|
||||||
stages: [ manual ]
|
|
||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
rev: v4.4.0
|
rev: v4.4.0
|
||||||
hooks:
|
hooks:
|
||||||
|
|||||||
@ -10,12 +10,9 @@ endif ()
|
|||||||
# Basic project definition #
|
# Basic project definition #
|
||||||
]==============================================================================================]
|
]==============================================================================================]
|
||||||
|
|
||||||
# TODO: CMake >= 3.19 can use string(JSON VERSION GET "${METADATA}" "version") to load from JSON
|
|
||||||
set(PROJECT_VERSION 2.4.0)
|
|
||||||
|
|
||||||
# TODO: Version 3, rename the project and namespace to something more compact
|
# TODO: Version 3, rename the project and namespace to something more compact
|
||||||
project(nlohmann_json_schema_validator
|
project(nlohmann_json_schema_validator
|
||||||
VERSION ${PROJECT_VERSION}
|
VERSION 2.2.0
|
||||||
DESCRIPTION "Json validator for nlohmann::json library"
|
DESCRIPTION "Json validator for nlohmann::json library"
|
||||||
HOMEPAGE_URL "https://github.com/pboettch/json-schema-validator"
|
HOMEPAGE_URL "https://github.com/pboettch/json-schema-validator"
|
||||||
LANGUAGES CXX)
|
LANGUAGES CXX)
|
||||||
@ -83,17 +80,16 @@ endif ()
|
|||||||
]==============================================================================================]
|
]==============================================================================================]
|
||||||
|
|
||||||
set(fetch_packages "")
|
set(fetch_packages "")
|
||||||
if (NOT TARGET nlohmann_json)
|
# Fetch/Find nlohmann_json
|
||||||
# Fetch/Find nlohmann_json
|
# TODO: Remove when bumping cmake >= 3.24
|
||||||
# TODO: Remove when bumping cmake >= 3.24
|
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
||||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.24)
|
|
||||||
FetchContent_Declare(nlohmann_json
|
FetchContent_Declare(nlohmann_json
|
||||||
GIT_REPOSITORY https://github.com/nlohmann/json
|
GIT_REPOSITORY https://github.com/nlohmann/json
|
||||||
GIT_TAG ${JSON_FETCH_VERSION}
|
GIT_TAG ${JSON_FETCH_VERSION}
|
||||||
FIND_PACKAGE_ARGS
|
FIND_PACKAGE_ARGS
|
||||||
)
|
)
|
||||||
list(APPEND fetch_packages nlohmann_json)
|
list(APPEND fetch_packages nlohmann_json)
|
||||||
else ()
|
else ()
|
||||||
# Try to get system installed version
|
# Try to get system installed version
|
||||||
find_package(nlohmann_json QUIET)
|
find_package(nlohmann_json QUIET)
|
||||||
if (NOT nlohmann_json_FOUND)
|
if (NOT nlohmann_json_FOUND)
|
||||||
@ -104,7 +100,6 @@ if (NOT TARGET nlohmann_json)
|
|||||||
)
|
)
|
||||||
list(APPEND fetch_packages nlohmann_json)
|
list(APPEND fetch_packages nlohmann_json)
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
# Handle configure flags
|
# Handle configure flags
|
||||||
|
|||||||
@ -74,7 +74,7 @@ types, depending on if the schema type is "integer" or "number". Bignum
|
|||||||
This library is based on Niels Lohmann's JSON-library and thus has
|
This library is based on Niels Lohmann's JSON-library and thus has
|
||||||
a build-dependency to it.
|
a build-dependency to it.
|
||||||
|
|
||||||
Currently at least version **3.8.0** of NLohmann's JSON library
|
Currently at least version **3.6.0** of NLohmann's JSON library
|
||||||
is required.
|
is required.
|
||||||
|
|
||||||
Various methods using CMake can be used to build this project.
|
Various methods using CMake can be used to build this project.
|
||||||
|
|||||||
54
conanfile.py
54
conanfile.py
@ -1,10 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
from conans import load, tools, ConanFile, CMake
|
||||||
|
|
||||||
from conan import ConanFile
|
|
||||||
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
|
|
||||||
from conans.tools import load
|
|
||||||
from conans import tools as ctools
|
|
||||||
|
|
||||||
def get_version():
|
def get_version():
|
||||||
try:
|
try:
|
||||||
@ -23,59 +20,52 @@ class JsonSchemaValidatorConan(ConanFile):
|
|||||||
version = get_version()
|
version = get_version()
|
||||||
url = 'https://github.com/pboettch/json-schema-validator'
|
url = 'https://github.com/pboettch/json-schema-validator'
|
||||||
license = 'MIT'
|
license = 'MIT'
|
||||||
|
|
||||||
settings = 'os', 'compiler', 'build_type', 'arch'
|
settings = 'os', 'compiler', 'build_type', 'arch'
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
'shared': [True, False],
|
'shared': [True, False],
|
||||||
'fPIC': [True, False],
|
'fPIC': [True, False],
|
||||||
'build_examples': [True, False],
|
'build_examples': [True, False],
|
||||||
'build_tests': [True, False],
|
'build_tests': [True, False]
|
||||||
'test_coverage': [True, False],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default_options = {
|
default_options = {
|
||||||
'shared': False,
|
'shared': False,
|
||||||
'fPIC': True,
|
'fPIC': True,
|
||||||
'build_examples': True,
|
'build_examples': True,
|
||||||
'build_tests': False,
|
'build_tests': False
|
||||||
'test_coverage': False,
|
|
||||||
}
|
}
|
||||||
|
generators = "CMakeDeps"
|
||||||
generators = 'CMakeDeps', 'CMakeToolchain', 'VirtualBuildEnv', 'VirtualRunEnv'
|
|
||||||
|
|
||||||
exports_sources = [
|
exports_sources = [
|
||||||
'CMakeLists.txt',
|
'CMakeLists.txt',
|
||||||
'conanfile.py',
|
'nlohmann_json_schema_validatorConfig.cmake.in',
|
||||||
'cmake/*',
|
|
||||||
'src/*',
|
'src/*',
|
||||||
'example/*',
|
'app/*',
|
||||||
'test/*',
|
'test/*',
|
||||||
]
|
]
|
||||||
|
requires = (
|
||||||
requires = [
|
|
||||||
'nlohmann_json/3.11.2'
|
'nlohmann_json/3.11.2'
|
||||||
]
|
)
|
||||||
|
_cmake = None
|
||||||
|
|
||||||
def generate(self):
|
def _configure_cmake(self):
|
||||||
tc = CMakeToolchain(self)
|
if self._cmake:
|
||||||
tc.variables['JSON_VALIDATOR_BUILD_EXAMPLES'] = self.options.build_examples
|
return self._cmake
|
||||||
tc.variables['JSON_VALIDATOR_BUILD_TESTS'] = self.options.build_tests
|
self._cmake = CMake(self)
|
||||||
tc.variables['JSON_VALIDATOR_SHARED_LIBS '] = self.options.shared
|
self._cmake.definitions['JSON_VALIDATOR_BUILD_EXAMPLES'] = self.options.build_examples
|
||||||
tc.variables['JSON_VALIDATOR_TEST_COVERAGE '] = self.options.test_coverage
|
self._cmake.definitions['JSON_VALIDATOR_BUILD_TESTS'] = self.options.build_tests
|
||||||
tc.generate()
|
self._cmake.configure()
|
||||||
|
return self._cmake
|
||||||
|
|
||||||
def layout(self):
|
def layout(self):
|
||||||
cmake_layout(self)
|
build_type = str(self.settings.build_type).lower()
|
||||||
|
self.folders.build = "build-{}".format(build_type)
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
cmake = CMake(self)
|
cmake = self._configure_cmake()
|
||||||
cmake.configure()
|
cmake.configure()
|
||||||
cmake.verbose = True
|
|
||||||
cmake.build()
|
cmake.build()
|
||||||
|
|
||||||
def package(self):
|
def package(self):
|
||||||
cmake = CMake(self)
|
cmake = self._configure_cmake()
|
||||||
cmake.install()
|
cmake.install()
|
||||||
|
|
||||||
def package_info(self):
|
def package_info(self):
|
||||||
@ -84,7 +74,7 @@ class JsonSchemaValidatorConan(ConanFile):
|
|||||||
|
|
||||||
libdir = os.path.join(self.package_folder, "lib")
|
libdir = os.path.join(self.package_folder, "lib")
|
||||||
self.cpp_info.libdirs = [libdir]
|
self.cpp_info.libdirs = [libdir]
|
||||||
self.cpp_info.libs += ctools.collect_libs(self, libdir)
|
self.cpp_info.libs += tools.collect_libs(self, libdir)
|
||||||
|
|
||||||
bindir = os.path.join(self.package_folder, "bin")
|
bindir = os.path.join(self.package_folder, "bin")
|
||||||
self.output.info("Appending PATH environment variable: {}".format(bindir))
|
self.output.info("Appending PATH environment variable: {}".format(bindir))
|
||||||
|
|||||||
@ -54,11 +54,21 @@ target_link_libraries(nlohmann_json_schema_validator PUBLIC
|
|||||||
|
|
||||||
if (JSON_VALIDATOR_INSTALL)
|
if (JSON_VALIDATOR_INSTALL)
|
||||||
# Normal installation target to system. When using scikit-build check python subdirectory
|
# Normal installation target to system. When using scikit-build check python subdirectory
|
||||||
|
if (WIN32)
|
||||||
|
# TODO: Probably wrong, please fix
|
||||||
install(TARGETS nlohmann_json_schema_validator
|
install(TARGETS nlohmann_json_schema_validator
|
||||||
EXPORT nlohmann_json_schema_validatorTargets
|
EXPORT nlohmann_json_schema_validatorTargets
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime
|
||||||
NAMELINK_COMPONENT nlohmann_json_schema_validator_Development
|
NAMELINK_COMPONENT nlohmann_json_schema_validator_Development
|
||||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT nlohmann_json_schema_validator_Runtime)
|
RUNTIME DESTINATION ${CMAKE_INSTALL_RUNTIMEDIR} COMPONENT nlohmann_json_schema_validator_Runtime)
|
||||||
|
else ()
|
||||||
|
install(TARGETS nlohmann_json_schema_validator
|
||||||
|
EXPORT nlohmann_json_schema_validatorTargets
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Runtime
|
||||||
|
NAMELINK_COMPONENT nlohmann_json_schema_validator_Development
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT nlohmann_json_schema_validator_Development
|
||||||
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/nlohmann COMPONENT nlohmann_json_schema_validator_Development)
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|||||||
@ -28,13 +28,10 @@ public:
|
|||||||
json_patch &replace(const json::json_pointer &, json value);
|
json_patch &replace(const json::json_pointer &, json value);
|
||||||
json_patch &remove(const json::json_pointer &);
|
json_patch &remove(const json::json_pointer &);
|
||||||
|
|
||||||
json &get_json() { return j_; }
|
|
||||||
const json &get_json() const { return j_; }
|
|
||||||
|
|
||||||
operator json() const { return j_; }
|
operator json() const { return j_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
json j_ = nlohmann::json::array();
|
json j_;
|
||||||
|
|
||||||
static void validateJsonPatch(json const &patch);
|
static void validateJsonPatch(json const &patch);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -226,11 +226,10 @@ public:
|
|||||||
// for each token create an object, if not already existing
|
// for each token create an object, if not already existing
|
||||||
auto unk_kw = &file.unknown_keywords;
|
auto unk_kw = &file.unknown_keywords;
|
||||||
for (auto &rt : ref_tokens) {
|
for (auto &rt : ref_tokens) {
|
||||||
// create a json_pointer from rt as rt can be an stringified integer doing find on an array won't work
|
auto existing_object = unk_kw->find(rt);
|
||||||
json::json_pointer rt_ptr{"/" + rt};
|
if (existing_object == unk_kw->end())
|
||||||
if (unk_kw->contains(rt_ptr) == false)
|
|
||||||
(*unk_kw)[rt] = json::object();
|
(*unk_kw)[rt] = json::object();
|
||||||
unk_kw = &(*unk_kw)[rt_ptr];
|
unk_kw = &(*unk_kw)[rt];
|
||||||
}
|
}
|
||||||
(*unk_kw)[key] = value;
|
(*unk_kw)[key] = value;
|
||||||
}
|
}
|
||||||
@ -254,15 +253,15 @@ public:
|
|||||||
//
|
//
|
||||||
// an unknown keyword can only be referenced by a json-pointer,
|
// an unknown keyword can only be referenced by a json-pointer,
|
||||||
// not by a plain name fragment
|
// not by a plain name fragment
|
||||||
if (!uri.pointer().to_string().empty()) {
|
if (uri.pointer().to_string() != "") {
|
||||||
bool contains_pointer = file.unknown_keywords.contains(uri.pointer());
|
try {
|
||||||
if (contains_pointer) {
|
auto &subschema = file.unknown_keywords.at(uri.pointer()); // null is returned if not existing
|
||||||
auto &subschema = file.unknown_keywords.at(uri.pointer());
|
auto s = schema::make(subschema, this, {}, {{uri}}); // A JSON Schema MUST be an object or a boolean.
|
||||||
auto s = schema::make(subschema, this, {}, {{uri}});
|
if (s) { // nullptr if invalid schema, e.g. null
|
||||||
if (s) { // if schema is valid (non-null)
|
|
||||||
file.unknown_keywords.erase(uri.fragment());
|
file.unknown_keywords.erase(uri.fragment());
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
} catch (nlohmann::detail::out_of_range &) { // at() did not find it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -426,31 +425,6 @@ enum logical_combination_types {
|
|||||||
oneOf
|
oneOf
|
||||||
};
|
};
|
||||||
|
|
||||||
class logical_combination_error_handler : public error_handler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct error_entry {
|
|
||||||
json::json_pointer ptr_;
|
|
||||||
json instance_;
|
|
||||||
std::string message_;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<error_entry> error_entry_list_;
|
|
||||||
|
|
||||||
void error(const json::json_pointer &ptr, const json &instance, const std::string &message) override
|
|
||||||
{
|
|
||||||
error_entry_list_.push_back(error_entry{ptr, instance, message});
|
|
||||||
}
|
|
||||||
|
|
||||||
void propagate(error_handler &e, const std::string &prefix) const
|
|
||||||
{
|
|
||||||
for (const error_entry &entry : error_entry_list_)
|
|
||||||
e.error(entry.ptr_, entry.instance_, prefix + entry.message_);
|
|
||||||
}
|
|
||||||
|
|
||||||
operator bool() const { return !error_entry_list_.empty(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
template <enum logical_combination_types combine_logic>
|
template <enum logical_combination_types combine_logic>
|
||||||
class logical_combination : public schema
|
class logical_combination : public schema
|
||||||
{
|
{
|
||||||
@ -459,33 +433,29 @@ class logical_combination : public schema
|
|||||||
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
|
void validate(const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e) const final
|
||||||
{
|
{
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
logical_combination_error_handler error_summary;
|
|
||||||
|
|
||||||
for (std::size_t index = 0; index < subschemata_.size(); ++index) {
|
for (auto &s : subschemata_) {
|
||||||
const std::shared_ptr<schema> &s = subschemata_[index];
|
first_error_handler esub;
|
||||||
logical_combination_error_handler esub;
|
json_patch old_patch(patch);
|
||||||
auto oldPatchSize = patch.get_json().size();
|
|
||||||
s->validate(ptr, instance, patch, esub);
|
s->validate(ptr, instance, patch, esub);
|
||||||
if (!esub)
|
if (!esub)
|
||||||
count++;
|
count++;
|
||||||
else {
|
else
|
||||||
patch.get_json().get_ref<nlohmann::json::array_t &>().resize(oldPatchSize);
|
patch = old_patch;
|
||||||
esub.propagate(error_summary, "case#" + std::to_string(index) + "] ");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_validate_complete(instance, ptr, e, esub, count, index))
|
if (is_validate_complete(instance, ptr, e, esub, count))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (count == 0) {
|
// could accumulate esub details for anyOf and oneOf, but not clear how to select which subschema failure to report
|
||||||
e.error(ptr, instance, "no subschema has succeeded, but one of them is required to validate. Type: " + key + ", number of failed subschemas: " + std::to_string(subschemata_.size()));
|
// or how to report multiple such failures
|
||||||
error_summary.propagate(e, "[combination: " + key + " / ");
|
if (count == 0)
|
||||||
}
|
e.error(ptr, instance, "no subschema has succeeded, but one of them is required to validate");
|
||||||
}
|
}
|
||||||
|
|
||||||
// specialized for each of the logical_combination_types
|
// specialized for each of the logical_combination_types
|
||||||
static const std::string key;
|
static const std::string key;
|
||||||
static bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t, size_t);
|
static bool is_validate_complete(const json &, const json::json_pointer &, error_handler &, const first_error_handler &, size_t);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
logical_combination(json &sch,
|
logical_combination(json &sch,
|
||||||
@ -510,23 +480,21 @@ template <>
|
|||||||
const std::string logical_combination<oneOf>::key = "oneOf";
|
const std::string logical_combination<oneOf>::key = "oneOf";
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool logical_combination<allOf>::is_validate_complete(const json &, const json::json_pointer &, error_handler &e, const logical_combination_error_handler &esub, size_t, size_t current_schema_index)
|
bool logical_combination<allOf>::is_validate_complete(const json &, const json::json_pointer &, error_handler &e, const first_error_handler &esub, size_t)
|
||||||
{
|
{
|
||||||
if (esub) {
|
if (esub)
|
||||||
e.error(esub.error_entry_list_.front().ptr_, esub.error_entry_list_.front().instance_, "at least one subschema has failed, but all of them are required to validate - " + esub.error_entry_list_.front().message_);
|
e.error(esub.ptr_, esub.instance_, "at least one subschema has failed, but all of them are required to validate - " + esub.message_);
|
||||||
esub.propagate(e, "[combination: allOf / case#" + std::to_string(current_schema_index) + "] ");
|
|
||||||
}
|
|
||||||
return esub;
|
return esub;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool logical_combination<anyOf>::is_validate_complete(const json &, const json::json_pointer &, error_handler &, const logical_combination_error_handler &, size_t count, size_t)
|
bool logical_combination<anyOf>::is_validate_complete(const json &, const json::json_pointer &, error_handler &, const first_error_handler &, size_t count)
|
||||||
{
|
{
|
||||||
return count == 1;
|
return count == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
bool logical_combination<oneOf>::is_validate_complete(const json &instance, const json::json_pointer &ptr, error_handler &e, const logical_combination_error_handler &, size_t count, size_t)
|
bool logical_combination<oneOf>::is_validate_complete(const json &instance, const json::json_pointer &ptr, error_handler &e, const first_error_handler &, size_t count)
|
||||||
{
|
{
|
||||||
if (count > 1)
|
if (count > 1)
|
||||||
e.error(ptr, instance, "more than one subschema has succeeded, but exactly one of them is required to validate");
|
e.error(ptr, instance, "more than one subschema has succeeded, but exactly one of them is required to validate");
|
||||||
@ -896,12 +864,7 @@ class numeric : public schema
|
|||||||
bool violates_multiple_of(T x) const
|
bool violates_multiple_of(T x) const
|
||||||
{
|
{
|
||||||
double res = std::remainder(x, multipleOf_.second);
|
double res = std::remainder(x, multipleOf_.second);
|
||||||
double multiple = std::fabs(x / multipleOf_.second);
|
|
||||||
if (multiple > 1) {
|
|
||||||
res = res / multiple;
|
|
||||||
}
|
|
||||||
double eps = std::nextafter(x, 0) - static_cast<double>(x);
|
double eps = std::nextafter(x, 0) - static_cast<double>(x);
|
||||||
|
|
||||||
return std::fabs(res) > std::fabs(eps);
|
return std::fabs(res) > std::fabs(eps);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -909,31 +872,22 @@ class numeric : public schema
|
|||||||
{
|
{
|
||||||
T value = instance; // conversion of json to value_type
|
T value = instance; // conversion of json to value_type
|
||||||
|
|
||||||
std::ostringstream oss;
|
|
||||||
|
|
||||||
if (multipleOf_.first && value != 0) // zero is multiple of everything
|
if (multipleOf_.first && value != 0) // zero is multiple of everything
|
||||||
if (violates_multiple_of(value))
|
if (violates_multiple_of(value))
|
||||||
oss << "instance is not a multiple of " << json(multipleOf_.second);
|
e.error(ptr, instance, "instance is not a multiple of " + std::to_string(multipleOf_.second));
|
||||||
|
|
||||||
if (maximum_.first) {
|
if (maximum_.first) {
|
||||||
if (exclusiveMaximum_ && value >= maximum_.second)
|
if (exclusiveMaximum_ && value >= maximum_.second)
|
||||||
oss << "instance exceeds or equals maximum of " << json(maximum_.second);
|
e.error(ptr, instance, "instance exceeds or equals maximum of " + std::to_string(maximum_.second));
|
||||||
else if (value > maximum_.second)
|
else if (value > maximum_.second)
|
||||||
oss << "instance exceeds maximum of " << json(maximum_.second);
|
e.error(ptr, instance, "instance exceeds maximum of " + std::to_string(maximum_.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (minimum_.first) {
|
if (minimum_.first) {
|
||||||
if (exclusiveMinimum_ && value <= minimum_.second)
|
if (exclusiveMinimum_ && value <= minimum_.second)
|
||||||
oss << "instance is below or equals minimum of " << json(minimum_.second);
|
e.error(ptr, instance, "instance is below or equals minimum of " + std::to_string(minimum_.second));
|
||||||
else if (value < minimum_.second)
|
else if (value < minimum_.second)
|
||||||
oss << "instance is below minimum of " << json(minimum_.second);
|
e.error(ptr, instance, "instance is below minimum of " + std::to_string(minimum_.second));
|
||||||
}
|
|
||||||
|
|
||||||
oss.seekp(0, std::ios::end);
|
|
||||||
auto size = oss.tellp();
|
|
||||||
if (size != 0) {
|
|
||||||
oss.seekp(0, std::ios::beg);
|
|
||||||
e.error(ptr, instance, oss.str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1386,18 +1340,11 @@ std::shared_ptr<schema> schema::make(json &schema,
|
|||||||
schema.erase(attr);
|
schema.erase(attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto findDefinitions = [&](const std::string &defs) -> bool {
|
attr = schema.find("definitions");
|
||||||
attr = schema.find(defs);
|
|
||||||
if (attr != schema.end()) {
|
if (attr != schema.end()) {
|
||||||
for (auto &def : attr.value().items())
|
for (auto &def : attr.value().items())
|
||||||
schema::make(def.value(), root, {defs, def.key()}, uris);
|
schema::make(def.value(), root, {"definitions", def.key()}, uris);
|
||||||
schema.erase(attr);
|
schema.erase(attr);
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
if (!findDefinitions("$defs")) {
|
|
||||||
findDefinitions("definitions");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attr = schema.find("$ref");
|
attr = schema.find("$ref");
|
||||||
|
|||||||
@ -669,6 +669,10 @@ static const short _address_eof_trans[] = {
|
|||||||
1278, 1279, 1280, 1281, 1282, 1283, 0};
|
1278, 1279, 1280, 1281, 1282, 1283, 0};
|
||||||
|
|
||||||
static const int address_start = 1;
|
static const int address_start = 1;
|
||||||
|
static const int address_first_final = 196;
|
||||||
|
static const int address_error = 0;
|
||||||
|
|
||||||
|
static const int address_en_main = 1;
|
||||||
|
|
||||||
bool is_address(const char *p, const char *pe)
|
bool is_address(const char *p, const char *pe)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -43,10 +43,6 @@ add_executable(issue-98 issue-98.cpp)
|
|||||||
target_link_libraries(issue-98 nlohmann_json_schema_validator)
|
target_link_libraries(issue-98 nlohmann_json_schema_validator)
|
||||||
add_test(NAME issue-98-erase-exception-unknown-keywords COMMAND issue-98)
|
add_test(NAME issue-98-erase-exception-unknown-keywords COMMAND issue-98)
|
||||||
|
|
||||||
add_executable(issue-293 issue-293.cpp)
|
|
||||||
target_link_libraries(issue-293 nlohmann_json_schema_validator)
|
|
||||||
add_test(NAME issue-293-float-point-error COMMAND issue-293)
|
|
||||||
|
|
||||||
# Unit test for string format checks
|
# Unit test for string format checks
|
||||||
add_executable(string-format-check-test string-format-check-test.cpp)
|
add_executable(string-format-check-test string-format-check-test.cpp)
|
||||||
target_include_directories(string-format-check-test PRIVATE ${PROJECT_SOURCE_DIR}/src/)
|
target_include_directories(string-format-check-test PRIVATE ${PROJECT_SOURCE_DIR}/src/)
|
||||||
@ -85,11 +81,3 @@ add_test(NAME issue-229-oneof-default-values COMMAND issue-229-oneof-default-val
|
|||||||
add_executable(issue-243-root-default-values issue-243-root-default-values.cpp)
|
add_executable(issue-243-root-default-values issue-243-root-default-values.cpp)
|
||||||
target_link_libraries(issue-243-root-default-values nlohmann_json_schema_validator)
|
target_link_libraries(issue-243-root-default-values nlohmann_json_schema_validator)
|
||||||
add_test(NAME issue-243-root-default-values COMMAND issue-243-root-default-values)
|
add_test(NAME issue-243-root-default-values COMMAND issue-243-root-default-values)
|
||||||
|
|
||||||
add_executable(issue-255-error-message-limit-precision issue-255-error-message-limit-precision.cpp)
|
|
||||||
target_link_libraries(issue-255-error-message-limit-precision nlohmann_json_schema_validator)
|
|
||||||
add_test(NAME issue-255-error-message-limit-precision COMMAND issue-255-error-message-limit-precision)
|
|
||||||
|
|
||||||
add_executable(issue-105-verbose-combination-errors issue-105-verbose-combination-errors.cpp)
|
|
||||||
target_link_libraries(issue-105-verbose-combination-errors nlohmann_json_schema_validator)
|
|
||||||
add_test(NAME issue-105-verbose-combination-errors COMMAND issue-105-verbose-combination-errors)
|
|
||||||
|
|||||||
@ -1,321 +0,0 @@
|
|||||||
#include "nlohmann/json-schema.hpp"
|
|
||||||
#include "nlohmann/json.hpp"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <regex>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// Test macros
|
|
||||||
//==============================================================================
|
|
||||||
#define LOG_ERROR(LOG_ERROR__ARGS) \
|
|
||||||
std::cerr << __FILE__ << ":" << __LINE__ << ": " << LOG_ERROR__ARGS << std::endl
|
|
||||||
|
|
||||||
#define EXPECT_THROW_WITH_MESSAGE(EXPRESSION, MESSAGE) \
|
|
||||||
do { \
|
|
||||||
try { \
|
|
||||||
EXPRESSION; \
|
|
||||||
LOG_ERROR("Expected exception not thrown with matching regex: \"" << MESSAGE << "\""); \
|
|
||||||
++g_error_count; \
|
|
||||||
} catch (const std::exception &error) { \
|
|
||||||
const std::regex error_re{MESSAGE}; \
|
|
||||||
if (!std::regex_search(error.what(), error_re)) { \
|
|
||||||
LOG_ERROR("Expected exception with matching regex: \"" << MESSAGE << "\", but got this instead: " << error.what()); \
|
|
||||||
++g_error_count; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
#define ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, RETURN_IN_CASE_OF_ERROR) \
|
|
||||||
do { \
|
|
||||||
if ((FIRST_THING) != (SECOND_THING)) { \
|
|
||||||
LOG_ERROR("The two values of " << (FIRST_THING) << " (" #FIRST_THING << ") and " << (SECOND_THING) << " (" #SECOND_THING << ") should be equal"); \
|
|
||||||
if (RETURN_IN_CASE_OF_ERROR) { \
|
|
||||||
return; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
#define ASSERT_EQ(FIRST_THING, SECOND_THING) ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, true)
|
|
||||||
#define EXPECT_EQ(FIRST_THING, SECOND_THING) ASSERT_OR_EXPECT_EQ(FIRST_THING, SECOND_THING, true)
|
|
||||||
|
|
||||||
#define EXPECT_MATCH(STRING, REGEX) \
|
|
||||||
do { \
|
|
||||||
if (!std::regex_search((STRING), std::regex{(REGEX)})) { \
|
|
||||||
LOG_ERROR("String \"" << (STRING) << "\" doesn't match with regex: \"" << (REGEX) << "\""); \
|
|
||||||
++g_error_count; \
|
|
||||||
} \
|
|
||||||
} while (false)
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// Test environment
|
|
||||||
//==============================================================================
|
|
||||||
int g_error_count = 0;
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// The schema used for testing
|
|
||||||
//==============================================================================
|
|
||||||
const std::string g_schema_template = R"(
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"first": {
|
|
||||||
"%COMBINATION_FIRST_LEVEL%": [
|
|
||||||
{
|
|
||||||
"properties": {
|
|
||||||
"second": {
|
|
||||||
"%COMBINATION_SECOND_LEVEL%": [
|
|
||||||
{
|
|
||||||
"minimum": 5,
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"multipleOf": 2,
|
|
||||||
"type": "integer"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minimum": 20,
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"minLength": 10,
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "object"
|
|
||||||
}
|
|
||||||
)";
|
|
||||||
|
|
||||||
auto generateSchema(const std::string &first_combination, const std::string &second_combination) -> nlohmann::json
|
|
||||||
{
|
|
||||||
static const std::regex first_replace_re{"%COMBINATION_FIRST_LEVEL%"};
|
|
||||||
static const std::regex second_replace_re{"%COMBINATION_SECOND_LEVEL%"};
|
|
||||||
|
|
||||||
std::string intermediate = std::regex_replace(g_schema_template, first_replace_re, first_combination);
|
|
||||||
|
|
||||||
return nlohmann::json::parse(std::regex_replace(intermediate, second_replace_re, second_combination));
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// Error handler to catch all the errors generated by the validator - also inside the combinations
|
|
||||||
//==============================================================================
|
|
||||||
class MyErrorHandler : public nlohmann::json_schema::error_handler
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
struct ErrorEntry {
|
|
||||||
nlohmann::json::json_pointer ptr;
|
|
||||||
nlohmann::json intance;
|
|
||||||
std::string message;
|
|
||||||
};
|
|
||||||
|
|
||||||
using ErrorEntryList = std::vector<ErrorEntry>;
|
|
||||||
|
|
||||||
auto getErrors() const -> const ErrorEntryList &
|
|
||||||
{
|
|
||||||
return m_error_list;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
auto error(const nlohmann::json::json_pointer &ptr, const nlohmann::json &instance, const std::string &message) -> void override
|
|
||||||
{
|
|
||||||
m_error_list.push_back(ErrorEntry{ptr, instance, message});
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorEntryList m_error_list;
|
|
||||||
};
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// Error string helpers
|
|
||||||
//==============================================================================
|
|
||||||
auto operator<<(std::string first, const std::string &second) -> std::string
|
|
||||||
{
|
|
||||||
first += ".*";
|
|
||||||
first += second;
|
|
||||||
return first;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rootError(const std::string &combination_type, std::size_t number_of_subschemas) -> std::string
|
|
||||||
{
|
|
||||||
return "no subschema has succeeded, but one of them is required to validate. Type: " + combination_type + ", number of failed subschemas: " + std::to_string(number_of_subschemas);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto combinationError(const std::string &combination_type, std::size_t test_case_number) -> std::string
|
|
||||||
{
|
|
||||||
return "[combination: " + combination_type + " / case#" + std::to_string(test_case_number) + "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// Validator function - for simplicity
|
|
||||||
//==============================================================================
|
|
||||||
auto validate(const nlohmann::json &schema, const nlohmann::json &instance, nlohmann::json_schema::error_handler *error_handler = nullptr) -> void
|
|
||||||
{
|
|
||||||
nlohmann::json_schema::json_validator validator;
|
|
||||||
validator.set_root_schema(schema);
|
|
||||||
|
|
||||||
if (error_handler) {
|
|
||||||
validator.validate(instance, *error_handler);
|
|
||||||
} else {
|
|
||||||
validator.validate(instance);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// The test cases
|
|
||||||
//==============================================================================
|
|
||||||
auto simpleTest(const std::string &first_combination, const std::string &second_combination) -> void
|
|
||||||
{
|
|
||||||
const nlohmann::json schema = generateSchema(first_combination, second_combination);
|
|
||||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", {{"second", 1}}}}), rootError(first_combination, 3));
|
|
||||||
if (second_combination == "oneOf") {
|
|
||||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", {{"second", 8}}}}), rootError(first_combination, 3));
|
|
||||||
}
|
|
||||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", 10}}), rootError(first_combination, 3));
|
|
||||||
EXPECT_THROW_WITH_MESSAGE(validate(schema, nlohmann::json{{"first", "short"}}), rootError(first_combination, 3));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto verboseTest(const std::string &first_combination, const std::string &second_combination) -> void
|
|
||||||
{
|
|
||||||
const nlohmann::json schema = generateSchema(first_combination, second_combination);
|
|
||||||
|
|
||||||
{
|
|
||||||
MyErrorHandler error_handler;
|
|
||||||
validate(schema, nlohmann::json{{"first", {{"second", 1}}}}, &error_handler);
|
|
||||||
|
|
||||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
|
||||||
EXPECT_EQ(error_list.size(), 6);
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << rootError(second_combination, 2));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 0) << combinationError(second_combination, 0) << "instance is below minimum of 5");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 0) << combinationError(second_combination, 1) << "instance is not a multiple of 2.0");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[4].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[4].message, combinationError(first_combination, 1) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[5].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[5].message, combinationError(first_combination, 2) << "unexpected instance type");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
MyErrorHandler error_handler;
|
|
||||||
validate(schema, nlohmann::json{{"first", {{"second", "not-an-integer"}}}}, &error_handler);
|
|
||||||
|
|
||||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
|
||||||
EXPECT_EQ(error_list.size(), 6);
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << rootError(second_combination, 2));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 0) << combinationError(second_combination, 0) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 0) << combinationError(second_combination, 1) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[4].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[4].message, combinationError(first_combination, 1) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[5].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[5].message, combinationError(first_combination, 2) << "unexpected instance type");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (second_combination == "oneOf") {
|
|
||||||
MyErrorHandler error_handler;
|
|
||||||
validate(schema, nlohmann::json{{"first", {{"second", 8}}}}, &error_handler);
|
|
||||||
|
|
||||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
|
||||||
EXPECT_EQ(error_list.size(), 4);
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first/second"});
|
|
||||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "more than one subschema has succeeded, but exactly one of them is required to validate");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "unexpected instance type");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
MyErrorHandler error_handler;
|
|
||||||
validate(schema, nlohmann::json{{"first", 10}}, &error_handler);
|
|
||||||
|
|
||||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
|
||||||
EXPECT_EQ(error_list.size(), 4);
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "instance is below minimum of 20");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "unexpected instance type");
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
MyErrorHandler error_handler;
|
|
||||||
validate(schema, nlohmann::json{{"first", "short"}}, &error_handler);
|
|
||||||
|
|
||||||
const MyErrorHandler::ErrorEntryList &error_list = error_handler.getErrors();
|
|
||||||
EXPECT_EQ(error_list.size(), 4);
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[0].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[0].message, rootError(first_combination, 3));
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[1].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[1].message, combinationError(first_combination, 0) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[2].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[2].message, combinationError(first_combination, 1) << "unexpected instance type");
|
|
||||||
|
|
||||||
EXPECT_EQ(error_list[3].ptr, nlohmann::json::json_pointer{"/first"});
|
|
||||||
EXPECT_MATCH(error_list[3].message, combinationError(first_combination, 2) << "instance is too short as per minLength:10");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
//==============================================================================
|
|
||||||
// MAIN - calling the test cases
|
|
||||||
//==============================================================================
|
|
||||||
auto main() -> int
|
|
||||||
{
|
|
||||||
simpleTest("anyOf", "anyOf");
|
|
||||||
simpleTest("anyOf", "oneOf");
|
|
||||||
simpleTest("oneOf", "anyOf");
|
|
||||||
simpleTest("oneOf", "oneOf");
|
|
||||||
|
|
||||||
verboseTest("anyOf", "anyOf");
|
|
||||||
verboseTest("anyOf", "oneOf");
|
|
||||||
verboseTest("oneOf", "anyOf");
|
|
||||||
verboseTest("oneOf", "oneOf");
|
|
||||||
|
|
||||||
return g_error_count;
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
#include <nlohmann/json-schema.hpp>
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
using nlohmann::json;
|
|
||||||
using nlohmann::json_schema::json_validator;
|
|
||||||
|
|
||||||
static const json schema = R"(
|
|
||||||
{
|
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
||||||
"$id": "arc.schema.json",
|
|
||||||
"properties": {
|
|
||||||
"angle": {
|
|
||||||
"type": "number",
|
|
||||||
"description": "Radians, from -π to π.",
|
|
||||||
"minimum": -3.14159265358979323846,
|
|
||||||
"maximum": 3.14159265358979323846
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})"_json;
|
|
||||||
|
|
||||||
class custom_error_handler : public nlohmann::json_schema::basic_error_handler
|
|
||||||
{
|
|
||||||
void error(const nlohmann::json::json_pointer &ptr, const json &instance, const std::string &message) override
|
|
||||||
{
|
|
||||||
if (message != "instance exceeds maximum of 3.141592653589793")
|
|
||||||
throw std::invalid_argument("Precision print does not work.");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
json_validator validator;
|
|
||||||
|
|
||||||
auto instance = R"({ "angle": 3.1415927410125732 })"_json;
|
|
||||||
|
|
||||||
validator.set_root_schema(schema);
|
|
||||||
custom_error_handler err;
|
|
||||||
validator.validate(instance, err);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@ -1,32 +0,0 @@
|
|||||||
#include "nlohmann/json-schema.hpp"
|
|
||||||
|
|
||||||
using nlohmann::json_schema::json_validator;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
int should_throw(const nlohmann::json &schema, T value)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
json_validator(schema).validate(value);
|
|
||||||
} catch (const std::exception &ex) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.3 - 0.2);
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 3.3}}).validate(8.0 - 1.4);
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 1000.01}}).validate((1000.03 - 0.02) * 15.0);
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 0.001}}).validate(0.030999999999999993);
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 0.100000}}).validate(1.9);
|
|
||||||
json_validator({{"type", "number"}, {"multipleOf", 100000.1}}).validate(9000009);
|
|
||||||
|
|
||||||
int exc_count = 0;
|
|
||||||
exc_count += should_throw({{"type", "number"}, {"multipleOf", 0.001}}, 0.3 - 0.2005);
|
|
||||||
exc_count += should_throw({{"type", "number"}, {"multipleOf", 1000.02}}, (1000.03 - 0.02) * 15.0);
|
|
||||||
exc_count += should_throw({{"type", "number"}, {"multipleOf", 100000.11}}, 9000009);
|
|
||||||
|
|
||||||
return exc_count;
|
|
||||||
}
|
|
||||||
@ -1,3 +0,0 @@
|
|||||||
add_test_simple_schema(Issue::311
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/schema.json
|
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/instance.json)
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"element": [1],
|
|
||||||
"element2": "test"
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"type": "object",
|
|
||||||
"properties": {
|
|
||||||
"element": {
|
|
||||||
"$ref": "#/$defs/element"
|
|
||||||
},
|
|
||||||
"element2": {
|
|
||||||
"$ref": "#/$defs/element/items/0/$defs/element2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"$defs": {
|
|
||||||
"element": {
|
|
||||||
"type": "array",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"$defs": {
|
|
||||||
"element2": {
|
|
||||||
"type": "string"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "number"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue
Block a user