diff --git a/.github/workflows/common-build.yml b/.github/workflows/common-build.yml new file mode 100644 index 0000000..340ee36 --- /dev/null +++ b/.github/workflows/common-build.yml @@ -0,0 +1,43 @@ +name: Common build and test steps +on: + workflow_call: + inputs: + os: + required: true + type: string + +jobs: + build-and-test: + runs-on: ${{ inputs.os }} + steps: + - name: Set EXT variable + shell: bash + run: | + if [[ "${{ runner.os }}" == "Windows" ]]; then + echo "EXT=.exe" >> $GITHUB_ENV + else + echo "EXT=" >> $GITHUB_ENV + fi + + - name: Checkout cpp-oasvalidator + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - uses: lukka/get-cmake@latest + + - name: Run CMake Ninja build all release preset including example, unittests, perftests + uses: lukka/run-cmake@v10 + id: runcmake + with: + workflowPreset: 'build-example-and-run-unittests' + + - name: Run Example + run: ./build/release/example/oasvalidator-example${{ env.EXT }} + + - name: Run Unit Tests + run: ./build/release/test/unittest/oasvalidator-unittests${{ env.EXT }} + + - name: Run Performance Tests + run: ./build/release/test/perftest/oasvalidator-perftests${{ env.EXT }} \ No newline at end of file diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..47195c1 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,82 @@ +name: Deploy docs and code coverage +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + build-and-deploy-docs-and-codecov: + runs-on: ubuntu-latest + + steps: + - name: Checkout cpp-oasvalidator + uses: actions/checkout@v4 + with: + submodules: true + fetch-depth: 0 + + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Set up latest Oracle JDK 21 + uses: oracle-actions/setup-java@v1 + with: + website: oracle.com + release: 21 + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install doxygen graphviz plantuml lcov -y + + - name: Install python dependencies + run: | + pip3 install gcovr sphinx breathe exhale furo sphinx-plantuml + + - uses: lukka/get-cmake@latest + + - name: Configure code coverage code coverage and docs + uses: lukka/run-cmake@v10 + with: + configurePreset: 'debug' + + - name: Build performance tests in release mode + uses: lukka/run-cmake@v10 + with: + configurePreset: 'release' + buildPreset: 'perftests-build' + + - name: Run performance tests + run: build/release/test/perftest/oasvalidator-perftests --benchmark_format=json > build/debug/docs/benchmark.json + + - name: Convert benchmark.json to benchmark.rst + run: python .github/workflows/convert_json_to_rst.py build/debug/docs/benchmark.json build/debug/docs/benchmark.rst + + - name: Build docs and code coverage + uses: lukka/run-cmake@v10 + with: + workflowPreset: 'build-docs-and-codecov' + + - name: Copy code coverage to docs + run: cp -r build/debug/covhtml-oasvalidator build/debug/docs/html + + - name: Deploy docs + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.MY_PAT }} + publish_dir: build/debug/docs/html + + - name: Generate Coverage Report + if: github.ref == 'refs/heads/main' + run: | + lcov --capture --directory . --output-file coverage.info + lcov --remove coverage.info '/usr/*' --output-file coverage.info + lcov --list coverage.info + + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/linux-build.yml b/.github/workflows/linux-build.yml new file mode 100644 index 0000000..09077f8 --- /dev/null +++ b/.github/workflows/linux-build.yml @@ -0,0 +1,8 @@ +name: Ubuntu build and test +on: [push, workflow_dispatch] + +jobs: + linux-build-and-test: + uses: ./.github/workflows/common-build.yml + with: + os: ubuntu-latest \ No newline at end of file diff --git a/.github/workflows/linux_build.yml b/.github/workflows/linux_build.yml deleted file mode 100644 index d314e27..0000000 --- a/.github/workflows/linux_build.yml +++ /dev/null @@ -1,93 +0,0 @@ -name: Linux Build - -on: - push: - branches: - - main - #- '**' - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - name: Checkout cpp-oasvalidator - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Setup Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'adopt' - - - name: Install dependencies - run: | - sudo apt-get update - sudo apt-get install -y gcc g++ cmake lcov gcovr - sudo apt-get install -y plantuml - sudo apt-get install -yq doxygen - - - name: Install python dependencies - run: | - pip install sphinx breathe exhale furo sphinxcontrib-plantuml - - - name: Build and install libbenchmark - run: | - cd ./thirdparty/benchmark - mkdir build - cmake -E chdir "build" cmake -DBENCHMARK_ENABLE_TESTING=OFF -DBENCHMARK_ENABLE_GTEST_TESTS=OFF -DCMAKE_BUILD_TYPE=Release ../ - sudo cmake --build "build" --config Release --target install -- -j $(nproc) - - - name: Configure CMake - run: cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_COVERAGE=ON -DBUILD_PERF=ON -DBUILD_DOCS=ON -DBUILD_EXAMPLE=ON - - - name: Build oasvalidator - run: cmake --build build --target oasvalidator --config Release -j $(nproc) - - - name: Build oasvalidator-unittests - run: cmake --build build --target oasvalidator-unittests --config Release -j $(nproc) - - - name: Build oasvalidator-perftests - run: cmake --build build --target oasvalidator-perftests --config Release -j $(nproc) - - - name: Run oasvalidator-perftests - run: build/test/perftest/oasvalidator-perftests --benchmark_format=json > build/test/perftest/benchmark.json - - - name: Convert benchmark.json to benchmark.rst - run: python .github/workflows/convert_json_to_rst.py build/test/perftest/benchmark.json build/docs/benchmark.rst - - - name: Build covhtml-oasvalidator - run: cmake --build build --target covhtml-oasvalidator --config Release -j $(nproc) - - - name: Build docs - run: cmake --build build --target docs --config Release -j $(nproc) - - - name: Copy covhtml-oasvalidator to docs - run: cp -r build/covhtml-oasvalidator build/docs/html - - - name: Deploy docs - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.MY_PAT }} - publish_dir: build/docs/html - - - name: Generate Coverage Report - if: github.ref == 'refs/heads/main' - run: | - lcov --capture --directory . --output-file coverage.info - lcov --remove coverage.info '/usr/*' --output-file coverage.info - lcov --list coverage.info - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml new file mode 100644 index 0000000..e7ee6f5 --- /dev/null +++ b/.github/workflows/mac-build.yml @@ -0,0 +1,8 @@ +name: Mac build and test +on: [push, workflow_dispatch] + +jobs: + macos-build-and-test: + uses: ./.github/workflows/common-build.yml + with: + os: macos-latest diff --git a/.github/workflows/mac_build.yml b/.github/workflows/mac_build.yml deleted file mode 100644 index 916ffa6..0000000 --- a/.github/workflows/mac_build.yml +++ /dev/null @@ -1,90 +0,0 @@ -name: Mac Build - -on: - push: - branches: - - main - #- '**' - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: macos-latest - - steps: - - uses: actions/checkout@v4 - with: - submodules: 'true' - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Install dependencies - run: | - brew install cmake - brew install ccache - brew install doxygen - brew install lcov - brew install gcovr - - - name: Install python dependencies - run: | - pip install sphinx breathe exhale furo sphinxcontrib-plantuml - - - name: Configure CMake - run: cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_COVERAGE=ON -DBUILD_PERF=ON -DBUILD_DOCS=ON -DBUILD_EXAMPLE=ON - - - name: Build oasvalidator - run: cmake --build build --target oasvalidator --config Release - - - name: Build oasvalidator-unittests - run: cmake --build build --target oasvalidator-unittests --config Release - - - name: Build oasvalidator-perftests - run: cmake --build build --target oasvalidator-perftests --config Release - - - name: Run oasvalidator-perftests - run: build/test/perftest/oasvalidator-perftests --benchmark_format=json > build/test/perftest/benchmark.json - - - name: Convert benchmark.json to benchmark.rst - run: python .github/workflows/convert_json_to_rst.py build/test/perftest/benchmark.json build/docs/benchmark.rst - - - name: Build covhtml-oasvalidator - run: cmake --build build --target covhtml-oasvalidator --config Release - - - name: Set up JDK 21 - uses: actions/setup-java@v3 - with: - distribution: 'temurin' - java-version: '21' - - - name: Install PlantUML - run: | - brew install plantuml - - - name: Build docs - run: cmake --build build --target docs --config Release - - - name: Copy covhtml-oasvalidator to docs - run: cp -r build/covhtml-oasvalidator build/docs/html - - - name: Deploy docs - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.MY_PAT }} - publish_dir: build/docs/html - - - name: Generate Coverage Report - if: github.ref == 'refs/heads/main' - run: | - lcov --capture --directory . --output-file coverage.info - lcov --remove coverage.info '/usr/*' --output-file coverage.info - lcov --list coverage.info - - - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/win_build.yml b/.github/workflows/win_build.yml deleted file mode 100644 index bdd7743..0000000 --- a/.github/workflows/win_build.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: Win Build - -on: - push: - branches: - - main - - '**' - pull_request: - branches: [ main ] - -jobs: - build: - runs-on: windows-latest - - steps: - - name: Checkout cpp-oasvalidator - uses: actions/checkout@v4 - with: - submodules: 'recursive' - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Setup Java 17 - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'adopt' - - - name: Install doxygen - uses: ssciwr/doxygen-install@v1 - - - name: Install dependencies - run: | - choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System' - choco install graphviz - choco install plantuml - choco install sphinx - - - name: Install python dependencies - run: | - pip install sphinx breathe exhale furo sphinxcontrib-plantuml - - - name: Configure CMake - run: cmake -S . -B build -DBUILD_TESTS=ON -DBUILD_PERF=ON -DBUILD_DOCS=ON -DBUILD_EXAMPLE=ON -DBUILD_SHARED_LIB=OFF - - name: List recusrive build artifacts - run: ls -R build - - name: Build oasvalidator - run: cmake --build build --target oasvalidator --config Release - - -# - name: Build example -# run: cmake --build build --target oasvalidator-example --config Release - -# - name: Run example -# run: build/example/Release/oasvalidator-example.exe - - - name: Build oasvalidator-unittests - run: cmake --build build --target oasvalidator-unittests --config Release - - - name: Run oasvalidator-unittests - run: build/test/unittest/Release/oasvalidator-unittests.exe - - - name: Build oasvalidator-perftests - run: cmake --build build --target oasvalidator-perftests --config Release -j $(nproc) - - - name: Run oasvalidator-perftests - run: build/test/perftest/Release/oasvalidator-perftests.exe --benchmark_format=json > build/test/perftest/Release/benchmark.json - - - name: List recusrive build - run: ls -R build - - name: Convert benchmark.json to benchmark.rst - run: python .github/workflows/convert_json_to_rst.py build/test/perftest/Release/benchmark.json build/docs/benchmark.rst - - - name: Build docs - run: cmake --build build --target docs - - - name: Deploy docs - uses: peaceiris/actions-gh-pages@v3 - with: - github_token: ${{ secrets.MY_PAT }} - publish_dir: build/docs/html diff --git a/.github/workflows/windows-build.yml b/.github/workflows/windows-build.yml new file mode 100644 index 0000000..d1cdf16 --- /dev/null +++ b/.github/workflows/windows-build.yml @@ -0,0 +1,8 @@ +name: Windows build and test +on: [push, workflow_dispatch] + +jobs: + windows-build-and-test: + uses: ./.github/workflows/common-build.yml + with: + os: windows-latest \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index c6ca5fa..37c1987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,9 +6,9 @@ endif () if (POLICY CMP0054) cmake_policy(SET CMP0054 NEW) endif () -if(POLICY CMP0091) - cmake_policy(SET CMP0091 NEW) -endif() +if (POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) +endif () SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) @@ -22,10 +22,12 @@ set(OASVALIDATOR_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") set(OASVALIDATOR_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md") message(STATUS "Building oasvalidator version ${OASVALIDATOR_VERSION_STRING}") -project(oasvalidator LANGUAGES CXX +project(cpp-oasvalidator LANGUAGES CXX VERSION "${OASVALIDATOR_VERSION_STRING}" DESCRIPTION "A FAST C++ library to validate the HTTP requests against the OpenAPI specifications of the REST server") +set(OASVALIDATOR oasvalidator) + # Default to release build type with specific optimization flags if (NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) @@ -47,9 +49,7 @@ if (OASVALIDATOR_BUILD_CXX11) elseif (OASVALIDATOR_BUILD_CXX17) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED TRUE) -endif() - -message(STATUS "EXTRA_CXX_FLAGS: ${EXTRA_CXX_FLAGS}") +endif () find_program(CCACHE_FOUND ccache) if (CCACHE_FOUND) @@ -59,7 +59,7 @@ if (CCACHE_FOUND) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics") endif () -endif() +endif () ############################# Compiler-specific settings ############################# if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") @@ -81,7 +81,7 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") elseif (OASVALIDATOR_BUILD_CXX17 AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0") message(STATUS "Building with C++17") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17") - endif() + endif () elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang") message(STATUS "Using Clang compiler") if (NOT CMAKE_CROSSCOMPILING) @@ -127,20 +127,20 @@ endif () # if release build, add extra optimization flags if (CMAKE_BUILD_TYPE STREQUAL "Release") message(STATUS "Adding extra optimization flags for release build") - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -ffast-math -funroll-loops -fomit-frame-pointer -DNDEBUG -fno-strict-aliasing -fvisibility-inlines-hidden") - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Ox /Ob2 /Oi /Ot /Oy /GL /fp:fast /GS- /Gy /DNDEBUG") - endif() -endif() + endif () +endif () #add extra search paths for libraries and includes SET(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The directory the headers are installed in") SET(LIB_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE STRING "Directory where lib will install") -SET(DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${PROJECT_NAME}" CACHE PATH "Path to the documentation") +SET(DOC_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/share/doc/${OASVALIDATOR}" CACHE PATH "Path to the documentation") if (UNIX OR CYGWIN) - SET(_CMAKE_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake/${PROJECT_NAME}") + SET(_CMAKE_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake/${OASVALIDATOR}") elseif (WIN32) SET(_CMAKE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/cmake") endif () @@ -149,7 +149,7 @@ SET(CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" CACHE PATH "The directory cmake fi # Specify RapidJSON directories or fallback to default if (NOT RAPIDJSON_INCLUDE_DIRS) set(RAPIDJSON_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/rapidjson/include") -endif() +endif () file(GLOB_RECURSE SOURCES "src/*.cpp") @@ -161,21 +161,21 @@ endif () set(OAS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_include_directories(${PROJECT_NAME} +target_include_directories(${OASVALIDATOR} PRIVATE ${RAPIDJSON_INCLUDE_DIRS} ${OAS_INCLUDE_DIR} ) -set_target_properties(${PROJECT_NAME} PROPERTIES +set_target_properties(${OASVALIDATOR} PROPERTIES SOVERSION "${OASVALIDATOR_VERSION_STRING}" VERSION "${OASVALIDATOR_VERSION_STRING}" LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) ############################# Installation ############################# -install(TARGETS ${PROJECT_NAME} - EXPORT ${PROJECT_NAME}-targets +install(TARGETS ${OASVALIDATOR} + EXPORT ${OASVALIDATOR}-targets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib ) @@ -191,26 +191,33 @@ install(FILES LICENSE ############################# Subprojects ############################# # Export package for use from the build tree -EXPORT(PACKAGE ${PROJECT_NAME}) +EXPORT(PACKAGE ${OASVALIDATOR}) if (BUILD_COVERAGE) - set(PROJECT_TEST_NAME ${PROJECT_NAME}-unittests) - include(cmake/CodeCoverage.cmake) + set(TEST_TARGET ${OASVALIDATOR}-unittests) + set(DOWNLOADED_CMAKE_MODULES "${CMAKE_BINARY_DIR}/downloaded_cmake_modules") + file(MAKE_DIRECTORY ${DOWNLOADED_CMAKE_MODULES}) + set(CODE_COVERAGE_SCRIPT "https://raw.githubusercontent.com/bilke/cmake-modules/70a0b5209a2a7cbea181b148ca645e4181f394bc/CodeCoverage.cmake") + file(DOWNLOAD ${CODE_COVERAGE_SCRIPT} "${DOWNLOADED_CMAKE_MODULES}/CodeCoverage.cmake") + include("${DOWNLOADED_CMAKE_MODULES}/CodeCoverage.cmake") enable_testing() append_coverage_compiler_flags() setup_target_for_coverage_gcovr_html( - NAME covhtml-${PROJECT_NAME} - EXECUTABLE ${PROJECT_NAME}-unittests + NAME covhtml-${OASVALIDATOR} + EXECUTABLE ${TEST_TARGET} BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/* + EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/* + EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/build/* ) endif () + if (BUILD_TESTS OR BUILD_COVERAGE) add_subdirectory(test/unittest) + include(CTest) endif () -if(BUILD_PERF) - # Use thidpart/benchmark as a subproject +if (BUILD_PERF) + # Use thirdparty/benchmark as a subproject set(BENCHMARK_ENABLE_INSTALL OFF CACHE BOOL "Disable benchmark install") set(BENCHMARK_INSTALL_DOCS OFF CACHE BOOL "Disable benchmark docs install") set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "Disable benchmark tests") diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 0000000..a11f52e --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,141 @@ +{ + "version": 6, + "configurePresets": [ + { + "name": "debug", + "displayName": "Debug configuration for code coverage and docs", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "BUILD_COVERAGE": "ON", + "BUILD_DOCS": "ON", + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "release", + "displayName": "Release configuration for oasvalidator, tests and example", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build/${presetName}", + "cacheVariables": { + "BUILD_SHARED_LIB": "OFF", + "BUILD_TESTS": "ON", + "BUILD_PERF": "ON", + "BUILD_EXAMPLE": "ON", + "CMAKE_BUILD_TYPE": "Release" + } + } + ], + "buildPresets": [ + { + "name": "oasvalidator-build", + "displayName": "Build oasvalidator Release", + "configurePreset": "release", + "targets": [ + "oasvalidator" + ] + }, + { + "name": "tests-build", + "displayName": "Build oasvalidator tests Release", + "configurePreset": "release", + "targets": [ + "oasvalidator-unittests", + "oasvalidator-perftests" + ] + }, + { + "name": "perftests-build", + "displayName": "Build oasvalidator tests Release", + "configurePreset": "release", + "targets": [ + "oasvalidator-perftests" + ] + }, + { + "name": "example-build", + "displayName": "Build oasvalidator example", + "configurePreset": "release", + "targets": [ + "oasvalidator-example" + ] + }, + { + "name": "docs-build", + "displayName": "Build oasvalidator docs", + "configurePreset": "debug", + "targets": [ + "docs" + ] + }, + { + "name": "codecov-build", + "displayName": "Build oasvalidator codecov", + "configurePreset": "debug", + "targets": [ + "covhtml-oasvalidator" + ] + } + ], + "testPresets": [ + { + "name": "run-oasvalidator-unittests", + "displayName": "Test oasvalidator", + "configurePreset": "release", + "output": { + "shortProgress": true, + "verbosity": "extra" + }, + "execution": { + "noTestsAction": "error", + "testMode": "exclusive" + } + } + ], + "workflowPresets": [ + { + "name": "build-docs-and-codecov", + "displayName": "Build oasvalidator, docs and code coverage in Debug mode", + "steps": [ + { + "type": "configure", + "name": "debug" + }, + { + "type": "build", + "name": "docs-build" + }, + { + "type": "build", + "name": "codecov-build" + } + ] + }, + { + "name": "build-example-and-run-unittests", + "displayName": "Build oasvalidator, unittest, perftests and example in Release mode and run unittests", + "steps": [ + { + "type": "configure", + "name": "release" + }, + { + "type": "build", + "name": "oasvalidator-build" + }, + { + "type": "build", + "name": "example-build" + }, + { + "type": "build", + "name": "tests-build" + }, + { + "type": "test", + "name": "run-oasvalidator-unittests" + } + ] + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 5f3b4e0..fdb14fd 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ cpp-oasvalidator: REST Request Validator [![Language C++](https://img.shields.io/badge/language-c++-blue.svg?logo=c%2B%2B)](https://isocpp.org) [![Github releases](https://img.shields.io/github/release/nawaz1991/cpp-oasvalidator.svg)](https://github.com/nawaz1991/cpp-oasvalidator/releases) -![Mac build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/mac_build.yml?logo=apple&label=Build) -![Linux build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/linux_build.yml?logo=linux&label=Build) -![Win build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/win_build.yml?logo=windows&label=Build) +![Mac build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/mac-build.yml?logo=apple&label=Tests) +![Linux build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/linux-build.yml?logo=linux&label=Tests) +![Win build](https://img.shields.io/github/actions/workflow/status/nawaz1991/cpp-oasvalidator/windows-build.yml?logo=windows&label=Tests) [![codecov](https://codecov.io/gh/nawaz1991/cpp-oasvalidator/branch/main/graph/badge.svg?token=96b475c2-8dc1-4693-8ce3-84a572720d43)](https://codecov.io/gh/nawaz1991/cpp-oasvalidator) [![License](https://img.shields.io/github/license/nawaz1991/cpp-oasvalidator.svg)](./LICENSE) [![API Docs](https://img.shields.io/badge/API%20Docs-v1.0.0-brightgreen)](API.md) @@ -195,7 +195,7 @@ To generate the code coverage report, follow the steps below: 1. Navigate to the root directory of the project. 2. Run the following commands: ```bash - cmake -S . -B build -DBUILD_COVERAGE=ON + cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -DBUILD_COVERAGE=ON cmake --build build --target covhtml-oasvalidator -j $(nproc) ``` The coverage report will be generated in the `build/covhtml-cpp-oasvalidator/` directory. Open `index.html` in your browser to view the report. @@ -220,8 +220,8 @@ To run the example, follow the steps below: 2. Run the following commands: ```bash cmake -S . -B build -DBUILD_EXAMPLE=ON - cmake --build build --target example -j $(nproc) - build/example/example + cmake --build build --target oasvalidator-example -j $(nproc) + build/example/oasvalidator-example ``` ### 5.1.7 Generating API Documentation diff --git a/cmake/CodeCoverage.cmake b/cmake/CodeCoverage.cmake deleted file mode 100644 index 24f5f37..0000000 --- a/cmake/CodeCoverage.cmake +++ /dev/null @@ -1,736 +0,0 @@ -# Copyright (c) 2012 - 2017, Lars Bilke -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, this -# list of conditions and the following disclaimer. -# -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# -# 3. Neither the name of the copyright holder nor the names of its contributors -# may be used to endorse or promote products derived from this software without -# specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR -# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -# CHANGES: -# -# 2012-01-31, Lars Bilke -# - Enable Code Coverage -# -# 2013-09-17, Joakim Söderberg -# - Added support for Clang. -# - Some additional usage instructions. -# -# 2016-02-03, Lars Bilke -# - Refactored functions to use named parameters -# -# 2017-06-02, Lars Bilke -# - Merged with modified version from github.com/ufz/ogs -# -# 2019-05-06, Anatolii Kurotych -# - Remove unnecessary --coverage flag -# -# 2019-12-13, FeRD (Frank Dana) -# - Deprecate COVERAGE_LCOVR_EXCLUDES and COVERAGE_GCOVR_EXCLUDES lists in favor -# of tool-agnostic COVERAGE_EXCLUDES variable, or EXCLUDE setup arguments. -# - CMake 3.4+: All excludes can be specified relative to BASE_DIRECTORY -# - All setup functions: accept BASE_DIRECTORY, EXCLUDE list -# - Set lcov basedir with -b argument -# - Add automatic --demangle-cpp in lcovr, if 'c++filt' is available (can be -# overridden with NO_DEMANGLE option in setup_target_for_coverage_lcovr().) -# - Delete output dir, .info file on 'make clean' -# - Remove Python detection, since version mismatches will break gcovr -# - Minor cleanup (lowercase function names, update examples...) -# -# 2019-12-19, FeRD (Frank Dana) -# - Rename Lcov outputs, make filtered file canonical, fix cleanup for targets -# -# 2020-01-19, Bob Apthorpe -# - Added gfortran support -# -# 2020-02-17, FeRD (Frank Dana) -# - Make all add_custom_target()s VERBATIM to auto-escape wildcard characters -# in EXCLUDEs, and remove manual escaping from gcovr targets -# -# 2021-01-19, Robin Mueller -# - Add CODE_COVERAGE_VERBOSE option which will allow to print out commands which are run -# - Added the option for users to set the GCOVR_ADDITIONAL_ARGS variable to supply additional -# flags to the gcovr command -# -# 2020-05-04, Mihchael Davis -# - Add -fprofile-abs-path to make gcno files contain absolute paths -# - Fix BASE_DIRECTORY not working when defined -# - Change BYPRODUCT from folder to index.html to stop ninja from complaining about double defines -# -# 2021-05-10, Martin Stump -# - Check if the generator is multi-config before warning about non-Debug builds -# -# 2022-02-22, Marko Wehle -# - Change gcovr output from -o for --xml and --html output respectively. -# This will allow for Multiple Output Formats at the same time by making use of GCOVR_ADDITIONAL_ARGS, e.g. GCOVR_ADDITIONAL_ARGS "--txt". -# -# USAGE: -# -# 1. Copy this file into your cmake modules path. -# -# 2. Add the following line to your CMakeLists.txt (best inside an if-condition -# using a CMake option() to enable it just optionally): -# include(CodeCoverage) -# -# 3. Append necessary compiler flags for all supported source files: -# append_coverage_compiler_flags() -# Or for specific target: -# append_coverage_compiler_flags_to_target(YOUR_TARGET_NAME) -# -# 3.a (OPTIONAL) Set appropriate optimization flags, e.g. -O0, -O1 or -Og -# -# 4. If you need to exclude additional directories from the report, specify them -# using full paths in the COVERAGE_EXCLUDES variable before calling -# setup_target_for_coverage_*(). -# Example: -# set(COVERAGE_EXCLUDES -# '${PROJECT_SOURCE_DIR}/src/dir1/*' -# '/path/to/my/src/dir2/*') -# Or, use the EXCLUDE argument to setup_target_for_coverage_*(). -# Example: -# setup_target_for_coverage_lcov( -# NAME coverage -# EXECUTABLE testrunner -# EXCLUDE "${PROJECT_SOURCE_DIR}/src/dir1/*" "/path/to/my/src/dir2/*") -# -# 4.a NOTE: With CMake 3.4+, COVERAGE_EXCLUDES or EXCLUDE can also be set -# relative to the BASE_DIRECTORY (default: PROJECT_SOURCE_DIR) -# Example: -# set(COVERAGE_EXCLUDES "dir1/*") -# setup_target_for_coverage_gcovr_html( -# NAME coverage -# EXECUTABLE testrunner -# BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/src" -# EXCLUDE "dir2/*") -# -# 5. Use the functions described below to create a custom make target which -# runs your test executable and produces a code coverage report. -# -# 6. Build a Debug build: -# cmake -DCMAKE_BUILD_TYPE=Debug .. -# make -# make my_coverage_target -# - -include(CMakeParseArguments) - -option(CODE_COVERAGE_VERBOSE "Verbose information" FALSE) - -# Check prereqs -find_program( GCOV_PATH gcov ) -find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl) -find_program( FASTCOV_PATH NAMES fastcov fastcov.py ) -find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat ) -find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test) -find_program( CPPFILT_PATH NAMES c++filt ) - -if(NOT GCOV_PATH) - message(FATAL_ERROR "gcov not found! Aborting...") -endif() # NOT GCOV_PATH - -# Check supported compiler (Clang, GNU and Flang) -get_property(LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) -foreach(LANG ${LANGUAGES}) - if("${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang") - if("${CMAKE_${LANG}_COMPILER_VERSION}" VERSION_LESS 3) - message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...") - endif() - elseif(NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "GNU" - AND NOT "${CMAKE_${LANG}_COMPILER_ID}" MATCHES "(LLVM)?[Ff]lang") - message(FATAL_ERROR "Compiler is not GNU or Flang! Aborting...") - endif() -endforeach() - -set(COVERAGE_COMPILER_FLAGS "-g -fprofile-arcs -ftest-coverage" - CACHE INTERNAL "") -if(CMAKE_CXX_COMPILER_ID MATCHES "(GNU|Clang)") - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-fprofile-abs-path HAVE_fprofile_abs_path) - if(HAVE_fprofile_abs_path) - set(COVERAGE_COMPILER_FLAGS "${COVERAGE_COMPILER_FLAGS} -fprofile-abs-path") - endif() -endif() - -set(CMAKE_Fortran_FLAGS_COVERAGE - ${COVERAGE_COMPILER_FLAGS} - CACHE STRING "Flags used by the Fortran compiler during coverage builds." - FORCE ) -set(CMAKE_CXX_FLAGS_COVERAGE - ${COVERAGE_COMPILER_FLAGS} - CACHE STRING "Flags used by the C++ compiler during coverage builds." - FORCE ) -set(CMAKE_C_FLAGS_COVERAGE - ${COVERAGE_COMPILER_FLAGS} - CACHE STRING "Flags used by the C compiler during coverage builds." - FORCE ) -set(CMAKE_EXE_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used for linking binaries during coverage builds." - FORCE ) -set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE - "" - CACHE STRING "Flags used by the shared libraries linker during coverage builds." - FORCE ) -mark_as_advanced( - CMAKE_Fortran_FLAGS_COVERAGE - CMAKE_CXX_FLAGS_COVERAGE - CMAKE_C_FLAGS_COVERAGE - CMAKE_EXE_LINKER_FLAGS_COVERAGE - CMAKE_SHARED_LINKER_FLAGS_COVERAGE ) - -get_property(GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) -if(NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG)) - message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading") -endif() # NOT (CMAKE_BUILD_TYPE STREQUAL "Debug" OR GENERATOR_IS_MULTI_CONFIG) - -if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_Fortran_COMPILER_ID STREQUAL "GNU") - link_libraries(gcov) -endif() - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# setup_target_for_coverage_lcov( -# NAME testrunner_coverage # New target name -# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES testrunner # Dependencies to build first -# BASE_DIRECTORY "../" # Base directory for report -# # (defaults to PROJECT_SOURCE_DIR) -# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative -# # to BASE_DIRECTORY, with CMake 3.4+) -# NO_DEMANGLE # Don't demangle C++ symbols -# # even if c++filt is found -# ) -function(setup_target_for_coverage_lcov) - - set(options NO_DEMANGLE SONARQUBE) - set(oneValueArgs BASE_DIRECTORY NAME) - set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT LCOV_PATH) - message(FATAL_ERROR "lcov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() # NOT GENHTML_PATH - - # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR - if(DEFINED Coverage_BASE_DIRECTORY) - get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) - else() - set(BASEDIR ../..) - endif() - - # Collect excludes (CMake 3.4+: Also compute absolute paths) - set(LCOV_EXCLUDES "") - foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_LCOV_EXCLUDES}) - if(CMAKE_VERSION VERSION_GREATER 3.4) - get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) - endif() - list(APPEND LCOV_EXCLUDES "${EXCLUDE}") - endforeach() - list(REMOVE_DUPLICATES LCOV_EXCLUDES) - - # Conditional arguments - if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE}) - set(GENHTML_EXTRA_ARGS "--demangle-cpp") - endif() - - # Setting up commands which will be run to generate coverage data. - # Cleanup lcov - set(LCOV_CLEAN_CMD - ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . - -b ${BASEDIR} --zerocounters - ) - # Create baseline to make sure untouched files show up in the report - set(LCOV_BASELINE_CMD - ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -b - ${BASEDIR} -o ${Coverage_NAME}.base - ) - # Run tests - set(LCOV_EXEC_TESTS_CMD - ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} - ) - # Capturing lcov counters and generating report - set(LCOV_CAPTURE_CMD - ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . -b - ${BASEDIR} --capture --output-file ${Coverage_NAME}.capture - ) - # add baseline counters - set(LCOV_BASELINE_COUNT_CMD - ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base - -a ${Coverage_NAME}.capture --output-file ${Coverage_NAME}.total - ) - # filter collected data to final coverage report - set(LCOV_FILTER_CMD - ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove - ${Coverage_NAME}.total ${LCOV_EXCLUDES} --output-file ${Coverage_NAME}.info - ) - # Generate HTML output - set(LCOV_GEN_HTML_CMD - ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} -o - ${Coverage_NAME} ${Coverage_NAME}.info - ) - if(${Coverage_SONARQUBE}) - # Generate SonarQube output - set(GCOVR_XML_CMD - ${GCOVR_PATH} --sonarqube ${Coverage_NAME}_sonarqube.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} - ${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR} - ) - set(GCOVR_XML_CMD_COMMAND - COMMAND ${GCOVR_XML_CMD} - ) - set(GCOVR_XML_CMD_BYPRODUCTS ${Coverage_NAME}_sonarqube.xml) - set(GCOVR_XML_CMD_COMMENT COMMENT "SonarQube code coverage info report saved in ${Coverage_NAME}_sonarqube.xml.") - endif() - - - if(CODE_COVERAGE_VERBOSE) - message(STATUS "Executed command report") - message(STATUS "Command to clean up lcov: ") - string(REPLACE ";" " " LCOV_CLEAN_CMD_SPACED "${LCOV_CLEAN_CMD}") - message(STATUS "${LCOV_CLEAN_CMD_SPACED}") - - message(STATUS "Command to create baseline: ") - string(REPLACE ";" " " LCOV_BASELINE_CMD_SPACED "${LCOV_BASELINE_CMD}") - message(STATUS "${LCOV_BASELINE_CMD_SPACED}") - - message(STATUS "Command to run the tests: ") - string(REPLACE ";" " " LCOV_EXEC_TESTS_CMD_SPACED "${LCOV_EXEC_TESTS_CMD}") - message(STATUS "${LCOV_EXEC_TESTS_CMD_SPACED}") - - message(STATUS "Command to capture counters and generate report: ") - string(REPLACE ";" " " LCOV_CAPTURE_CMD_SPACED "${LCOV_CAPTURE_CMD}") - message(STATUS "${LCOV_CAPTURE_CMD_SPACED}") - - message(STATUS "Command to add baseline counters: ") - string(REPLACE ";" " " LCOV_BASELINE_COUNT_CMD_SPACED "${LCOV_BASELINE_COUNT_CMD}") - message(STATUS "${LCOV_BASELINE_COUNT_CMD_SPACED}") - - message(STATUS "Command to filter collected data: ") - string(REPLACE ";" " " LCOV_FILTER_CMD_SPACED "${LCOV_FILTER_CMD}") - message(STATUS "${LCOV_FILTER_CMD_SPACED}") - - message(STATUS "Command to generate lcov HTML output: ") - string(REPLACE ";" " " LCOV_GEN_HTML_CMD_SPACED "${LCOV_GEN_HTML_CMD}") - message(STATUS "${LCOV_GEN_HTML_CMD_SPACED}") - - if(${Coverage_SONARQUBE}) - message(STATUS "Command to generate SonarQube XML output: ") - string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}") - message(STATUS "${GCOVR_XML_CMD_SPACED}") - endif() - endif() - - # Setup target - add_custom_target(${Coverage_NAME} - COMMAND ${LCOV_CLEAN_CMD} - COMMAND ${LCOV_BASELINE_CMD} - COMMAND ${LCOV_EXEC_TESTS_CMD} - COMMAND ${LCOV_CAPTURE_CMD} - COMMAND ${LCOV_BASELINE_COUNT_CMD} - COMMAND ${LCOV_FILTER_CMD} - COMMAND ${LCOV_GEN_HTML_CMD} - ${GCOVR_XML_CMD_COMMAND} - - # Set output files as GENERATED (will be removed on 'make clean') - BYPRODUCTS - ${Coverage_NAME}.base - ${Coverage_NAME}.capture - ${Coverage_NAME}.total - ${Coverage_NAME}.info - ${GCOVR_XML_CMD_BYPRODUCTS} - ${Coverage_NAME}/index.html - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - VERBATIM # Protect arguments to commands - COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report." - ) - - # Show where to find the lcov info report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info." - ${GCOVR_XML_CMD_COMMENT} - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) - -endfunction() # setup_target_for_coverage_lcov - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# setup_target_for_coverage_gcovr_xml( -# NAME ctest_coverage # New target name -# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES executable_target # Dependencies to build first -# BASE_DIRECTORY "../" # Base directory for report -# # (defaults to PROJECT_SOURCE_DIR) -# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative -# # to BASE_DIRECTORY, with CMake 3.4+) -# ) -# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the -# GCVOR command. -function(setup_target_for_coverage_gcovr_xml) - - set(options NONE) - set(oneValueArgs BASE_DIRECTORY NAME) - set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT GCOVR_PATH) - message(FATAL_ERROR "gcovr not found! Aborting...") - endif() # NOT GCOVR_PATH - - # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR - if(DEFINED Coverage_BASE_DIRECTORY) - get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) - else() - set(BASEDIR ../..) - endif() - - # Collect excludes (CMake 3.4+: Also compute absolute paths) - set(GCOVR_EXCLUDES "") - foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) - if(CMAKE_VERSION VERSION_GREATER 3.4) - get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) - endif() - list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") - endforeach() - list(REMOVE_DUPLICATES GCOVR_EXCLUDES) - - # Combine excludes to several -e arguments - set(GCOVR_EXCLUDE_ARGS "") - foreach(EXCLUDE ${GCOVR_EXCLUDES}) - list(APPEND GCOVR_EXCLUDE_ARGS "-e") - list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") - endforeach() - - # Set up commands which will be run to generate coverage data - # Run tests - set(GCOVR_XML_EXEC_TESTS_CMD - ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} - ) - # Running gcovr - set(GCOVR_XML_CMD - ${GCOVR_PATH} --xml ${Coverage_NAME}.xml -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} - ${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR} - ) - - if(CODE_COVERAGE_VERBOSE) - message(STATUS "Executed command report") - - message(STATUS "Command to run tests: ") - string(REPLACE ";" " " GCOVR_XML_EXEC_TESTS_CMD_SPACED "${GCOVR_XML_EXEC_TESTS_CMD}") - message(STATUS "${GCOVR_XML_EXEC_TESTS_CMD_SPACED}") - - message(STATUS "Command to generate gcovr XML coverage data: ") - string(REPLACE ";" " " GCOVR_XML_CMD_SPACED "${GCOVR_XML_CMD}") - message(STATUS "${GCOVR_XML_CMD_SPACED}") - endif() - - add_custom_target(${Coverage_NAME} - COMMAND ${GCOVR_XML_EXEC_TESTS_CMD} - COMMAND ${GCOVR_XML_CMD} - - BYPRODUCTS ${Coverage_NAME}.xml - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - VERBATIM # Protect arguments to commands - COMMENT "Running gcovr to produce Cobertura code coverage report." - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml." - ) -endfunction() # setup_target_for_coverage_gcovr_xml - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# setup_target_for_coverage_gcovr_html( -# NAME ctest_coverage # New target name -# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES executable_target # Dependencies to build first -# BASE_DIRECTORY "../" # Base directory for report -# # (defaults to PROJECT_SOURCE_DIR) -# EXCLUDE "src/dir1/*" "src/dir2/*" # Patterns to exclude (can be relative -# # to BASE_DIRECTORY, with CMake 3.4+) -# ) -# The user can set the variable GCOVR_ADDITIONAL_ARGS to supply additional flags to the -# GCVOR command. -function(setup_target_for_coverage_gcovr_html) - - set(options NONE) - set(oneValueArgs BASE_DIRECTORY NAME) - set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT GCOVR_PATH) - message(FATAL_ERROR "gcovr not found! Aborting...") - endif() # NOT GCOVR_PATH - - # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR - if(DEFINED Coverage_BASE_DIRECTORY) - get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) - else() - set(BASEDIR ../..) - endif() - - # Collect excludes (CMake 3.4+: Also compute absolute paths) - set(GCOVR_EXCLUDES "") - foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_GCOVR_EXCLUDES}) - if(CMAKE_VERSION VERSION_GREATER 3.4) - get_filename_component(EXCLUDE ${EXCLUDE} ABSOLUTE BASE_DIR ${BASEDIR}) - endif() - list(APPEND GCOVR_EXCLUDES "${EXCLUDE}") - endforeach() - list(REMOVE_DUPLICATES GCOVR_EXCLUDES) - - # Combine excludes to several -e arguments - set(GCOVR_EXCLUDE_ARGS "") - foreach(EXCLUDE ${GCOVR_EXCLUDES}) - list(APPEND GCOVR_EXCLUDE_ARGS "-e") - list(APPEND GCOVR_EXCLUDE_ARGS "${EXCLUDE}") - endforeach() - - # Set up commands which will be run to generate coverage data - # Run tests - set(GCOVR_HTML_EXEC_TESTS_CMD - ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS} - ) - # Create folder - set(GCOVR_HTML_FOLDER_CMD - ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME} - ) - # Running gcovr - set(GCOVR_HTML_CMD - ${GCOVR_PATH} --html ${Coverage_NAME}/index.html --html-details -r ${BASEDIR} ${GCOVR_ADDITIONAL_ARGS} - ${GCOVR_EXCLUDE_ARGS} --object-directory=${PROJECT_BINARY_DIR} - ) - - if(CODE_COVERAGE_VERBOSE) - message(STATUS "Executed command report") - - message(STATUS "Command to run tests: ") - string(REPLACE ";" " " GCOVR_HTML_EXEC_TESTS_CMD_SPACED "${GCOVR_HTML_EXEC_TESTS_CMD}") - message(STATUS "${GCOVR_HTML_EXEC_TESTS_CMD_SPACED}") - - message(STATUS "Command to create a folder: ") - string(REPLACE ";" " " GCOVR_HTML_FOLDER_CMD_SPACED "${GCOVR_HTML_FOLDER_CMD}") - message(STATUS "${GCOVR_HTML_FOLDER_CMD_SPACED}") - - message(STATUS "Command to generate gcovr HTML coverage data: ") - string(REPLACE ";" " " GCOVR_HTML_CMD_SPACED "${GCOVR_HTML_CMD}") - message(STATUS "${GCOVR_HTML_CMD_SPACED}") - endif() - - add_custom_target(${Coverage_NAME} - COMMAND ${GCOVR_HTML_EXEC_TESTS_CMD} - COMMAND ${GCOVR_HTML_FOLDER_CMD} - COMMAND ${GCOVR_HTML_CMD} - - BYPRODUCTS ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html # report directory - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - VERBATIM # Protect arguments to commands - COMMENT "Running gcovr to produce HTML code coverage report." - ) - - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) - -endfunction() # setup_target_for_coverage_gcovr_html - -# Defines a target for running and collection code coverage information -# Builds dependencies, runs the given executable and outputs reports. -# NOTE! The executable should always have a ZERO as exit code otherwise -# the coverage generation will not complete. -# -# setup_target_for_coverage_fastcov( -# NAME testrunner_coverage # New target name -# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR -# DEPENDENCIES testrunner # Dependencies to build first -# BASE_DIRECTORY "../" # Base directory for report -# # (defaults to PROJECT_SOURCE_DIR) -# EXCLUDE "src/dir1/" "src/dir2/" # Patterns to exclude. -# NO_DEMANGLE # Don't demangle C++ symbols -# # even if c++filt is found -# SKIP_HTML # Don't create html report -# POST_CMD perl -i -pe s!${PROJECT_SOURCE_DIR}/!!g ctest_coverage.json # E.g. for stripping source dir from file paths -# ) -function(setup_target_for_coverage_fastcov) - - set(options NO_DEMANGLE SKIP_HTML) - set(oneValueArgs BASE_DIRECTORY NAME) - set(multiValueArgs EXCLUDE EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES FASTCOV_ARGS GENHTML_ARGS POST_CMD) - cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) - - if(NOT FASTCOV_PATH) - message(FATAL_ERROR "fastcov not found! Aborting...") - endif() - - if(NOT Coverage_SKIP_HTML AND NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() - - # Set base directory (as absolute path), or default to PROJECT_SOURCE_DIR - if(Coverage_BASE_DIRECTORY) - get_filename_component(BASEDIR ${Coverage_BASE_DIRECTORY} ABSOLUTE) - else() - set(BASEDIR ../..) - endif() - - # Collect excludes (Patterns, not paths, for fastcov) - set(FASTCOV_EXCLUDES "") - foreach(EXCLUDE ${Coverage_EXCLUDE} ${COVERAGE_EXCLUDES} ${COVERAGE_FASTCOV_EXCLUDES}) - list(APPEND FASTCOV_EXCLUDES "${EXCLUDE}") - endforeach() - list(REMOVE_DUPLICATES FASTCOV_EXCLUDES) - - # Conditional arguments - if(CPPFILT_PATH AND NOT ${Coverage_NO_DEMANGLE}) - set(GENHTML_EXTRA_ARGS "--demangle-cpp") - endif() - - # Set up commands which will be run to generate coverage data - set(FASTCOV_EXEC_TESTS_CMD ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}) - - set(FASTCOV_CAPTURE_CMD ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH} - --search-directory ${BASEDIR} - --process-gcno - --output ${Coverage_NAME}.json - --exclude ${FASTCOV_EXCLUDES} - --exclude ${FASTCOV_EXCLUDES} - ) - - set(FASTCOV_CONVERT_CMD ${FASTCOV_PATH} - -C ${Coverage_NAME}.json --lcov --output ${Coverage_NAME}.info - ) - - if(Coverage_SKIP_HTML) - set(FASTCOV_HTML_CMD ";") - else() - set(FASTCOV_HTML_CMD ${GENHTML_PATH} ${GENHTML_EXTRA_ARGS} ${Coverage_GENHTML_ARGS} - -o ${Coverage_NAME} ${Coverage_NAME}.info - ) - endif() - - set(FASTCOV_POST_CMD ";") - if(Coverage_POST_CMD) - set(FASTCOV_POST_CMD ${Coverage_POST_CMD}) - endif() - - if(CODE_COVERAGE_VERBOSE) - message(STATUS "Code coverage commands for target ${Coverage_NAME} (fastcov):") - - message(" Running tests:") - string(REPLACE ";" " " FASTCOV_EXEC_TESTS_CMD_SPACED "${FASTCOV_EXEC_TESTS_CMD}") - message(" ${FASTCOV_EXEC_TESTS_CMD_SPACED}") - - message(" Capturing fastcov counters and generating report:") - string(REPLACE ";" " " FASTCOV_CAPTURE_CMD_SPACED "${FASTCOV_CAPTURE_CMD}") - message(" ${FASTCOV_CAPTURE_CMD_SPACED}") - - message(" Converting fastcov .json to lcov .info:") - string(REPLACE ";" " " FASTCOV_CONVERT_CMD_SPACED "${FASTCOV_CONVERT_CMD}") - message(" ${FASTCOV_CONVERT_CMD_SPACED}") - - if(NOT Coverage_SKIP_HTML) - message(" Generating HTML report: ") - string(REPLACE ";" " " FASTCOV_HTML_CMD_SPACED "${FASTCOV_HTML_CMD}") - message(" ${FASTCOV_HTML_CMD_SPACED}") - endif() - if(Coverage_POST_CMD) - message(" Running post command: ") - string(REPLACE ";" " " FASTCOV_POST_CMD_SPACED "${FASTCOV_POST_CMD}") - message(" ${FASTCOV_POST_CMD_SPACED}") - endif() - endif() - - # Setup target - add_custom_target(${Coverage_NAME} - - # Cleanup fastcov - COMMAND ${FASTCOV_PATH} ${Coverage_FASTCOV_ARGS} --gcov ${GCOV_PATH} - --search-directory ${BASEDIR} - --zerocounters - - COMMAND ${FASTCOV_EXEC_TESTS_CMD} - COMMAND ${FASTCOV_CAPTURE_CMD} - COMMAND ${FASTCOV_CONVERT_CMD} - COMMAND ${FASTCOV_HTML_CMD} - COMMAND ${FASTCOV_POST_CMD} - - # Set output files as GENERATED (will be removed on 'make clean') - BYPRODUCTS - ${Coverage_NAME}.info - ${Coverage_NAME}.json - ${Coverage_NAME}/index.html # report directory - - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - DEPENDS ${Coverage_DEPENDENCIES} - VERBATIM # Protect arguments to commands - COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report." - ) - - set(INFO_MSG "fastcov code coverage info report saved in ${Coverage_NAME}.info and ${Coverage_NAME}.json.") - if(NOT Coverage_SKIP_HTML) - string(APPEND INFO_MSG " Open ${PROJECT_BINARY_DIR}/${Coverage_NAME}/index.html in your browser to view the coverage report.") - endif() - # Show where to find the fastcov info report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E echo ${INFO_MSG} - ) - -endfunction() # setup_target_for_coverage_fastcov - -function(append_coverage_compiler_flags) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) - set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE) - message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}") -endfunction() # append_coverage_compiler_flags - -# Setup coverage for specific library -function(append_coverage_compiler_flags_to_target name) - target_compile_options(${name} - PRIVATE ${COVERAGE_COMPILER_FLAGS}) -endfunction() \ No newline at end of file diff --git a/docs/classdiagram.puml.in b/docs/classdiagram.puml.in index 13381b3..077d3c3 100644 --- a/docs/classdiagram.puml.in +++ b/docs/classdiagram.puml.in @@ -1,5 +1,7 @@ @startuml skinparam linetype ortho +skinparam backgroundColor transparent + ' Classes class ArrayDeserializer { diff --git a/docs/classdiagram.rst.in b/docs/classdiagram.rst.in index 2cfc04c..75c86ba 100644 --- a/docs/classdiagram.rst.in +++ b/docs/classdiagram.rst.in @@ -3,4 +3,4 @@ Class Diagram -------------------- -.. uml:: classdiagram.puml +.. plantuml:: classdiagram.puml diff --git a/docs/oasvalidator.rst.in b/docs/oasvalidator.rst.in index 925e163..e16f5f9 100644 --- a/docs/oasvalidator.rst.in +++ b/docs/oasvalidator.rst.in @@ -375,8 +375,8 @@ To run the example, follow the steps below: .. code:: bash cmake -S . -B build -DBUILD_EXAMPLE=ON - cmake --build build --target example -j $(nproc) - build/example/example + cmake --build build --target oasvalidator-example -j $(nproc) + build/example/oasvalidator-example 6.6 Initialization 🎬 ~~~~~~~~~~~~~~~~~~~~~ diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 25b1405..99a42d2 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -1,15 +1,15 @@ cmake_minimum_required(VERSION 3.10 FATAL_ERROR) # Project description -project(oasvalidator-example LANGUAGES CXX) +project(${OASVALIDATOR}-example LANGUAGES CXX) include_directories(${OAS_INCLUDE_DIR}) # Create the executable -add_executable(example example.cpp) +add_executable(${PROJECT_NAME} example.cpp) # Link the executable with the library -target_link_libraries(example oasvalidator) +target_link_libraries(${PROJECT_NAME} oasvalidator) set(SPEC_FILE_ABSOLUTE_PATH "${CMAKE_SOURCE_DIR}/data/openAPI_example.json") add_definitions(-DSPEC_PATH="${SPEC_FILE_ABSOLUTE_PATH}") diff --git a/src/oas_validator_imp.cpp b/src/oas_validator_imp.cpp index 5339947..3102c1d 100644 --- a/src/oas_validator_imp.cpp +++ b/src/oas_validator_imp.cpp @@ -5,8 +5,8 @@ // [ END OF LICENSE 7982e23aed1dc8eda1fdc979fee617354ae998dc ] #include "oas_validator_imp.hpp" -#include #include +#include OASValidatorImp::OASValidatorImp(const std::string& oas_specs) { @@ -23,8 +23,8 @@ OASValidatorImp::OASValidatorImp(const std::string& oas_specs) } if (doc.HasParseError()) { - throw ValidatorInitExc("Unable to parse specs: " + oas_specs + " \nError code: " + std::to_string(doc.GetParseError()) + " at offset: " + - std::to_string(doc.GetErrorOffset()) + " Error message: " + rapidjson::GetParseError_En(doc.GetParseError())); + throw ValidatorInitExc("Unable to parse specs: " + oas_specs + " \nError code: " + std::to_string(doc.GetParseError()) + + " at offset: " + std::to_string(doc.GetErrorOffset()) + " Error message: " + rapidjson::GetParseError_En(doc.GetParseError())); } const rapidjson::Value& paths = doc["paths"]; diff --git a/test/perftest/CMakeLists.txt b/test/perftest/CMakeLists.txt index b6b7e63..23e446f 100644 --- a/test/perftest/CMakeLists.txt +++ b/test/perftest/CMakeLists.txt @@ -1,4 +1,4 @@ -project(${PROJECT_NAME}-perftests LANGUAGES CXX) +project(${OASVALIDATOR}-perftests LANGUAGES CXX) file(GLOB_RECURSE SOURCES "src/*.cpp") include_directories(${CMAKE_SOURCE_DIR}/include) diff --git a/test/perftest/src/perftest.cpp b/test/perftest/src/perftest.cpp index cacde93..f16890b 100644 --- a/test/perftest/src/perftest.cpp +++ b/test/perftest/src/perftest.cpp @@ -26,12 +26,12 @@ class OASValidatorPerf: public ::benchmark::Fixture SetDefaultTimeUnit(::benchmark::kMicrosecond); MinWarmUpTime(K_MIN_WARM_UP_TIME); MinTime(K_MIN_TIME); - } + } void TearDown(benchmark::State&) override { - validator.reset(); - } + validator.reset(); + } std::unique_ptr validator; }; @@ -138,7 +138,7 @@ BENCHMARK_F(OASValidatorPerf, ValidRequest)(benchmark::State& state) } } -BENCHMARK_F(OASValidatorPerf, InvalidRequest1)(benchmark::State& state) // Check 1: Invalid method +BENCHMARK_F(OASValidatorPerf, InvalidRequest1)(benchmark::State& state) // Check 1: Invalid method { std::string err_msg; std::unordered_map headers; @@ -149,7 +149,7 @@ BENCHMARK_F(OASValidatorPerf, InvalidRequest1)(benchmark::State& state) // Chec } } -BENCHMARK_F(OASValidatorPerf, InvalidRequest2)(benchmark::State& state)// Check 2: Invalid Path +BENCHMARK_F(OASValidatorPerf, InvalidRequest2)(benchmark::State& state) // Check 2: Invalid Path { std::string err_msg; std::unordered_map headers; @@ -159,7 +159,7 @@ BENCHMARK_F(OASValidatorPerf, InvalidRequest2)(benchmark::State& state)// Check err_msg); } } -BENCHMARK_F(OASValidatorPerf, InvalidRequest3)(benchmark::State& state) // Check 3: Invalid Path param +BENCHMARK_F(OASValidatorPerf, InvalidRequest3)(benchmark::State& state) // Check 3: Invalid Path param { std::string err_msg; std::unordered_map headers; @@ -170,7 +170,7 @@ BENCHMARK_F(OASValidatorPerf, InvalidRequest3)(benchmark::State& state) // Chec } } -BENCHMARK_F(OASValidatorPerf, InvalidRequest4)(benchmark::State& state)// Check 4: Invalid Query param +BENCHMARK_F(OASValidatorPerf, InvalidRequest4)(benchmark::State& state) // Check 4: Invalid Query param { std::string err_msg; std::unordered_map headers; @@ -181,7 +181,7 @@ BENCHMARK_F(OASValidatorPerf, InvalidRequest4)(benchmark::State& state)// Check } } -BENCHMARK_F(OASValidatorPerf, InvalidRequest5)(benchmark::State& state)// Check 5: Invalid Header param +BENCHMARK_F(OASValidatorPerf, InvalidRequest5)(benchmark::State& state) // Check 5: Invalid Header param { std::string err_msg; std::unordered_map headers; diff --git a/test/unittest/CMakeLists.txt b/test/unittest/CMakeLists.txt index cb055ac..ab23e98 100644 --- a/test/unittest/CMakeLists.txt +++ b/test/unittest/CMakeLists.txt @@ -1,16 +1,16 @@ -project(${PROJECT_NAME}-unittests LANGUAGES CXX) +project(${OASVALIDATOR}-unittests LANGUAGES CXX) set(GOOGLETEST_VERSION 1.14.0) find_package(GTestSrc) -IF(GTESTSRC_FOUND) +IF (GTESTSRC_FOUND) enable_testing() if (WIN32 AND (NOT CYGWIN) AND (NOT MINGW)) set(gtest_disable_pthreads ON) set(gtest_force_shared_crt ON) - endif() + endif () add_subdirectory(${GTEST_SOURCE_DIR} ${CMAKE_BINARY_DIR}/googletest) include_directories(SYSTEM ${GTEST_INCLUDE_DIR}) @@ -21,13 +21,13 @@ IF(GTESTSRC_FOUND) file(GLOB_RECURSE SOURCES "src/*.cpp") find_program(CCACHE_FOUND ccache) - if(CCACHE_FOUND) + if (CCACHE_FOUND) set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments -fcolor-diagnostics") - endif() - endif(CCACHE_FOUND) + endif () + endif (CCACHE_FOUND) add_executable(${PROJECT_NAME} ${SOURCES}) @@ -47,11 +47,9 @@ IF(GTESTSRC_FOUND) $<$:-lgcov> ) - add_test(NAME unittest - COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/oasvalidator-unittest - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/bin) + add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME}) set(SPEC_FILE_ABSOLUTE_PATH "${CMAKE_SOURCE_DIR}/data/openAPI_example.json") add_definitions(-DSPEC_PATH="${SPEC_FILE_ABSOLUTE_PATH}") -ENDIF(GTESTSRC_FOUND) +ENDIF (GTESTSRC_FOUND) diff --git a/test/unittest/src/deserializers/object_deserializer.cpp b/test/unittest/src/deserializers/object_deserializer.cpp index 8560163..cb25a96 100644 --- a/test/unittest/src/deserializers/object_deserializer.cpp +++ b/test/unittest/src/deserializers/object_deserializer.cpp @@ -61,19 +61,19 @@ TEST_P(ObjectDeserializerTest, Deserialize) } INSTANTIATE_TEST_SUITE_P(ObjectDeserializerTests, ObjectDeserializerTest, - ::testing::Values(std::make_tuple("boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '\0', false, ',', ',', false, false), - std::make_tuple("boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '\0', false, '=', ',', false, false), - std::make_tuple(".boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '.', false, ',', ',', false, false), - std::make_tuple(".boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '.', false, '=', ',', false, false), - std::make_tuple(";test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", ';', true, ',', ',', false, false), - std::make_tuple(";boolTrue=true;boolFalse=false;int=123;number=123.456;string=abc%20xyz", ';', false, '=', ';', false, false), - std::make_tuple("?boolTrue=true&boolFalse=false&int=123&number=123.456&string=abc%20xyz", '?', false, '=', '&', false, false), - std::make_tuple("?test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '?', true, ',', ',', false, false), - std::make_tuple("?test[boolTrue]=true&test[boolFalse]=false&test[int]=123&test[number]=123.456&test[string]=abc%20xyz", '?', true, '=', - '&', true, false), - std::make_tuple("boolTrue,true,boolFalse,false,int,str,number,123.456,string,abc%20xyz", '\0', false, ',', ',', false, true), - std::make_tuple("boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%2xyz", '\0', false, '=', ',', false, true), - std::make_tuple(".boolTrue,true,boolFalse,false,int,123,number,1.23.456,string,abc%20xyz", '.', false, ',', ',', false, true), - std::make_tuple(".boolTrue;true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '.', false, '=', ',', false, true), - std::make_tuple("test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", ';', true, ',', ',', false, true), - std::make_tuple(";boolTrue,true;boolFalse=false;int=123;number=123.456;string=abc%20xyz", ';', false, '=', ';', false, true))); \ No newline at end of file + ::testing::Values(std::make_tuple("boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '\0', false, ',', ',', false, false), + std::make_tuple("boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '\0', false, '=', ',', false, false), + std::make_tuple(".boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '.', false, ',', ',', false, false), + std::make_tuple(".boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '.', false, '=', ',', false, false), + std::make_tuple(";test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", ';', true, ',', ',', false, false), + std::make_tuple(";boolTrue=true;boolFalse=false;int=123;number=123.456;string=abc%20xyz", ';', false, '=', ';', false, false), + std::make_tuple("?boolTrue=true&boolFalse=false&int=123&number=123.456&string=abc%20xyz", '?', false, '=', '&', false, false), + std::make_tuple("?test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", '?', true, ',', ',', false, false), + std::make_tuple("?test[boolTrue]=true&test[boolFalse]=false&test[int]=123&test[number]=123.456&test[string]=abc%20xyz", '?', true, '=', + '&', true, false), + std::make_tuple("boolTrue,true,boolFalse,false,int,str,number,123.456,string,abc%20xyz", '\0', false, ',', ',', false, true), + std::make_tuple("boolTrue=true,boolFalse=false,int=123,number=123.456,string=abc%2xyz", '\0', false, '=', ',', false, true), + std::make_tuple(".boolTrue,true,boolFalse,false,int,123,number,1.23.456,string,abc%20xyz", '.', false, ',', ',', false, true), + std::make_tuple(".boolTrue;true,boolFalse=false,int=123,number=123.456,string=abc%20xyz", '.', false, '=', ',', false, true), + std::make_tuple("test=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", ';', true, ',', ',', false, true), + std::make_tuple(";boolTrue,true;boolFalse=false;int=123;number=123.456;string=abc%20xyz", ';', false, '=', ';', false, true))); \ No newline at end of file diff --git a/test/unittest/src/validators/header_param_validator.cpp b/test/unittest/src/validators/header_param_validator.cpp index 733b42b..60e4e5a 100644 --- a/test/unittest/src/validators/header_param_validator.cpp +++ b/test/unittest/src/validators/header_param_validator.cpp @@ -55,7 +55,7 @@ TEST_P(HeaderParamValidatorTest, ValidateParam) } INSTANTIATE_TEST_SUITE_P(HeaderParamValidatorTest, HeaderParamValidatorTest, - ::testing::Values(std::make_tuple("123", false, "integer", ValidationError::NONE), std::make_tuple("123", true, "integer", ValidationError::NONE), - std::make_tuple("true", false, "boolean", ValidationError::NONE), std::make_tuple("true", true, "boolean", ValidationError::NONE), - std::make_tuple("123.456", false, "number", ValidationError::NONE), std::make_tuple("123.456", true, "number", ValidationError::NONE), - std::make_tuple("abc", false, "string", ValidationError::NONE), std::make_tuple("abc", true, "string", ValidationError::NONE))); + ::testing::Values(std::make_tuple("123", false, "integer", ValidationError::NONE), std::make_tuple("123", true, "integer", ValidationError::NONE), + std::make_tuple("true", false, "boolean", ValidationError::NONE), std::make_tuple("true", true, "boolean", ValidationError::NONE), + std::make_tuple("123.456", false, "number", ValidationError::NONE), std::make_tuple("123.456", true, "number", ValidationError::NONE), + std::make_tuple("abc", false, "string", ValidationError::NONE), std::make_tuple("abc", true, "string", ValidationError::NONE))); diff --git a/test/unittest/src/validators/query_param_validator.cpp b/test/unittest/src/validators/query_param_validator.cpp index 006878f..ff01ad3 100644 --- a/test/unittest/src/validators/query_param_validator.cpp +++ b/test/unittest/src/validators/query_param_validator.cpp @@ -69,25 +69,25 @@ TEST_P(QueryPrimitiveParam, ValidateParam) } INSTANTIATE_TEST_SUITE_P(QueryPrimitiveParamTests, QueryPrimitiveParam, - ::testing::Values(std::make_tuple("param=123", "form", false, "integer", ValidationError::NONE), - std::make_tuple("param=123", "form", true, "integer", ValidationError::NONE), - std::make_tuple("param=123.123", "form", false, "number", ValidationError::NONE), - std::make_tuple("param=123.123", "form", true, "number", ValidationError::NONE), - std::make_tuple("param=abc%20xyz", "form", false, "string", ValidationError::NONE), - std::make_tuple("param=abc", "form", true, "string", ValidationError::NONE), - std::make_tuple("param=true", "form", false, "boolean", ValidationError::NONE), - std::make_tuple("param=true", "form", true, "boolean", ValidationError::NONE), - std::make_tuple("param=string", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=string", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=123.123", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=123.123", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=true", "form", false, "number", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=true", "form", true, "number", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=123", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=123", "form", true, "boolean", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=123.123", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=abc%2yz", "form", true, "string", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=abc%2yz", "form", false, "string", ValidationError::INVALID_QUERY_PARAM))); + ::testing::Values(std::make_tuple("param=123", "form", false, "integer", ValidationError::NONE), + std::make_tuple("param=123", "form", true, "integer", ValidationError::NONE), + std::make_tuple("param=123.123", "form", false, "number", ValidationError::NONE), + std::make_tuple("param=123.123", "form", true, "number", ValidationError::NONE), + std::make_tuple("param=abc%20xyz", "form", false, "string", ValidationError::NONE), + std::make_tuple("param=abc", "form", true, "string", ValidationError::NONE), + std::make_tuple("param=true", "form", false, "boolean", ValidationError::NONE), + std::make_tuple("param=true", "form", true, "boolean", ValidationError::NONE), + std::make_tuple("param=string", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=string", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=123.123", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=123.123", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=true", "form", false, "number", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=true", "form", true, "number", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=123", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=123", "form", true, "boolean", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=123.123", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=abc%2yz", "form", true, "string", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=abc%2yz", "form", false, "string", ValidationError::INVALID_QUERY_PARAM))); class QueryArrayParam: public ::testing::TestWithParam> { @@ -145,40 +145,40 @@ TEST_P(QueryArrayParam, ValidateParam) } INSTANTIATE_TEST_SUITE_P(QueryArrayParamTests, QueryArrayParam, - ::testing::Values(std::make_tuple("param=3,4,5", "form", false, "integer", ValidationError::NONE), - std::make_tuple("param=3¶m=4¶m=5", "form", true, "integer", ValidationError::NONE), - std::make_tuple("param=3.3,4.4,5.5", "form", false, "number", ValidationError::NONE), - std::make_tuple("param=3.3¶m=4.4¶m=5.5", "form", true, "number", ValidationError::NONE), - std::make_tuple("param=abc%20xyz,def%20xyz,ghi%20xyz", "form", false, "string", ValidationError::NONE), - std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "form", true, "string", ValidationError::NONE), - std::make_tuple("param=true,false,true", "form", false, "boolean", ValidationError::NONE), - std::make_tuple("param=true¶m=false¶m=true", "form", true, "boolean", ValidationError::NONE), - std::make_tuple("param=string,abc,xyz", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=string¶m=abc¶m=xyz", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=3.3,4.4,5.5", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=3.3¶m=4.4¶m=5.5", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=true,false,true", "form", false, "number", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=true¶m=false¶m=true", "form", true, "number", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=3,4,5", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=3%204%205", "spaceDelimited", false, "integer", ValidationError::NONE), - std::make_tuple("param=3¶m=4¶m=5", "spaceDelimited", true, "integer", ValidationError::NONE), - std::make_tuple("param=3.3%204.4%205.5", "spaceDelimited", false, "number", ValidationError::NONE), - std::make_tuple("param=3.3¶m=4.4¶m=5.5", "spaceDelimited", true, "number", ValidationError::NONE), - std::make_tuple("param=abc%20xyz%20def%20xyz%20ghi%20xyz", "spaceDelimited", false, "string", ValidationError::NONE), - std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "spaceDelimited", true, "string", ValidationError::NONE), - std::make_tuple("param=true%20false%20true", "spaceDelimited", false, "boolean", ValidationError::NONE), - std::make_tuple("param=true¶m=false¶m=true", "spaceDelimited", true, "boolean", ValidationError::NONE), - std::make_tuple("param=string%20abc%20xyz", "spaceDelimited", false, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=string¶m=abc¶m=xyz", "spaceDelimited", true, "integer", ValidationError::INVALID_QUERY_PARAM), - std::make_tuple("param=3|4|5", "pipeDelimited", false, "integer", ValidationError::NONE), - std::make_tuple("param=3¶m=4¶m=5", "pipeDelimited", true, "integer", ValidationError::NONE), - std::make_tuple("param=3.3|4.4|5.5", "pipeDelimited", false, "number", ValidationError::NONE), - std::make_tuple("param=3.3¶m=4.4¶m=5.5", "pipeDelimited", true, "number", ValidationError::NONE), - std::make_tuple("param=abc%20xyz|def%20xyz|ghi%20xyz", "pipeDelimited", false, "string", ValidationError::NONE), - std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "pipeDelimited", true, "string", ValidationError::NONE), - std::make_tuple("param=true|false|true", "pipeDelimited", false, "boolean", ValidationError::NONE), - std::make_tuple("param=true¶m=false¶m=true", "pipeDelimited", true, "boolean", ValidationError::NONE), - std::make_tuple("param=string|abc|xyz", "pipeDelimited", false, "integer", ValidationError::INVALID_QUERY_PARAM))); + ::testing::Values(std::make_tuple("param=3,4,5", "form", false, "integer", ValidationError::NONE), + std::make_tuple("param=3¶m=4¶m=5", "form", true, "integer", ValidationError::NONE), + std::make_tuple("param=3.3,4.4,5.5", "form", false, "number", ValidationError::NONE), + std::make_tuple("param=3.3¶m=4.4¶m=5.5", "form", true, "number", ValidationError::NONE), + std::make_tuple("param=abc%20xyz,def%20xyz,ghi%20xyz", "form", false, "string", ValidationError::NONE), + std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "form", true, "string", ValidationError::NONE), + std::make_tuple("param=true,false,true", "form", false, "boolean", ValidationError::NONE), + std::make_tuple("param=true¶m=false¶m=true", "form", true, "boolean", ValidationError::NONE), + std::make_tuple("param=string,abc,xyz", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=string¶m=abc¶m=xyz", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=3.3,4.4,5.5", "form", false, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=3.3¶m=4.4¶m=5.5", "form", true, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=true,false,true", "form", false, "number", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=true¶m=false¶m=true", "form", true, "number", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=3,4,5", "form", false, "boolean", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=3%204%205", "spaceDelimited", false, "integer", ValidationError::NONE), + std::make_tuple("param=3¶m=4¶m=5", "spaceDelimited", true, "integer", ValidationError::NONE), + std::make_tuple("param=3.3%204.4%205.5", "spaceDelimited", false, "number", ValidationError::NONE), + std::make_tuple("param=3.3¶m=4.4¶m=5.5", "spaceDelimited", true, "number", ValidationError::NONE), + std::make_tuple("param=abc%20xyz%20def%20xyz%20ghi%20xyz", "spaceDelimited", false, "string", ValidationError::NONE), + std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "spaceDelimited", true, "string", ValidationError::NONE), + std::make_tuple("param=true%20false%20true", "spaceDelimited", false, "boolean", ValidationError::NONE), + std::make_tuple("param=true¶m=false¶m=true", "spaceDelimited", true, "boolean", ValidationError::NONE), + std::make_tuple("param=string%20abc%20xyz", "spaceDelimited", false, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=string¶m=abc¶m=xyz", "spaceDelimited", true, "integer", ValidationError::INVALID_QUERY_PARAM), + std::make_tuple("param=3|4|5", "pipeDelimited", false, "integer", ValidationError::NONE), + std::make_tuple("param=3¶m=4¶m=5", "pipeDelimited", true, "integer", ValidationError::NONE), + std::make_tuple("param=3.3|4.4|5.5", "pipeDelimited", false, "number", ValidationError::NONE), + std::make_tuple("param=3.3¶m=4.4¶m=5.5", "pipeDelimited", true, "number", ValidationError::NONE), + std::make_tuple("param=abc%20xyz|def%20xyz|ghi%20xyz", "pipeDelimited", false, "string", ValidationError::NONE), + std::make_tuple("param=abc%20xyz¶m=def%20xyz¶m=ghi%20xyz", "pipeDelimited", true, "string", ValidationError::NONE), + std::make_tuple("param=true|false|true", "pipeDelimited", false, "boolean", ValidationError::NONE), + std::make_tuple("param=true¶m=false¶m=true", "pipeDelimited", true, "boolean", ValidationError::NONE), + std::make_tuple("param=string|abc|xyz", "pipeDelimited", false, "integer", ValidationError::INVALID_QUERY_PARAM))); class QueryObjectParam: public ::testing::TestWithParam> { @@ -248,7 +248,7 @@ TEST_P(QueryObjectParam, ValidateParam) } INSTANTIATE_TEST_SUITE_P(QueryObjectParamTests, QueryObjectParam, - ::testing::Values(std::make_tuple("param=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", "form", false, ValidationError::NONE), - std::make_tuple("boolTrue=true&boolFalse=false&int=123&number=123.456&string=abc%20xyz", "form", true, ValidationError::NONE), - std::make_tuple("param[boolTrue]=true¶m[boolFalse]=false¶m[int]=123¶m[number]=123.456¶m[string]=abc%20xyz", "deepObject", - true, ValidationError::NONE))); \ No newline at end of file + ::testing::Values(std::make_tuple("param=boolTrue,true,boolFalse,false,int,123,number,123.456,string,abc%20xyz", "form", false, ValidationError::NONE), + std::make_tuple("boolTrue=true&boolFalse=false&int=123&number=123.456&string=abc%20xyz", "form", true, ValidationError::NONE), + std::make_tuple("param[boolTrue]=true¶m[boolFalse]=false¶m[int]=123¶m[number]=123.456¶m[string]=abc%20xyz", "deepObject", + true, ValidationError::NONE))); \ No newline at end of file