diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 58921f51..048858ca 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -3,11 +3,12 @@ name: Linux on: [push, pull_request] jobs: - gcc14: + Linux: strategy: fail-fast: false matrix: - config: [Debug, Release] + compiler: [gcc-14, clang-18] + config: [debug, release] runs-on: ubuntu-24.04 @@ -18,17 +19,15 @@ jobs: - name: Install Dependencies run: | - sudo apt-get update - sudo apt-get upgrade sudo add-apt-repository -y universe sudo apt-get update - sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build gcc-14 g++-14 + sudo apt-get install -yq libgtest-dev libboost-program-options-dev rapidjson-dev ninja-build - name: Build GTest run: | cmake -E make_directory gtest cd gtest - cmake -DCMAKE_BUILD_TYPE=${{ matrix.config }} -G Ninja /usr/src/gtest + cmake -DCMAKE_BUILD_TYPE=${{ matrix.config == 'debug' && 'Debug' || 'Release' }} -G Ninja /usr/src/gtest cmake --build . -j -v sudo cmake --install . @@ -36,20 +35,10 @@ jobs: run: cmake -E make_directory build - name: Configure CMake - shell: pwsh - env: - CC: gcc-14 - CXX: g++-14 - working-directory: build/ - run: | - $cmakeBuildType = '${{ matrix.config }}' - - cmake "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} + run: cmake --preset ${{ matrix.compiler }}-${{ matrix.config }} -DCMAKE_TOOLCHAIN_FILE= - name: Build - working-directory: build/ - run: cmake --build . -j -v + run: cmake --build --preset ${{ matrix.compiler }}-${{ matrix.config }} -j -v - name: Test - working-directory: build/ - run: ctest --output-on-failure + run: ctest --preset ${{ matrix.compiler }}-${{ matrix.config }} --output-on-failure diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 70cea90b..c7d3ef49 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -3,7 +3,7 @@ name: macOS on: [push, pull_request] jobs: - xcode: + apple-clang: strategy: fail-fast: false matrix: @@ -53,7 +53,7 @@ jobs: $env:VCPKG_BINARY_SOURCES = "clear;files,$cachedBinaries,$cacheAccess" $env:PATH = "${env:PATH}:${{ github.workspace }}/ninja-build" - cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" -G Ninja ${{ github.workspace }} + cmake "-DCMAKE_TOOLCHAIN_FILE=$vcpkgToolchain" "-DCMAKE_BUILD_TYPE=$cmakeBuildType" "-DGRAPHQL_BUILD_MODULES=OFF" -G Ninja ${{ github.workspace }} - name: Build working-directory: build/ diff --git a/.gitignore b/.gitignore index 0f77c1a4..08458f10 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ CMakeSettings.json CMakeCache.txt CTestCostData.txt CTestTestfile.cmake +CMakeUserPresets.json DartConfiguration.tcl install_manifest.txt LastTest.log @@ -40,3 +41,4 @@ settings.json build/ install/ isenseconfig/ +vc140.pdb diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c6440dd..753aca8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,6 +33,7 @@ if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/.git") endif() endif() +option(GRAPHQL_BUILD_MODULES "Build the C++20 module interface libraries." ON) option(GRAPHQL_BUILD_SCHEMAGEN "Build the schemagen tool." ON) option(GRAPHQL_BUILD_CLIENTGEN "Build the clientgen tool." ON) option(GRAPHQL_BUILD_TESTS "Build the tests and sample schema library." ON) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..942ec260 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,120 @@ +{ + "version": 8, + "configurePresets": [ + { + "hidden": true, + "name": "ninja-generator", + "binaryDir": "build/${presetName}", + "toolchainFile": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake", + "generator": "Ninja" + }, + { + "name": "debug", + "inherits": [ "ninja-generator" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug" + } + }, + { + "name": "release", + "inherits": [ "ninja-generator" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "gcc-14-debug", + "inherits": [ "debug" ], + "condition": { + "type": "notEquals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "/usr/bin/gcc-14", + "CMAKE_CXX_COMPILER": "/usr/bin/g++-14", + "GRAPHQL_BUILD_MODULES": false + } + }, + { + "name": "gcc-14-release", + "inherits": [ "gcc-14-debug" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "RelWithDebInfo" + } + }, + { + "name": "clang-18-debug", + "inherits": [ "debug" ], + "condition": { + "type": "notEquals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "cacheVariables": { + "CMAKE_C_COMPILER": "/usr/bin/clang-18", + "CMAKE_CXX_COMPILER": "/usr/bin/clang++-18", + "CMAKE_CXX_COMPILER_CLANG_SCAN_DEPS": "/usr/bin/clang-scan-deps-18" + } + }, + { + "name": "clang-18-release", + "inherits": [ "clang-18-debug" ], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + } + ], + "buildPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + }, + { + "name": "gcc-14-debug", + "configurePreset": "gcc-14-debug" + }, + { + "name": "gcc-14-release", + "configurePreset": "gcc-14-release" + }, + { + "name": "clang-18-debug", + "configurePreset": "clang-18-debug" + }, + { + "name": "clang-18-release", + "configurePreset": "clang-18-release" + } + ], + "testPresets": [ + { + "name": "debug", + "configurePreset": "debug" + }, + { + "name": "release", + "configurePreset": "release" + }, + { + "name": "gcc-14-debug", + "configurePreset": "gcc-14-debug" + }, + { + "name": "gcc-14-release", + "configurePreset": "gcc-14-release" + }, + { + "name": "clang-18-debug", + "configurePreset": "clang-18-debug" + }, + { + "name": "clang-18-release", + "configurePreset": "clang-18-release" + } + ] +} \ No newline at end of file diff --git a/cmake/Version.h.in b/cmake/Version.h.in index ce86ef57..711f874c 100644 --- a/cmake/Version.h.in +++ b/cmake/Version.h.in @@ -6,15 +6,20 @@ #ifndef GRAPHQLVERSION_H #define GRAPHQLVERSION_H +#include #include namespace graphql::internal { +inline namespace version { + constexpr std::string_view FullVersion { "@PROJECT_VERSION@" }; -constexpr size_t MajorVersion = @PROJECT_VERSION_MAJOR@; -constexpr size_t MinorVersion = @PROJECT_VERSION_MINOR@; -constexpr size_t PatchVersion = @PROJECT_VERSION_PATCH@; +constexpr std::size_t MajorVersion = @PROJECT_VERSION_MAJOR@; +constexpr std::size_t MinorVersion = @PROJECT_VERSION_MINOR@; +constexpr std::size_t PatchVersion = @PROJECT_VERSION_PATCH@; + +} // namespace version } // namespace graphql::internal diff --git a/cmake/cppgraphqlgen-functions.cmake b/cmake/cppgraphqlgen-functions.cmake index 1ad5c95d..5114c6b7 100644 --- a/cmake/cppgraphqlgen-functions.cmake +++ b/cmake/cppgraphqlgen-functions.cmake @@ -46,8 +46,19 @@ function(add_graphql_schema_target SCHEMA_TARGET) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_TARGET}_schema_files SCHEMA_FILES) add_library(${SCHEMA_TARGET}_schema STATIC ${SCHEMA_FILES}) add_dependencies(${SCHEMA_TARGET}_schema ${SCHEMA_TARGET}_update_schema) + target_compile_features(${SCHEMA_TARGET}_schema PUBLIC cxx_std_20) target_include_directories(${SCHEMA_TARGET}_schema PUBLIC $) target_link_libraries(${SCHEMA_TARGET}_schema PUBLIC cppgraphqlgen::graphqlservice) + file(GLOB SCHEMA_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${SCHEMA_HEADERS}) + if(GRAPHQL_BUILD_MODULES) + file(GLOB SCHEMA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) + target_sources(${SCHEMA_TARGET}_schema PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${SCHEMA_MODULES}) + endif() endif() endfunction() @@ -88,7 +99,18 @@ function(add_graphql_client_target CLIENT_TARGET) file(STRINGS ${CMAKE_CURRENT_SOURCE_DIR}/${CLIENT_TARGET}_client_files CLIENT_FILES) add_library(${CLIENT_TARGET}_client STATIC ${CLIENT_FILES}) add_dependencies(${CLIENT_TARGET}_client ${CLIENT_TARGET}_update_client) + target_compile_features(${CLIENT_TARGET}_client PUBLIC cxx_std_20) target_include_directories(${CLIENT_TARGET}_client PUBLIC $) target_link_libraries(${CLIENT_TARGET}_client PUBLIC cppgraphqlgen::graphqlclient) + file(GLOB CLIENT_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CLIENT_HEADERS}) + if(GRAPHQL_BUILD_MODULES) + file(GLOB CLIENT_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) + target_sources(${CLIENT_TARGET}_client PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CLIENT_MODULES}) + endif() endif() endfunction() diff --git a/cmake/cppgraphqlgen-update-client-files.cmake b/cmake/cppgraphqlgen-update-client-files.cmake index 1ab6fcb1..c9d5934d 100644 --- a/cmake/cppgraphqlgen-update-client-files.cmake +++ b/cmake/cppgraphqlgen-update-client-files.cmake @@ -11,7 +11,7 @@ get_filename_component(REQUEST_GRAPHQL "${CLIENT_SOURCE_DIR}/${REQUEST_GRAPHQL}" file(MAKE_DIRECTORY ${CLIENT_BINARY_DIR}) # Cleanup all of the stale files in the binary directory -file(GLOB PREVIOUS_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.cpp +file(GLOB PREVIOUS_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.ixx ${CLIENT_BINARY_DIR}/*.cpp ${CLIENT_BINARY_DIR}/${CLIENT_TARGET}_client_files) foreach(PREVIOUS_FILE ${PREVIOUS_FILES}) file(REMOVE ${PREVIOUS_FILE}) @@ -30,7 +30,7 @@ execute_process( # Get the up-to-date list of files in the binary directory set(FILE_NAMES "") -file(GLOB NEW_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.cpp) +file(GLOB NEW_FILES ${CLIENT_BINARY_DIR}/*.h ${CLIENT_BINARY_DIR}/*.ixx ${CLIENT_BINARY_DIR}/*.cpp) foreach(NEW_FILE ${NEW_FILES}) get_filename_component(NEW_FILE ${NEW_FILE} NAME) list(APPEND FILE_NAMES "${NEW_FILE}") @@ -45,11 +45,11 @@ endif() cmake_policy(SET CMP0057 NEW) # Remove stale files in the source directory -file(GLOB OLD_FILES ${CLIENT_SOURCE_DIR}/*.h ${CLIENT_SOURCE_DIR}/*.cpp) +file(GLOB OLD_FILES ${CLIENT_SOURCE_DIR}/*.h ${CLIENT_SOURCE_DIR}/*.ixx ${CLIENT_SOURCE_DIR}/*.cpp) foreach(OLD_FILE ${OLD_FILES}) get_filename_component(OLD_FILE ${OLD_FILE} NAME) if(NOT OLD_FILE IN_LIST FILE_NAMES) - if(OLD_FILE MATCHES "Client\\.h$" OR OLD_FILE MATCHES "Client\\.cpp$") + if(OLD_FILE MATCHES "Client\\.h$" OR OLD_FILE MATCHES "Client\\.ixx$" OR OLD_FILE MATCHES "Client\\.cpp$") file(REMOVE "${CLIENT_SOURCE_DIR}/${OLD_FILE}") else() message(WARNING "Unexpected file in ${CLIENT_TARGET} client sources: ${OLD_FILE}") diff --git a/cmake/cppgraphqlgen-update-schema-files.cmake b/cmake/cppgraphqlgen-update-schema-files.cmake index 00d6fe06..8955f6fd 100644 --- a/cmake/cppgraphqlgen-update-schema-files.cmake +++ b/cmake/cppgraphqlgen-update-schema-files.cmake @@ -10,7 +10,7 @@ get_filename_component(SCHEMA_GRAPHQL "${SCHEMA_SOURCE_DIR}/${SCHEMA_GRAPHQL}" A file(MAKE_DIRECTORY ${SCHEMA_BINARY_DIR}) # Cleanup all of the stale files in the binary directory -file(GLOB PREVIOUS_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.cpp +file(GLOB PREVIOUS_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.ixx ${SCHEMA_BINARY_DIR}/*.cpp ${SCHEMA_BINARY_DIR}/${SCHEMA_TARGET}_schema_files) foreach(PREVIOUS_FILE ${PREVIOUS_FILES}) file(REMOVE ${PREVIOUS_FILE}) @@ -29,7 +29,7 @@ execute_process( # Get the up-to-date list of files in the binary directory set(FILE_NAMES "") -file(GLOB NEW_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.cpp) +file(GLOB NEW_FILES ${SCHEMA_BINARY_DIR}/*.h ${SCHEMA_BINARY_DIR}/*.ixx ${SCHEMA_BINARY_DIR}/*.cpp) foreach(NEW_FILE ${NEW_FILES}) get_filename_component(NEW_FILE ${NEW_FILE} NAME) list(APPEND FILE_NAMES "${NEW_FILE}") @@ -44,13 +44,14 @@ endif() cmake_policy(SET CMP0057 NEW) # Remove stale files in the source directory -file(GLOB OLD_FILES ${SCHEMA_SOURCE_DIR}/*.h ${SCHEMA_SOURCE_DIR}/*.cpp) +file(GLOB OLD_FILES ${SCHEMA_SOURCE_DIR}/*.h ${SCHEMA_SOURCE_DIR}/*.ixx ${SCHEMA_SOURCE_DIR}/*.cpp) foreach(OLD_FILE ${OLD_FILES}) get_filename_component(OLD_FILE ${OLD_FILE} NAME) if(NOT OLD_FILE IN_LIST FILE_NAMES) - if(OLD_FILE MATCHES "Object\\.h$" OR OLD_FILE MATCHES "Object\\.cpp$") + if(OLD_FILE MATCHES "Object\\.h$" OR OLD_FILE MATCHES "Object\\.ixx$" OR OLD_FILE MATCHES "Object\\.cpp$") file(REMOVE "${SCHEMA_SOURCE_DIR}/${OLD_FILE}") elseif(NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.h" AND + NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.ixx" AND NOT OLD_FILE STREQUAL "${SCHEMA_PREFIX}Schema.cpp") message(WARNING "Unexpected file in ${SCHEMA_TARGET} GraphQL schema sources: ${OLD_FILE}") endif() diff --git a/cmake/test_boost_beast.cpp b/cmake/test_boost_beast.cpp deleted file mode 100644 index b59b338a..00000000 --- a/cmake/test_boost_beast.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// This is a dummy program that just needs to compile to tell us if Boost.Asio -// supports co_await and Boost.Beast is installed. - -#include - -#include - -int main() -{ -#ifdef BOOST_ASIO_HAS_CO_AWAIT - return 0; -#else - #error BOOST_ASIO_HAS_CO_AWAIT is undefined -#endif -} \ No newline at end of file diff --git a/cmake/test_coroutine.cpp.in b/cmake/test_coroutine.cpp.in deleted file mode 100644 index 9ea6c5ac..00000000 --- a/cmake/test_coroutine.cpp.in +++ /dev/null @@ -1,59 +0,0 @@ -// This is a dummy program that just needs to compile and link to tell us if -// the C++20 coroutine API is available. Use CMake's configure_file command -// to replace the COROUTINE_HEADER and COROUTINE_NAMESPACE tokens for each -// combination of headers and namespaces which we want to pass to the CMake -// try_compile command. - -#include <@COROUTINE_HEADER@> -#include - -struct task -{ - struct promise_type - { - task get_return_object() noexcept - { - return {}; - } - - @COROUTINE_NAMESPACE@::suspend_never initial_suspend() noexcept - { - return {}; - } - - @COROUTINE_NAMESPACE@::suspend_never final_suspend() noexcept - { - return {}; - } - - void return_void() noexcept - { - promise.set_value(); - } - - void unhandled_exception() - { - promise.set_exception(std::current_exception()); - } - - std::promise promise; - }; - - constexpr bool await_ready() const noexcept - { - return true; - } - - std::future future; -}; - -task test_co_return() -{ - co_return; -} - -int main() -{ - test_co_return().future.get(); - return 0; -} \ No newline at end of file diff --git a/cmake/test_filesystem.cpp b/cmake/test_filesystem.cpp deleted file mode 100644 index 240e7d6b..00000000 --- a/cmake/test_filesystem.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// This is a dummy program that just needs to compile and link to tell us if -// the C++17 std::filesystem API requires any additional libraries. - -#include - -int main() -{ - try - { - throw std::filesystem::filesystem_error("instantiate one to make sure it links", - std::make_error_code(std::errc::function_not_supported)); - } - catch (const std::filesystem::filesystem_error& error) - { - return -1; - } - - return !std::filesystem::temp_directory_path().is_absolute(); -} \ No newline at end of file diff --git a/doc/awaitable.md b/doc/awaitable.md index e22a0454..4d13a6bc 100644 --- a/doc/awaitable.md +++ b/doc/awaitable.md @@ -16,7 +16,7 @@ private: virtual ~Concept() = default; [[nodiscard("unexpected call")]] virtual bool await_ready() const = 0; - virtual void await_suspend(coro::coroutine_handle<> h) const = 0; + virtual void await_suspend(std::coroutine_handle<> h) const = 0; virtual void await_resume() const = 0; }; ... @@ -32,7 +32,7 @@ public: // Default to immediate synchronous execution. await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -41,8 +41,8 @@ public: : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( std::make_shared())) - : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + : std::static_pointer_cast(std::make_shared>( + std::make_shared())) } { } ... @@ -51,12 +51,12 @@ public: For convenience, it will use `graphql::service::await_worker_thread` if you specify `std::launch::async`, which should have the same behavior as calling `std::async(std::launch::async, ...)` did before. -If you specify any other flags for `std::launch`, it does not honor them. It will use `coro::suspend_never` +If you specify any other flags for `std::launch`, it does not honor them. It will use `std::suspend_never` (an alias for `std::suspend_never` or `std::experimental::suspend_never`), which as the name suggests, continues executing the coroutine without suspending. In other words, `std::launch::deferred` will no longer defer execution as in previous versions, it will execute immediately. -There is also a default constructor which also uses `coro::suspend_never`, so that is the default +There is also a default constructor which also uses `std::suspend_never`, so that is the default behavior anywhere that `await_async` is default-initialized with `{}`. Other than simplification, the big advantage this brings is in the type-erased template constructor. @@ -68,7 +68,7 @@ coroutine when and where it likes. ## Awaitable Results Many APIs which used to return some sort of `std::future` now return an alias for -`graphql::internal::Awaitable<...>`. This template is defined in [Awaitable.h](../include/graphqlservice/internal/Awaitable.h): +`graphql::internal::Awaitable<...>`. This template is defined in [Awaitable.ixx](../include/graphqlservice/internal/Awaitable.ixx): ```cpp template class [[nodiscard("unnecessary construction")]] Awaitable @@ -110,7 +110,7 @@ public: return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } @@ -189,7 +189,7 @@ public: bool await_ready() const noexcept { ... } - void await_suspend(coro::coroutine_handle<> h) const { ... } + void await_suspend(std::coroutine_handle<> h) const { ... } T await_resume() { @@ -245,7 +245,7 @@ public: bool await_ready() const noexcept { ... } - void await_suspend(coro::coroutine_handle<> h) const { ... } + void await_suspend(std::coroutine_handle<> h) const { ... } T await_resume() { ... } diff --git a/doc/responses.md b/doc/responses.md index 079d18c6..d328f5cf 100644 --- a/doc/responses.md +++ b/doc/responses.md @@ -41,8 +41,8 @@ specializations. ## Map and List -`Map` and `List` types enable collection methods like `reserve(size_t)`, +`Map` and `List` types enable collection methods like `reserve(std::size_t)`, `size()`, and `emplace_back(...)`. `Map` additionally implements `begin()` and `end()` for range-based for loops and `find(const std::string&)` and `operator[](const std::string&)` for key-based lookups. `List` has an -`operator[](size_t)` for index-based instead of key-based lookups. \ No newline at end of file +`operator[](std::size_t)` for index-based instead of key-based lookups. \ No newline at end of file diff --git a/include/ClientGenerator.h b/include/ClientGenerator.h index 6083e526..4070a12f 100644 --- a/include/ClientGenerator.h +++ b/include/ClientGenerator.h @@ -9,6 +9,8 @@ #include "RequestLoader.h" #include "SchemaLoader.h" +#include + namespace graphql::generator::client { struct [[nodiscard("unnecessary construction")]] GeneratorPaths @@ -27,9 +29,8 @@ class [[nodiscard("unnecessary construction")]] Generator { public: // Initialize the generator with the introspection client or a custom GraphQL client. - explicit Generator(SchemaOptions && schemaOptions, - RequestOptions && requestOptions, - GeneratorOptions && options); + explicit Generator( + SchemaOptions&& schemaOptions, RequestOptions&& requestOptions, GeneratorOptions&& options); // Run the generator and return a list of filenames that were output. [[nodiscard("unnecessary memory copy")]] std::vector Build() const noexcept; @@ -38,29 +39,29 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getHeaderDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getModulePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; [[nodiscard("unnecessary call")]] const std::string& getClientNamespace() const noexcept; [[nodiscard("unnecessary call")]] const std::string& getOperationNamespace( const Operation& operation) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getResponseFieldCppType( - const ResponseField& responseField, - std::string_view currentScope = {}) const noexcept; + const ResponseField& responseField, std::string_view currentScope = {}) const noexcept; [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; - void outputRequestComment(std::ostream & headerFile) const noexcept; - void outputGetRequestDeclaration(std::ostream & headerFile) const noexcept; - void outputGetOperationNameDeclaration(std::ostream & headerFile) const noexcept; - [[nodiscard("unnecessary call")]] bool outputResponseFieldType(std::ostream & headerFile, - const ResponseField& responseField, - size_t indent = 0) const noexcept; + void outputRequestComment(std::ostream& headerFile) const noexcept; + void outputGetRequestDeclaration(std::ostream& headerFile) const noexcept; + void outputGetOperationNameDeclaration(std::ostream& headerFile) const noexcept; + [[nodiscard("unnecessary call")]] bool outputResponseFieldType(std::ostream& headerFile, + const ResponseField& responseField, std::size_t indent = 0) const noexcept; + + [[nodiscard("unnecessary call")]] bool outputModule() const noexcept; [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; - void outputGetRequestImplementation(std::ostream & sourceFile) const noexcept; - void outputGetOperationNameImplementation(std::ostream & sourceFile, const Operation& operation) - const noexcept; - bool outputModifiedResponseImplementation(std::ostream & sourceFile, - const std::string& outerScope, - const ResponseField& responseField) const noexcept; + void outputGetRequestImplementation(std::ostream& sourceFile) const noexcept; + void outputGetOperationNameImplementation( + std::ostream& sourceFile, const Operation& operation) const noexcept; + bool outputModifiedResponseImplementation(std::ostream& sourceFile, + const std::string& outerScope, const ResponseField& responseField) const noexcept; [[nodiscard("unnecessary memory copy")]] static std::string getTypeModifierList( const TypeModifierStack& modifiers) noexcept; @@ -70,6 +71,7 @@ class [[nodiscard("unnecessary construction")]] Generator const std::string _headerDir; const std::string _sourceDir; const std::string _headerPath; + const std::string _modulePath; const std::string _sourcePath; }; diff --git a/include/SchemaGenerator.h b/include/SchemaGenerator.h index f0ba1bf0..225d2b1d 100644 --- a/include/SchemaGenerator.h +++ b/include/SchemaGenerator.h @@ -8,6 +8,8 @@ #include "SchemaLoader.h" +#include + namespace graphql::generator::schema { struct [[nodiscard("unnecessary construction")]] GeneratorPaths @@ -28,7 +30,7 @@ class [[nodiscard("unnecessary construction")]] Generator { public: // Initialize the generator with the introspection schema or a custom GraphQL schema. - explicit Generator(SchemaOptions && schemaOptions, GeneratorOptions && options); + explicit Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options); // Run the generator and return a list of filenames that were output. [[nodiscard("unnecessary construction")]] std::vector Build() const noexcept; @@ -37,15 +39,18 @@ class [[nodiscard("unnecessary construction")]] Generator [[nodiscard("unnecessary memory copy")]] std::string getHeaderDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourceDir() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getHeaderPath() const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getModulePath() const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getSourcePath() const noexcept; [[nodiscard("unnecessary call")]] bool outputHeader() const noexcept; - void outputInterfaceDeclaration(std::ostream & headerFile, std::string_view cppType) const; - void outputObjectImplements(std::ostream & headerFile, const ObjectType& objectType) const; - void outputObjectStubs(std::ostream & headerFile, const ObjectType& objectType) const; - void outputObjectDeclaration(std::ostream & headerFile, - const ObjectType& objectType, - bool isQueryType) const; + [[nodiscard("unnecessary call")]] bool outputModule() const noexcept; + void outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const; + void outputObjectModule( + std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const; + void outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const; + void outputObjectStubs(std::ostream& headerFile, const ObjectType& objectType) const; + void outputObjectDeclaration( + std::ostream& headerFile, const ObjectType& objectType, bool isQueryType) const; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( const InputField& inputField) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getFieldDeclaration( @@ -54,26 +59,21 @@ class [[nodiscard("unnecessary construction")]] Generator const OutputField& outputField) const noexcept; [[nodiscard("unnecessary call")]] bool outputSource() const noexcept; - void outputInterfaceImplementation(std::ostream & sourceFile, std::string_view cppType) const; - void outputInterfaceIntrospection(std::ostream & sourceFile, const InterfaceType& interfaceType) - const; - void outputUnionIntrospection(std::ostream & sourceFile, const UnionType& unionType) const; - void outputObjectImplementation(std::ostream & sourceFile, - const ObjectType& objectType, - bool isQueryType) const; - void outputObjectIntrospection(std::ostream & sourceFile, const ObjectType& objectType) const; - void outputIntrospectionInterfaces(std::ostream & sourceFile, - std::string_view cppType, + void outputInterfaceImplementation(std::ostream& sourceFile, std::string_view cppType) const; + void outputInterfaceIntrospection( + std::ostream& sourceFile, const InterfaceType& interfaceType) const; + void outputUnionIntrospection(std::ostream& sourceFile, const UnionType& unionType) const; + void outputObjectImplementation( + std::ostream& sourceFile, const ObjectType& objectType, bool isQueryType) const; + void outputObjectIntrospection(std::ostream& sourceFile, const ObjectType& objectType) const; + void outputIntrospectionInterfaces(std::ostream& sourceFile, std::string_view cppType, const std::vector& interfaces) const; - void outputIntrospectionFields(std::ostream & sourceFile, - std::string_view cppType, - const OutputFieldList& fields) const; - [[nodiscard("unnecessary memory copy")]] std::string getArgumentDefaultValue(size_t level, - const response::Value& defaultValue) const noexcept; + void outputIntrospectionFields( + std::ostream& sourceFile, std::string_view cppType, const OutputFieldList& fields) const; + [[nodiscard("unnecessary memory copy")]] std::string getArgumentDefaultValue( + std::size_t level, const response::Value& defaultValue) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getArgumentDeclaration( - const InputField& argument, - const char* prefixToken, - const char* argumentsToken, + const InputField& argument, const char* prefixToken, const char* argumentsToken, const char* defaultToken) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getArgumentAccessType( const InputField& argument) const noexcept; @@ -81,8 +81,8 @@ class [[nodiscard("unnecessary construction")]] Generator const OutputField& result) const noexcept; [[nodiscard("unnecessary memory copy")]] std::string getTypeModifiers( const TypeModifierStack& modifiers) const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getIntrospectionType(std::string_view type, - const TypeModifierStack& modifiers) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getIntrospectionType( + std::string_view type, const TypeModifierStack& modifiers) const noexcept; [[nodiscard("unnecessary memory copy")]] std::vector outputSeparateFiles() const noexcept; @@ -92,8 +92,10 @@ class [[nodiscard("unnecessary construction")]] Generator SchemaLoader _loader; const GeneratorOptions _options; const std::string _headerDir; + const std::string _moduleDir; const std::string _sourceDir; const std::string _headerPath; + const std::string _modulePath; const std::string _sourcePath; }; diff --git a/include/SchemaLoader.h b/include/SchemaLoader.h index 9aa73444..181de219 100644 --- a/include/SchemaLoader.h +++ b/include/SchemaLoader.h @@ -14,6 +14,7 @@ #include "graphqlservice/internal/Grammar.h" #include +#include #include #include @@ -31,14 +32,14 @@ enum class [[nodiscard("unnecessary conversion")]] BuiltinType { using BuiltinTypeMap = std::map; // These are the C++ types we'll use for them. -using CppTypeMap = std::array(BuiltinType::ID) + 1>; +using CppTypeMap = std::array(BuiltinType::ID) + 1>; // Keep track of the positions of each type declaration in the file. using PositionMap = std::unordered_map; // For all of the named types we track, we want to keep them in order in a vector but // be able to lookup their offset quickly by name. -using TypeNameMap = std::unordered_map; +using TypeNameMap = std::unordered_map; // Scalar types are opaque to the generator, it's up to the service implementation // to handle parsing, validating, and serializing them. We just need to track which @@ -216,7 +217,7 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader { public: // Initialize the loader with the introspection schema or a custom GraphQL schema. - explicit SchemaLoader(SchemaOptions && schemaOptions); + explicit SchemaLoader(SchemaOptions&& schemaOptions); [[nodiscard("unnecessary call")]] bool isIntrospection() const noexcept; [[nodiscard("unnecessary call")]] std::string_view getSchemaDescription() const noexcept; @@ -232,22 +233,22 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader [[nodiscard("unnecessary call")]] const tao::graphqlpeg::position& getTypePosition( std::string_view type) const; - [[nodiscard("unnecessary call")]] size_t getScalarIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getScalarIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const ScalarTypeList& getScalarTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getEnumIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getEnumIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const EnumTypeList& getEnumTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getInputIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getInputIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const InputTypeList& getInputTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getUnionIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getUnionIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const UnionTypeList& getUnionTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getInterfaceIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getInterfaceIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const InterfaceTypeList& getInterfaceTypes() const noexcept; - [[nodiscard("unnecessary call")]] size_t getObjectIndex(std::string_view type) const; + [[nodiscard("unnecessary call")]] std::size_t getObjectIndex(std::string_view type) const; [[nodiscard("unnecessary call")]] const ObjectTypeList& getObjectTypes() const noexcept; [[nodiscard("unnecessary call")]] const DirectiveList& getDirectives() const noexcept; @@ -259,12 +260,12 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader [[nodiscard("unnecessary call")]] static std::string_view getSafeCppName( std::string_view type) noexcept; - [[nodiscard("unnecessary call")]] std::string_view getCppType(std::string_view type) - const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getInputCppType(const InputField& field) - const noexcept; - [[nodiscard("unnecessary memory copy")]] std::string getOutputCppType(const OutputField& field) - const noexcept; + [[nodiscard("unnecessary call")]] std::string_view getCppType( + std::string_view type) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getInputCppType( + const InputField& field) const noexcept; + [[nodiscard("unnecessary memory copy")]] std::string getOutputCppType( + const OutputField& field) const noexcept; [[nodiscard("unnecessary memory copy")]] static std::string getOutputCppAccessor( const OutputField& field) noexcept; @@ -296,32 +297,29 @@ class [[nodiscard("unnecessary construction")]] SchemaLoader void visitObjectTypeExtension(const peg::ast_node& objectTypeExtension); void visitDirectiveDefinition(const peg::ast_node& directiveDefinition); - static void blockReservedName(std::string_view name, - std::optional position = std::nullopt); + static void blockReservedName( + std::string_view name, std::optional position = std::nullopt); [[nodiscard("unnecessary memory copy")]] static OutputFieldList getOutputFields( const peg::ast_node::children_t& fields); [[nodiscard("unnecessary memory copy")]] static InputFieldList getInputFields( const peg::ast_node::children_t& fields); void validateSchema(); - void fixupOutputFieldList(OutputFieldList & fields, + void fixupOutputFieldList(OutputFieldList& fields, const std::optional>& interfaceFields, const std::optional& accessor); - void fixupInputFieldList(InputFieldList & fields); + void fixupInputFieldList(InputFieldList& fields); void reorderInputTypeDependencies(); void validateImplementedInterfaces() const; [[nodiscard("unnecessary call")]] const InterfaceType& findInterfaceType( - std::string_view typeName, - std::string_view interfaceName) const; - void validateInterfaceFields(std::string_view typeName, - std::string_view interfaceName, + std::string_view typeName, std::string_view interfaceName) const; + void validateInterfaceFields(std::string_view typeName, std::string_view interfaceName, const OutputFieldList& typeFields) const; - void validateTransitiveInterfaces(std::string_view typeName, - const std::vector& interfaces) const; + void validateTransitiveInterfaces( + std::string_view typeName, const std::vector& interfaces) const; [[nodiscard("unnecessary memory copy")]] static std::string getJoinedCppName( - std::string_view prefix, - std::string_view fieldName) noexcept; + std::string_view prefix, std::string_view fieldName) noexcept; static const std::string_view s_introspectionNamespace; static const BuiltinTypeMap s_builtinTypes; diff --git a/include/Validation.h b/include/Validation.h index 5b11057c..1dd48c77 100644 --- a/include/Validation.h +++ b/include/Validation.h @@ -10,6 +10,8 @@ #include "graphqlservice/internal/Schema.h" +#include + namespace graphql::service { using ValidateType = std::optional>; @@ -257,8 +259,8 @@ class [[nodiscard("unnecessary construction")]] ValidateExecutableVisitor VariableDefinitions _variableDefinitions; VariableSet _referencedVariables; FragmentSet _fragmentStack; - size_t _fieldCount = 0; - size_t _introspectionFieldCount = 0; + std::size_t _fieldCount = 0; + std::size_t _introspectionFieldCount = 0; TypeFields _typeFields; InputTypeFields _inputTypeFields; ValidateType _scopedType; diff --git a/include/graphqlservice/Client.ixx b/include/graphqlservice/Client.ixx new file mode 100644 index 00000000..9740d304 --- /dev/null +++ b/include/graphqlservice/Client.ixx @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLClient.h" + +export module GraphQL.Client; + +export import GraphQL.Response; + +export namespace graphql::client { + +// clang-format off +using client::ErrorLocation; +using client::ErrorPathSegment; +using client::Error; +using client::ServiceResponse; +using client::parseServiceResponse; +using client::TypeModifier; +using client::Variable; + +using modified_variable::ModifiedVariable; +using modified_variable::IntVariable; +using modified_variable::FloatVariable; +using modified_variable::StringVariable; +using modified_variable::BooleanVariable; +using modified_variable::IdVariable; +using modified_variable::ScalarVariable; + +using client::Response; + +using modified_response::ModifiedResponse; +using modified_response::IntResponse; +using modified_response::FloatResponse; +using modified_response::StringResponse; +using modified_response::BooleanResponse; +using modified_response::IdResponse; +using modified_response::ScalarResponse; +// clang-format on + +} // namespace graphql::client diff --git a/include/graphqlservice/GraphQLClient.h b/include/graphqlservice/GraphQLClient.h index 2aa7835d..afc0caa2 100644 --- a/include/graphqlservice/GraphQLClient.h +++ b/include/graphqlservice/GraphQLClient.h @@ -8,14 +8,12 @@ #include "GraphQLResponse.h" -#include "internal/Version.h" #include "internal/DllExports.h" #include #include #include #include -#include #include namespace graphql::client { @@ -85,7 +83,7 @@ template <> GRAPHQLCLIENT_EXPORT response::Value Variable::serialize(response::Value&& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_variable { // These types are used as scalar variables even though they are represented with a class. template @@ -236,7 +234,7 @@ using BooleanVariable = ModifiedVariable; using IdVariable = ModifiedVariable; using ScalarVariable = ModifiedVariable; -} // namespace +} // namespace modified_variable // Parse a single response output value. This is the inverse of Variable for output types instead of // input types. @@ -263,7 +261,7 @@ template <> GRAPHQLCLIENT_EXPORT response::Value Response::parse(response::Value&& response); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_response { // Parse response output values with chained type modifiers that add nullable or list wrappers. // This is the inverse of ModifiedVariable for output types instead of input types. @@ -346,7 +344,7 @@ using BooleanResponse = ModifiedResponse; using IdResponse = ModifiedResponse; using ScalarResponse = ModifiedResponse; -} // namespace +} // namespace modified_response } // namespace graphql::client #endif // GRAPHQLCLIENT_H diff --git a/include/graphqlservice/GraphQLParse.h b/include/graphqlservice/GraphQLParse.h index cfd8682f..4336fb8e 100644 --- a/include/graphqlservice/GraphQLParse.h +++ b/include/graphqlservice/GraphQLParse.h @@ -8,6 +8,7 @@ #include "internal/DllExports.h" +#include #include #include @@ -26,22 +27,22 @@ struct [[nodiscard("unnecessary parse")]] ast // By default, we want to limit the depth of nested nodes. You can override this with // another value for the depthLimit parameter in these parse functions. -constexpr size_t c_defaultDepthLimit = 25; +constexpr std::size_t c_defaultDepthLimit = 25; [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaString( - std::string_view input, size_t depthLimit = c_defaultDepthLimit); + std::string_view input, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseSchemaFile( - std::string_view filename, size_t depthLimit = c_defaultDepthLimit); + std::string_view filename, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseString( - std::string_view input, size_t depthLimit = c_defaultDepthLimit); + std::string_view input, std::size_t depthLimit = c_defaultDepthLimit); [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT ast parseFile( - std::string_view filename, size_t depthLimit = c_defaultDepthLimit); + std::string_view filename, std::size_t depthLimit = c_defaultDepthLimit); } // namespace peg [[nodiscard("unnecessary parse")]] GRAPHQLPEG_EXPORT peg::ast operator"" _graphql( - const char* text, size_t size); + const char* text, std::size_t size); } // namespace graphql diff --git a/include/graphqlservice/GraphQLResponse.h b/include/graphqlservice/GraphQLResponse.h index b8249926..f155c04f 100644 --- a/include/graphqlservice/GraphQLResponse.h +++ b/include/graphqlservice/GraphQLResponse.h @@ -6,11 +6,13 @@ #ifndef GRAPHQLRESPONSE_H #define GRAPHQLRESPONSE_H -#include "internal/Awaitable.h" #include "internal/DllExports.h" +#include "internal/Awaitable.h" +#include #include #include +#include #include #include #include @@ -55,7 +57,7 @@ struct [[nodiscard("unnecessary conversion")]] IdType GRAPHQLRESPONSE_EXPORT ~IdType(); // Implicit ByteData constructors - GRAPHQLRESPONSE_EXPORT IdType(size_t count, typename ByteData::value_type value = 0); + GRAPHQLRESPONSE_EXPORT IdType(std::size_t count, typename ByteData::value_type value = 0); GRAPHQLRESPONSE_EXPORT IdType(std::initializer_list values); template IdType(InputIt begin, InputIt end); @@ -90,20 +92,21 @@ struct [[nodiscard("unnecessary conversion")]] IdType // Shared accessors [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT bool empty() const noexcept; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t size() const noexcept; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t max_size() const noexcept; - GRAPHQLRESPONSE_EXPORT void reserve(size_t new_cap); - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t capacity() const noexcept; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t size() const noexcept; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t max_size() const noexcept; + GRAPHQLRESPONSE_EXPORT void reserve(std::size_t new_cap); + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t capacity() const noexcept; GRAPHQLRESPONSE_EXPORT void shrink_to_fit(); GRAPHQLRESPONSE_EXPORT void clear() noexcept; // ByteData accessors [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& at( - size_t pos) const; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& at(size_t pos); + std::size_t pos) const; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& at(std::size_t pos); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& operator[]( - size_t pos) const; - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& operator[](size_t pos); + std::size_t pos) const; + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& operator[]( + std::size_t pos); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& front() const; [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::uint8_t& front(); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const std::uint8_t& back() const; @@ -250,8 +253,8 @@ struct [[nodiscard("unnecessary conversion")]] Value [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT bool maybe_id() const noexcept; // Valid for Type::Map or Type::List - GRAPHQLRESPONSE_EXPORT void reserve(size_t count); - [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT size_t size() const; + GRAPHQLRESPONSE_EXPORT void reserve(std::size_t count); + [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT std::size_t size() const; // Valid for Type::Map GRAPHQLRESPONSE_EXPORT bool emplace_back(std::string&& name, Value&& value); @@ -265,7 +268,7 @@ struct [[nodiscard("unnecessary conversion")]] Value // Valid for Type::List GRAPHQLRESPONSE_EXPORT void emplace_back(Value&& value); [[nodiscard("unnecessary call")]] GRAPHQLRESPONSE_EXPORT const Value& operator[]( - size_t index) const; + std::size_t index) const; // Specialized for all single-value Types. template @@ -286,7 +289,7 @@ struct [[nodiscard("unnecessary conversion")]] Value [[nodiscard("unnecessary call")]] bool operator==(const MapData& rhs) const; MapType map; - std::vector members; + std::vector members; }; // Type::String @@ -461,7 +464,7 @@ class [[nodiscard("unnecessary construction")]] Writer final template Writer(std::unique_ptr writer) noexcept : _concept { std::static_pointer_cast( - std::make_shared>(std::move(writer))) } + std::make_shared>(std::move(writer))) } { } diff --git a/include/graphqlservice/GraphQLService.h b/include/graphqlservice/GraphQLService.h index a412b1a4..9561eb86 100644 --- a/include/graphqlservice/GraphQLService.h +++ b/include/graphqlservice/GraphQLService.h @@ -12,11 +12,10 @@ #include "internal/Awaitable.h" #include "internal/DllExports.h" #include "internal/SortedMap.h" -#include "internal/Version.h" #include #include -#include +#include #include #include #include @@ -26,9 +25,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -45,19 +42,19 @@ namespace service { // Errors should have a message string, and optional locations and a path. struct [[nodiscard("unnecessary construction")]] schema_location { - size_t line = 0; - size_t column = 1; + std::size_t line = 0; + std::size_t column = 1; }; // The implementation details of the error path should be opaque to client code. It is carried along // with the SelectionSetParams and automatically added to any schema errors or exceptions thrown // from an accessor as part of error reporting. -using path_segment = std::variant; +using path_segment = std::variant; struct [[nodiscard("unnecessary construction")]] field_path { std::optional> parent; - std::variant segment; + std::variant segment; }; using error_path = std::vector; @@ -123,18 +120,16 @@ struct [[nodiscard("unnecessary construction")]] RequestState inline namespace keywords { -using namespace std::literals; - -constexpr std::string_view strData { "data"sv }; -constexpr std::string_view strErrors { "errors"sv }; -constexpr std::string_view strMessage { "message"sv }; -constexpr std::string_view strLocations { "locations"sv }; -constexpr std::string_view strLine { "line"sv }; -constexpr std::string_view strColumn { "column"sv }; -constexpr std::string_view strPath { "path"sv }; -constexpr std::string_view strQuery { "query"sv }; -constexpr std::string_view strMutation { "mutation"sv }; -constexpr std::string_view strSubscription { "subscription"sv }; +constexpr std::string_view strData { "data" }; +constexpr std::string_view strErrors { "errors" }; +constexpr std::string_view strMessage { "message" }; +constexpr std::string_view strLocations { "locations" }; +constexpr std::string_view strLine { "line" }; +constexpr std::string_view strColumn { "column" }; +constexpr std::string_view strPath { "path" }; +constexpr std::string_view strQuery { "query" }; +constexpr std::string_view strMutation { "mutation" }; +constexpr std::string_view strSubscription { "subscription" }; } // namespace keywords @@ -160,20 +155,20 @@ enum class [[nodiscard("unnecessary conversion")]] ResolverContext { // Resume coroutine execution on a new worker thread any time co_await is called. This emulates the // behavior of std::async when passing std::launch::async. -struct [[nodiscard("unnecessary construction")]] await_worker_thread : coro::suspend_always +struct [[nodiscard("unnecessary construction")]] await_worker_thread : std::suspend_always { - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h) const; + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h) const; }; // Queue coroutine execution on a single dedicated worker thread any time co_await is called from // the thread which created it. -struct [[nodiscard("unnecessary construction")]] await_worker_queue : coro::suspend_always +struct [[nodiscard("unnecessary construction")]] await_worker_queue : std::suspend_always { GRAPHQLSERVICE_EXPORT await_worker_queue(); GRAPHQLSERVICE_EXPORT ~await_worker_queue(); [[nodiscard("unexpected call")]] GRAPHQLSERVICE_EXPORT bool await_ready() const; - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h); + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h); private: void resumePending(); @@ -181,7 +176,7 @@ struct [[nodiscard("unnecessary construction")]] await_worker_queue : coro::susp const std::thread::id _startId; std::mutex _mutex {}; std::condition_variable _cv {}; - std::list> _pending {}; + std::list> _pending {}; bool _shutdown = false; std::thread _worker; }; @@ -195,7 +190,7 @@ class [[nodiscard("unnecessary construction")]] await_async final virtual ~Concept() = default; [[nodiscard("unexpected call")]] virtual bool await_ready() const = 0; - virtual void await_suspend(coro::coroutine_handle<> h) const = 0; + virtual void await_suspend(std::coroutine_handle<> h) const = 0; virtual void await_resume() const = 0; }; @@ -212,7 +207,7 @@ class [[nodiscard("unnecessary construction")]] await_async final return _pimpl->await_ready(); } - void await_suspend(coro::coroutine_handle<> h) const final + void await_suspend(std::coroutine_handle<> h) const final { _pimpl->await_suspend(std::move(h)); } @@ -243,7 +238,7 @@ class [[nodiscard("unnecessary construction")]] await_async final GRAPHQLSERVICE_EXPORT await_async(std::launch launch); [[nodiscard("unexpected call")]] GRAPHQLSERVICE_EXPORT bool await_ready() const; - GRAPHQLSERVICE_EXPORT void await_suspend(coro::coroutine_handle<> h) const; + GRAPHQLSERVICE_EXPORT void await_suspend(std::coroutine_handle<> h) const; GRAPHQLSERVICE_EXPORT void await_resume() const; }; @@ -317,12 +312,12 @@ class [[nodiscard("unnecessary construction")]] AwaitableScalar return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -371,10 +366,10 @@ class [[nodiscard("unnecessary construction")]] AwaitableScalar _value); } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { std::thread( - [this](coro::coroutine_handle<> h) noexcept { + [this](std::coroutine_handle<> h) noexcept { std::get>(_value).wait(); h.resume(); }, @@ -447,12 +442,12 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -496,10 +491,10 @@ class [[nodiscard("unnecessary construction")]] AwaitableObject _value); } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { std::thread( - [this](coro::coroutine_handle<> h) noexcept { + [this](std::coroutine_handle<> h) noexcept { std::get>(_value).wait(); h.resume(); }, @@ -636,7 +631,7 @@ GRAPHQLSERVICE_EXPORT response::Value Argument::convert( const response::Value& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_argument { // These types are used as scalar arguments even though they are represented with a class. template @@ -852,7 +847,7 @@ using BooleanArgument = ModifiedArgument; using IdArgument = ModifiedArgument; using ScalarArgument = ModifiedArgument; -} // namespace +} // namespace modified_argument // Each type should handle fragments with type conditions matching its own // name and any inheritted interfaces. @@ -950,7 +945,7 @@ template <> GRAPHQLSERVICE_EXPORT void Result::validateScalar(const response::Value& value); #endif // GRAPHQL_DLLEXPORTS -namespace { +inline namespace modified_result { // Test if this Type is Object. template @@ -1147,7 +1142,7 @@ struct ModifiedResult children.reserve(awaitedResult.size()); params.errorPath = std::make_optional( field_path { parentPath ? std::make_optional(std::cref(*parentPath)) : std::nullopt, - path_segment { size_t { 0 } } }); + path_segment { std::size_t { 0 } } }); using vector_type = std::decay_t; @@ -1161,7 +1156,7 @@ struct ModifiedResult { children.push_back( ModifiedResult::convert(std::move(entry), ResolverParams(params))); - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } } else @@ -1170,14 +1165,14 @@ struct ModifiedResult { children.push_back( ModifiedResult::convert(std::move(entry), ResolverParams(params))); - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } } ResolverResult document { response::Value { response::Type::List } }; document.data.reserve(children.size()); - std::get(params.errorPath->segment) = 0; + std::get(params.errorPath->segment) = 0; for (auto& child : children) { @@ -1215,7 +1210,7 @@ struct ModifiedResult buildErrorPath(params.errorPath) }); } - ++std::get(params.errorPath->segment); + ++std::get(params.errorPath->segment); } co_return document; @@ -1253,7 +1248,7 @@ struct ModifiedResult throw schema_exception { { R"ex(not a valid List value)ex" } }; } - for (size_t i = 0; i < value.size(); ++i) + for (std::size_t i = 0; i < value.size(); ++i) { ModifiedResult::validateScalar(value[i]); } @@ -1322,14 +1317,14 @@ using IdResult = ModifiedResult; using ScalarResult = ModifiedResult; using ObjectResult = ModifiedResult; -} // namespace +} // namespace modified_result // Subscription callbacks receive the response::Value representing the result of evaluating the // SelectionSet against the payload. using SubscriptionCallback = std::function; // Subscriptions are stored in maps using these keys. -using SubscriptionKey = size_t; +using SubscriptionKey = std::size_t; using SubscriptionName = std::string; using AwaitableSubscribe = internal::Awaitable; diff --git a/include/graphqlservice/JSONResponse.ixx b/include/graphqlservice/JSONResponse.ixx new file mode 100644 index 00000000..ff36ba7e --- /dev/null +++ b/include/graphqlservice/JSONResponse.ixx @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "JSONResponse.h" + +export module GraphQL.JSONResponse; + +export import GraphQL.Response; + +export namespace graphql::response { + +// clang-format off +using response::toJSON; +using response::parseJSON; +// clang-format on + +} // namespace graphql::response diff --git a/include/graphqlservice/Parse.ixx b/include/graphqlservice/Parse.ixx new file mode 100644 index 00000000..bd699cf1 --- /dev/null +++ b/include/graphqlservice/Parse.ixx @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLParse.h" + +export module GraphQL.Parse; + +export namespace graphql { + +namespace peg { + +// clang-format off +using peg::ast_node; +using peg::ast_input; +using peg::ast; + +namespace constants { + +constexpr std::size_t c_defaultDepthLimit = peg::c_defaultDepthLimit; + +} // namespace constants + +using peg::parseSchemaString; +using peg::parseSchemaFile; +using peg::parseString; +using peg::parseFile; +// clang-format on + +} // namespace peg + +using graphql::operator"" _graphql; + +} // namespace graphql diff --git a/include/graphqlservice/Response.ixx b/include/graphqlservice/Response.ixx new file mode 100644 index 00000000..208368e6 --- /dev/null +++ b/include/graphqlservice/Response.ixx @@ -0,0 +1,34 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLResponse.h" + +export module GraphQL.Response; + +namespace included = graphql::response; + +export namespace graphql::response { + +// clang-format off +using response::Type; + +using response::MapType; +using response::ListType; +using response::StringType; +using response::BooleanType; +using response::IntType; +using response::FloatType; +using response::ScalarType; + +using response::IdType; + +using response::ValueTypeTraits; +using response::Value; +using response::AwaitableValue; + +using response::Writer; +// clang-format on + +} // namespace graphql::response diff --git a/include/graphqlservice/Service.ixx b/include/graphqlservice/Service.ixx new file mode 100644 index 00000000..83b88a2f --- /dev/null +++ b/include/graphqlservice/Service.ixx @@ -0,0 +1,130 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "GraphQLService.h" + +export module GraphQL.Service; + +export import GraphQL.Parse; +export import GraphQL.Response; + +export namespace graphql { + +namespace schema { + +using schema::Schema; + +} // namespace schema + +namespace service { + +// clang-format off +using service::schema_location; +using service::path_segment; +using service::field_path; + +using service::error_path; +using service::buildErrorPath; + +using service::schema_error; +using service::buildErrorValues; + +using service::schema_exception; +using service::unimplemented_method; + +using service::RequestState; + +constexpr std::string_view strData = keywords::strData; +constexpr std::string_view strErrors = keywords::strErrors; +constexpr std::string_view strMessage = keywords::strMessage; +constexpr std::string_view strLocations = keywords::strLocations; +constexpr std::string_view strLine = keywords::strLine; +constexpr std::string_view strColumn = keywords::strColumn; +constexpr std::string_view strPath = keywords::strPath; +constexpr std::string_view strQuery = keywords::strQuery; +constexpr std::string_view strMutation = keywords::strMutation; +constexpr std::string_view strSubscription = keywords::strSubscription; + +using service::ResolverContext; + +using service::await_worker_thread; +using service::await_worker_queue; +using service::await_async; + +using service::Directives; +using service::FragmentDefinitionDirectiveStack; +using service::FragmentSpreadDirectiveStack; + +using service::SelectionSetParams; +using service::FieldParams; + +using service::AwaitableScalar; +using service::AwaitableObject; + +using service::Fragment; +using service::FragmentMap; + +using service::ResolverParams; +using service::ResolverResult; +using service::AwaitableResolver; +using service::Resolver; +using service::ResolverMap; + +using service::TypeModifier; +using service::Argument; + +using modified_argument::ModifiedArgument; +using modified_argument::IntArgument; +using modified_argument::FloatArgument; +using modified_argument::StringArgument; +using modified_argument::BooleanArgument; +using modified_argument::IdArgument; +using modified_argument::ScalarArgument; + +using service::TypeNames; +using service::Object; +using service::Result; + +using modified_result::ModifiedResult; +using modified_result::IntResult; +using modified_result::FloatResult; +using modified_result::StringResult; +using modified_result::BooleanResult; +using modified_result::IdResult; +using modified_result::ScalarResult; +using modified_result::ObjectResult; + +using service::SubscriptionCallback; +using service::SubscriptionKey; +using service::SubscriptionName; + +using service::AwaitableSubscribe; +using service::AwaitableUnsubscribe; +using service::AwaitableDeliver; + +using service::RequestResolveParams; +using service::RequestSubscribeParams; +using service::RequestUnsubscribeParams; + +using service::SubscriptionArguments; +using service::SubscriptionArgumentFilterCallback; +using service::SubscriptionDirectiveFilterCallback; +using service::SubscriptionFilter; + +using service::RequestDeliverFilter; +using service::RequestDeliverParams; + +using service::TypeMap; +using service::OperationData; +using service::SubscriptionData; + +using service::SubscriptionPlaceholder; + +using service::Request; +// clang-format on + +} // namespace service + +} // namespace graphql diff --git a/include/graphqlservice/internal/Awaitable.h b/include/graphqlservice/internal/Awaitable.h index 45097751..046e6a8b 100644 --- a/include/graphqlservice/internal/Awaitable.h +++ b/include/graphqlservice/internal/Awaitable.h @@ -6,16 +6,7 @@ #ifndef GRAPHQLAWAITABLE_H #define GRAPHQLAWAITABLE_H -// clang-format off -#ifdef USE_STD_EXPERIMENTAL_COROUTINE - #include - namespace coro = std::experimental; -#else // !USE_STD_EXPERIMENTAL_COROUTINE - #include - namespace coro = std; -#endif -// clang-format on - +#include #include #include @@ -45,12 +36,12 @@ class [[nodiscard("unnecessary construction")]] Awaitable return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -74,7 +65,7 @@ class [[nodiscard("unnecessary construction")]] Awaitable return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } @@ -109,12 +100,12 @@ class [[nodiscard("unnecessary construction")]] Awaitable return { _promise.get_future() }; } - coro::suspend_never initial_suspend() const noexcept + std::suspend_never initial_suspend() const noexcept { return {}; } - coro::suspend_never final_suspend() const noexcept + std::suspend_never final_suspend() const noexcept { return {}; } @@ -143,7 +134,7 @@ class [[nodiscard("unnecessary construction")]] Awaitable return true; } - void await_suspend(coro::coroutine_handle<> h) const + void await_suspend(std::coroutine_handle<> h) const { h.resume(); } diff --git a/include/graphqlservice/internal/Awaitable.ixx b/include/graphqlservice/internal/Awaitable.ixx new file mode 100644 index 00000000..40d5e4c2 --- /dev/null +++ b/include/graphqlservice/internal/Awaitable.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Awaitable.h" + +export module GraphQL.Internal.Awaitable; + +export namespace graphql::internal { + +// clang-format off +using internal::Awaitable; +// clang-format on + +} // namespace graphql::internal diff --git a/include/graphqlservice/internal/Base64.ixx b/include/graphqlservice/internal/Base64.ixx new file mode 100644 index 00000000..1952d46a --- /dev/null +++ b/include/graphqlservice/internal/Base64.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Base64.h" + +export module GraphQL.Internal.Base64; + +export namespace graphql::internal { + +// clang-format off +using internal::Base64; +// clang-format on + +} // namespace graphql::internal diff --git a/include/graphqlservice/internal/Grammar.ixx b/include/graphqlservice/internal/Grammar.ixx new file mode 100644 index 00000000..2c780476 --- /dev/null +++ b/include/graphqlservice/internal/Grammar.ixx @@ -0,0 +1,256 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Grammar.h" + +export module GraphQL.Internal.Grammar; + +export namespace graphql::peg { + +// clang-format off +using namespace tao::graphqlpeg; + +using peg::for_each_child; +using peg::on_first_child; +using peg::on_first_child_if; + +using peg::alias; +using peg::alias_name; +using peg::argument; +using peg::argument_content; +using peg::argument_name; +using peg::arguments; +using peg::arguments_content; +using peg::backslash_token; +using peg::block_escape_sequence; +using peg::block_quote; +using peg::block_quote_character; +using peg::block_quote_content; +using peg::block_quote_content_lines; +using peg::block_quote_empty_line; +using peg::block_quote_line; +using peg::block_quote_line_content; +using peg::block_quote_token; +using peg::bool_value; +using peg::comment; +using peg::default_value; +using peg::default_value_content; +using peg::directive; +using peg::directive_content; +using peg::directive_name; +using peg::directives; +using peg::enum_value; +using peg::escaped_char; +using peg::escaped_unicode; +using peg::escaped_unicode_codepoint; +using peg::escaped_unicode_content; +using peg::exponent_indicator; +using peg::exponent_part; +using peg::exponent_part_content; +using peg::false_keyword; +using peg::field; +using peg::field_arguments; +using peg::field_content; +using peg::field_directives; +using peg::field_name; +using peg::field_selection_set; +using peg::field_start; +using peg::float_value; +using peg::fractional_part; +using peg::fractional_part_content; +using peg::fragment_name; +using peg::fragment_spread; +using peg::fragment_token; +using peg::ignored; +using peg::inline_fragment; +using peg::input_value; +using peg::input_value_content; +using peg::integer_part; +using peg::integer_value; +using peg::list_entry; +using peg::list_type; +using peg::list_type_content; +using peg::list_value; +using peg::list_value_content; +using peg::name; +using peg::named_type; +using peg::negative_sign; +using peg::nonnull_type; +using peg::nonzero_digit; +using peg::null_keyword; +using peg::object_field; +using peg::object_field_content; +using peg::object_field_name; +using peg::object_value; +using peg::object_value_content; +using peg::on_keyword; +using peg::operation_type; +using peg::quote_token; +using peg::sign; +using peg::source_character; +using peg::string_escape_sequence; +using peg::string_escape_sequence_content; +using peg::string_quote; +using peg::string_quote_character; +using peg::string_quote_content; +using peg::string_value; +using peg::true_keyword; +using peg::type_condition; +using peg::type_condition_content; +using peg::type_name; +using peg::type_name_content; +using peg::variable; +using peg::variable_content; +using peg::variable_definitions; +using peg::variable_definitions_content; +using peg::variable_name; +using peg::variable_name_content; +using peg::variable_value; +using peg::zero_digit; +using peg::fragement_spread_or_inline_fragment_content; +using peg::fragement_spread_or_inline_fragment; +using peg::operation_name; +using peg::selection; +using peg::selection_set; +using peg::selection_set_content; +using peg::operation_definition_operation_type_content; +using peg::arguments_definition; +using peg::arguments_definition_content; +using peg::arguments_definition_start; +using peg::description; +using peg::executable_definition; +using peg::field_definition; +using peg::field_definition_content; +using peg::field_definition_start; +using peg::fields_definition; +using peg::fields_definition_content; +using peg::fragment_definition; +using peg::fragment_definition_content; +using peg::implements_interfaces; +using peg::implements_interfaces_content; +using peg::interface_type; +using peg::object_name; +using peg::object_type_definition_object_name; +using peg::object_type_definition_start; +using peg::operation_definition; +using peg::root_operation_definition; +using peg::root_operation_definition_content; +using peg::scalar_keyword; +using peg::scalar_name; +using peg::scalar_type_definition; +using peg::scalar_type_definition_content; +using peg::scalar_type_definition_start; +using peg::schema_definition; +using peg::schema_definition_content; +using peg::schema_definition_start; +using peg::schema_keyword; +using peg::type_keyword; +using peg::object_type_definition_implements_interfaces; +using peg::interface_keyword; +using peg::interface_name; +using peg::interface_type_definition_interface_name; +using peg::interface_type_definition_start; +using peg::object_type_definition; +using peg::object_type_definition_content; +using peg::object_type_definition_directives; +using peg::object_type_definition_fields_definition; +using peg::interface_type_definition_implements_interfaces; +using peg::interface_type_definition_directives; +using peg::interface_type_definition_fields_definition; +using peg::enum_keyword; +using peg::enum_name; +using peg::enum_type_definition_directives; +using peg::enum_type_definition_name; +using peg::enum_type_definition_start; +using peg::enum_value_definition; +using peg::enum_value_definition_content; +using peg::enum_value_definition_start; +using peg::enum_values_definition; +using peg::enum_values_definition_content; +using peg::enum_values_definition_start; +using peg::interface_type_definition; +using peg::interface_type_definition_content; +using peg::union_keyword; +using peg::union_member_types; +using peg::union_member_types_content; +using peg::union_member_types_start; +using peg::union_name; +using peg::union_type; +using peg::union_type_definition; +using peg::union_type_definition_content; +using peg::union_type_definition_directives; +using peg::union_type_definition_start; +using peg::enum_type_definition_enum_values_definition; +using peg::enum_type_definition; +using peg::enum_type_definition_content; +using peg::input_field_definition; +using peg::input_field_definition_content; +using peg::input_field_definition_default_value; +using peg::input_field_definition_directives; +using peg::input_field_definition_start; +using peg::input_field_definition_type_name; +using peg::input_fields_definition; +using peg::input_fields_definition_content; +using peg::input_fields_definition_start; +using peg::input_keyword; +using peg::input_object_type_definition_directives; +using peg::input_object_type_definition_object_name; +using peg::input_object_type_definition_start; +using peg::input_object_type_definition_fields_definition; +using peg::directive_definition; +using peg::directive_definition_content; +using peg::directive_definition_start; +using peg::directive_location; +using peg::directive_locations; +using peg::executable_directive_location; +using peg::extend_keyword; +using peg::input_object_type_definition; +using peg::input_object_type_definition_content; +using peg::operation_type_definition; +using peg::repeatable_keyword; +using peg::schema_extension_start; +using peg::type_definition; +using peg::type_system_definition; +using peg::type_system_directive_location; +using peg::schema_extension_operation_type_definitions; +using peg::object_type_extension_start; +using peg::scalar_type_extension; +using peg::scalar_type_extension_content; +using peg::scalar_type_extension_start; +using peg::schema_extension; +using peg::schema_extension_content; +using peg::object_type_extension_implements_interfaces; +using peg::interface_type_extension_start; +using peg::object_type_extension; +using peg::object_type_extension_content; +using peg::object_type_extension_directives; +using peg::object_type_extension_fields_definition; +using peg::interface_type_extension_implements_interfaces; +using peg::interface_type_extension_directives; +using peg::interface_type_extension_fields_definition; +using peg::enum_type_extension; +using peg::enum_type_extension_content; +using peg::enum_type_extension_start; +using peg::executable_document; +using peg::executable_document_content; +using peg::input_object_type_extension; +using peg::input_object_type_extension_content; +using peg::input_object_type_extension_start; +using peg::interface_type_extension; +using peg::interface_type_extension_content; +using peg::mixed_definition; +using peg::mixed_document; +using peg::mixed_document_content; +using peg::schema_document; +using peg::schema_document_content; +using peg::schema_type_definition; +using peg::type_extension; +using peg::type_system_extension; +using peg::union_type_extension; +using peg::union_type_extension_content; +using peg::union_type_extension_start; +// clang-format on + +} // namespace graphql::peg diff --git a/include/graphqlservice/internal/Introspection.ixx b/include/graphqlservice/internal/Introspection.ixx new file mode 100644 index 00000000..3dab858d --- /dev/null +++ b/include/graphqlservice/internal/Introspection.ixx @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Introspection.h" + +export module GraphQL.Internal.Introspection; + +export namespace graphql::introspection { + +// clang-format off +using introspection::Schema; +using introspection::Type; +using introspection::Field; +using introspection::InputValue; +using introspection::EnumValue; +using introspection::Directive; +// clang-format on + +} // namespace graphql::introspection diff --git a/include/graphqlservice/internal/Schema.h b/include/graphqlservice/internal/Schema.h index bdc87926..6628a6f5 100644 --- a/include/graphqlservice/internal/Schema.h +++ b/include/graphqlservice/internal/Schema.h @@ -8,7 +8,6 @@ #include "DllExports.h" #include "SortedMap.h" -#include "Version.h" #include #include @@ -81,7 +80,7 @@ class [[nodiscard("unnecessary construction")]] Schema : public std::enable_shar std::shared_ptr _query; std::shared_ptr _mutation; std::shared_ptr _subscription; - internal::string_view_map _typeMap; + internal::string_view_map _typeMap; std::vector>> _types; std::vector> _directives; std::shared_mutex _nonNullWrappersMutex; diff --git a/include/graphqlservice/internal/Schema.ixx b/include/graphqlservice/internal/Schema.ixx new file mode 100644 index 00000000..19cf2ff3 --- /dev/null +++ b/include/graphqlservice/internal/Schema.ixx @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Schema.h" + +export module GraphQL.Internal.Schema; + +export namespace graphql { + +namespace introspection { + +// clang-format off +using introspection::TypeKind; +using introspection::DirectiveLocation; +// clang-format on + +} // namespace introspection + +namespace schema { + +// clang-format off +using schema::Schema; +using schema::BaseType; +using schema::ScalarType; +using schema::ObjectType; +using schema::InterfaceType; +using schema::UnionType; +using schema::EnumValueType; +using schema::EnumType; +using schema::InputObjectType; +using schema::WrapperType; +using schema::Field; +using schema::InputValue; +using schema::EnumValue; +using schema::Directive; +// clang-format on + +} // namespace schema + +} // namespace graphql diff --git a/include/graphqlservice/internal/SortedMap.h b/include/graphqlservice/internal/SortedMap.h index 50e49dec..7fbb39c6 100644 --- a/include/graphqlservice/internal/SortedMap.h +++ b/include/graphqlservice/internal/SortedMap.h @@ -7,6 +7,7 @@ #define GRAPHQLSORTEDMAP_H #include +#include #include #include #include @@ -67,7 +68,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map constexpr sorted_map() noexcept = default; constexpr sorted_map(const sorted_map& other) = default; - sorted_map(sorted_map && other) noexcept = default; + sorted_map(sorted_map&& other) noexcept = default; constexpr sorted_map(std::initializer_list> init) : _data { init } @@ -82,18 +83,18 @@ class [[nodiscard("unnecessary construction")]] sorted_map sorted_map& operator=(const sorted_map& rhs) = default; sorted_map& operator=(sorted_map&& rhs) noexcept = default; - [[nodiscard("unnecessary call")]] constexpr bool operator==(const sorted_map& rhs) - const noexcept + [[nodiscard("unnecessary call")]] constexpr bool operator==( + const sorted_map& rhs) const noexcept { return _data == rhs._data; } - void reserve(size_t size) + void reserve(std::size_t size) { _data.reserve(size); } - [[nodiscard("unnecessary call")]] constexpr size_t capacity() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t capacity() const noexcept { return _data.capacity(); } @@ -108,7 +109,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map return _data.empty(); } - [[nodiscard("unnecessary call")]] constexpr size_t size() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t size() const noexcept { return _data.size(); } @@ -141,7 +142,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - [[nodiscard("unnecessary call")]] constexpr const_iterator find(KeyArg && keyArg) const noexcept + [[nodiscard("unnecessary call")]] constexpr const_iterator find(KeyArg&& keyArg) const noexcept { const K key { std::forward(keyArg) }; @@ -149,7 +150,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - std::pair emplace(KeyArg && keyArg, ValueArgs && ... args) noexcept + std::pair emplace(KeyArg&& keyArg, ValueArgs&&... args) noexcept { K key { std::forward(keyArg) }; const auto [itr, itrEnd] = sorted_map_equal_range(_data.begin(), _data.end(), key); @@ -176,7 +177,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - const_iterator erase(KeyArg && keyArg) noexcept + const_iterator erase(KeyArg&& keyArg) noexcept { const K key { std::forward(keyArg) }; @@ -203,7 +204,7 @@ class [[nodiscard("unnecessary construction")]] sorted_map } template - [[nodiscard("unnecessary call")]] V& at(KeyArg && keyArg) + [[nodiscard("unnecessary call")]] V& at(KeyArg&& keyArg) { const K key { std::forward(keyArg) }; const auto [itr, itrEnd] = sorted_map_equal_range(_data.begin(), _data.end(), key); @@ -230,7 +231,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set constexpr sorted_set() noexcept = default; constexpr sorted_set(const sorted_set& other) = default; - sorted_set(sorted_set && other) noexcept = default; + sorted_set(sorted_set&& other) noexcept = default; constexpr sorted_set(std::initializer_list init) : _data { init } @@ -243,18 +244,18 @@ class [[nodiscard("unnecessary construction")]] sorted_set sorted_set& operator=(const sorted_set& rhs) = default; sorted_set& operator=(sorted_set&& rhs) noexcept = default; - [[nodiscard("unnecessary call")]] constexpr bool operator==(const sorted_set& rhs) - const noexcept + [[nodiscard("unnecessary call")]] constexpr bool operator==( + const sorted_set& rhs) const noexcept { return _data == rhs._data; } - void reserve(size_t size) + void reserve(std::size_t size) { _data.reserve(size); } - [[nodiscard("unnecessary call")]] constexpr size_t capacity() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t capacity() const noexcept { return _data.capacity(); } @@ -269,7 +270,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set return _data.empty(); } - [[nodiscard("unnecessary call")]] constexpr size_t size() const noexcept + [[nodiscard("unnecessary call")]] constexpr std::size_t size() const noexcept { return _data.size(); } @@ -304,7 +305,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - [[nodiscard("unnecessary call")]] constexpr const_iterator find(Arg && arg) const noexcept + [[nodiscard("unnecessary call")]] constexpr const_iterator find(Arg&& arg) const noexcept { const K key { std::forward(arg) }; @@ -312,7 +313,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - std::pair emplace(Arg && key) noexcept + std::pair emplace(Arg&& key) noexcept { const auto [itr, itrEnd] = std::equal_range(_data.begin(), _data.end(), key, [](K lhs, K rhs) noexcept { @@ -343,7 +344,7 @@ class [[nodiscard("unnecessary construction")]] sorted_set } template - const_iterator erase(Arg && arg) noexcept + const_iterator erase(Arg&& arg) noexcept { const K key { std::forward(arg) }; @@ -359,13 +360,14 @@ class [[nodiscard("unnecessary construction")]] sorted_set vector_type _data; }; -struct [[nodiscard("unnecessary construction")]] shorter_or_less { +struct [[nodiscard("unnecessary construction")]] shorter_or_less +{ [[nodiscard("unnecessary call")]] constexpr bool operator()( - std::string_view lhs, std::string_view rhs) - const noexcept { return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size(); -} // namespace graphql::internal -} -; + std::string_view lhs, std::string_view rhs) const noexcept + { + return lhs.size() == rhs.size() ? lhs < rhs : lhs.size() < rhs.size(); + } // namespace graphql::internal +}; template using string_view_map = sorted_map; diff --git a/include/graphqlservice/internal/SortedMap.ixx b/include/graphqlservice/internal/SortedMap.ixx new file mode 100644 index 00000000..156dd864 --- /dev/null +++ b/include/graphqlservice/internal/SortedMap.ixx @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "SortedMap.h" + +export module GraphQL.Internal.SortedMap; + +export namespace graphql::internal { + +// clang-format off +using internal::sorted_map_key; +using internal::sorted_map_equal_range; +using internal::sorted_map_lookup; +using internal::sorted_map; +using internal::sorted_set; +using internal::shorter_or_less; +using internal::string_view_map; +using internal::string_view_set; +// clang-format on + +} // namespace graphql::internal diff --git a/include/graphqlservice/internal/SyntaxTree.h b/include/graphqlservice/internal/SyntaxTree.h index fad8ef41..268eb544 100644 --- a/include/graphqlservice/internal/SyntaxTree.h +++ b/include/graphqlservice/internal/SyntaxTree.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -69,17 +70,17 @@ class [[nodiscard("unnecessary construction")]] ast_node : public parse_tree::ba } template - [[nodiscard("unnecessary call")]] static size_t type_hash() noexcept + [[nodiscard("unnecessary call")]] static std::size_t type_hash() noexcept { // This is cached in a static local variable per-specialization, but each module may have // its own instance of the specialization and the local variable. - static const size_t hash = std::hash {}(type_name()); + static const std::size_t hash = std::hash {}(type_name()); return hash; } std::string_view _type_name; - size_t _type_hash = 0; + std::size_t _type_hash = 0; using unescaped_t = std::variant; diff --git a/include/graphqlservice/internal/SyntaxTree.ixx b/include/graphqlservice/internal/SyntaxTree.ixx new file mode 100644 index 00000000..1fe4f213 --- /dev/null +++ b/include/graphqlservice/internal/SyntaxTree.ixx @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "SyntaxTree.h" + +export module GraphQL.Internal.SyntaxTree; + +export namespace graphql::peg { + +// clang-format off +using namespace tao::graphqlpeg; +namespace peginternal = tao::graphqlpeg::internal; + +using peg::ast_node; +// clang-format on + +} // namespace graphql::peg diff --git a/include/graphqlservice/internal/Version.h b/include/graphqlservice/internal/Version.h index 0009d7f2..8691f3b4 100644 --- a/include/graphqlservice/internal/Version.h +++ b/include/graphqlservice/internal/Version.h @@ -6,15 +6,20 @@ #ifndef GRAPHQLVERSION_H #define GRAPHQLVERSION_H +#include #include namespace graphql::internal { +inline namespace version { + constexpr std::string_view FullVersion { "4.5.8" }; -constexpr size_t MajorVersion = 4; -constexpr size_t MinorVersion = 5; -constexpr size_t PatchVersion = 8; +constexpr std::size_t MajorVersion = 4; +constexpr std::size_t MinorVersion = 5; +constexpr std::size_t PatchVersion = 8; + +} // namespace version } // namespace graphql::internal diff --git a/include/graphqlservice/internal/Version.ixx b/include/graphqlservice/internal/Version.ixx new file mode 100644 index 00000000..5fd825f0 --- /dev/null +++ b/include/graphqlservice/internal/Version.ixx @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "Version.h" + +export module GraphQL.Internal.Version; + +export namespace graphql::internal { + +// clang-format off +constexpr std::string_view FullVersion = version::FullVersion; + +constexpr std::size_t MajorVersion = version::MajorVersion; +constexpr std::size_t MinorVersion = version::MinorVersion; +constexpr std::size_t PatchVersion = version::PatchVersion; +// clang-format on + +} // namespace graphql::internal diff --git a/include/graphqlservice/introspection/DirectiveObject.ixx b/include/graphqlservice/introspection/DirectiveObject.ixx new file mode 100644 index 00000000..8a00c78d --- /dev/null +++ b/include/graphqlservice/introspection/DirectiveObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DirectiveObject.h" + +export module GraphQL.Introspection.DirectiveObject; + +export namespace graphql::introspection::object { + +using object::Directive; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/EnumValueObject.ixx b/include/graphqlservice/introspection/EnumValueObject.ixx new file mode 100644 index 00000000..45be5d13 --- /dev/null +++ b/include/graphqlservice/introspection/EnumValueObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "EnumValueObject.h" + +export module GraphQL.Introspection.EnumValueObject; + +export namespace graphql::introspection::object { + +using object::EnumValue; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/FieldObject.ixx b/include/graphqlservice/introspection/FieldObject.ixx new file mode 100644 index 00000000..aa5c8305 --- /dev/null +++ b/include/graphqlservice/introspection/FieldObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FieldObject.h" + +export module GraphQL.Introspection.FieldObject; + +export namespace graphql::introspection::object { + +using object::Field; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/InputValueObject.ixx b/include/graphqlservice/introspection/InputValueObject.ixx new file mode 100644 index 00000000..252760df --- /dev/null +++ b/include/graphqlservice/introspection/InputValueObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "InputValueObject.h" + +export module GraphQL.Introspection.InputValueObject; + +export namespace graphql::introspection::object { + +using object::InputValue; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/IntrospectionSchema.h b/include/graphqlservice/introspection/IntrospectionSchema.h index 363d67f2..b8e76fe3 100644 --- a/include/graphqlservice/introspection/IntrospectionSchema.h +++ b/include/graphqlservice/introspection/IntrospectionSchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace introspection { diff --git a/include/graphqlservice/introspection/IntrospectionSchema.ixx b/include/graphqlservice/introspection/IntrospectionSchema.ixx new file mode 100644 index 00000000..45f3f14a --- /dev/null +++ b/include/graphqlservice/introspection/IntrospectionSchema.ixx @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "IntrospectionSchema.h" + +export module GraphQL.Introspection.IntrospectionSchema; + +export import GraphQL.Introspection.SchemaObject; +export import GraphQL.Introspection.TypeObject; +export import GraphQL.Introspection.FieldObject; +export import GraphQL.Introspection.InputValueObject; +export import GraphQL.Introspection.EnumValueObject; +export import GraphQL.Introspection.DirectiveObject; + +export namespace graphql::introspection { + +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +using introspection::AddSchemaDetails; +using introspection::AddTypeDetails; +using introspection::AddFieldDetails; +using introspection::AddInputValueDetails; +using introspection::AddEnumValueDetails; +using introspection::AddDirectiveDetails; + +using introspection::AddTypesToSchema; + +} // namespace graphql::introspection diff --git a/include/graphqlservice/introspection/SchemaObject.ixx b/include/graphqlservice/introspection/SchemaObject.ixx new file mode 100644 index 00000000..56735d85 --- /dev/null +++ b/include/graphqlservice/introspection/SchemaObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SchemaObject.h" + +export module GraphQL.Introspection.SchemaObject; + +export namespace graphql::introspection::object { + +using object::Schema; + +} // namespace graphql::introspection::object diff --git a/include/graphqlservice/introspection/TypeObject.ixx b/include/graphqlservice/introspection/TypeObject.ixx new file mode 100644 index 00000000..001ccdd6 --- /dev/null +++ b/include/graphqlservice/introspection/TypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TypeObject.h" + +export module GraphQL.Introspection.TypeObject; + +export namespace graphql::introspection::object { + +using object::Type; + +} // namespace graphql::introspection::object diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 99131474..eff2f4ca 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -5,11 +5,14 @@ cmake_minimum_required(VERSION 3.28) add_subdirectory(client) add_subdirectory(learn) -add_subdirectory(today) add_subdirectory(validation) +if(GRAPHQL_BUILD_MODULES) + add_subdirectory(today) +endif() + if(GRAPHQL_BUILD_HTTP_SAMPLE) - find_package(Boost QUIET) + find_package(boost_beast CONFIG QUIET) if(Boost_FOUND) if(Boost_VERSION VERSION_GREATER_EQUAL "1.81.0") try_compile(TEST_RESULT diff --git a/samples/client/CMakeLists.txt b/samples/client/CMakeLists.txt index b5eb0d8a..a001c133 100644 --- a/samples/client/CMakeLists.txt +++ b/samples/client/CMakeLists.txt @@ -11,30 +11,32 @@ add_subdirectory(multiple) add_subdirectory(benchmark) -# client_benchmark -add_executable(client_benchmark benchmark.cpp) -target_link_libraries(client_benchmark PRIVATE - todaygraphql - benchmark_client) +if(GRAPHQL_BUILD_MODULES) + # client_benchmark + add_executable(client_benchmark benchmark.cpp) + target_link_libraries(client_benchmark PRIVATE + todaygraphql + benchmark_client) -if(WIN32 AND BUILD_SHARED_LIBS) - add_custom_command(OUTPUT copied_sample_dlls - COMMAND ${CMAKE_COMMAND} -E copy_if_different - $ - $ - $ - $ - $ - ${CMAKE_CURRENT_BINARY_DIR} - COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/copied_sample_dlls - DEPENDS - graphqlservice - graphqljson - graphqlpeg - graphqlresponse - graphqlclient) + if(WIN32 AND BUILD_SHARED_LIBS) + add_custom_command(OUTPUT copied_sample_dlls + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ + $ + $ + $ + $ + ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}/copied_sample_dlls + DEPENDS + graphqlservice + graphqljson + graphqlpeg + graphqlresponse + graphqlclient) - add_custom_target(copy_client_sample_dlls DEPENDS copied_sample_dlls) + add_custom_target(copy_client_sample_dlls DEPENDS copied_sample_dlls) - add_dependencies(client_benchmark copy_client_sample_dlls) + add_dependencies(client_benchmark copy_client_sample_dlls) + endif() endif() diff --git a/samples/client/benchmark.cpp b/samples/client/benchmark.cpp index 8e793a70..10c56b13 100644 --- a/samples/client/benchmark.cpp +++ b/samples/client/benchmark.cpp @@ -1,10 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "BenchmarkClient.h" -#include "TodayMock.h" - +#include #include +#include #include #include #include @@ -12,12 +11,19 @@ #include #include +import GraphQL.Client; +import GraphQL.Service; + +import GraphQL.Today.Mock; + +import GraphQL.Benchmark.BenchmarkClient; + using namespace graphql; using namespace std::literals; void outputOverview( - size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept + std::size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept { const auto requestsPerSecond = ((static_cast(iterations) @@ -60,14 +66,14 @@ void outputSegment( int main(int argc, char** argv) { - const size_t iterations = [](const char* arg) noexcept -> size_t { + const std::size_t iterations = [](const char* arg) noexcept -> std::size_t { if (arg) { const int parsed = std::atoi(arg); if (parsed > 0) { - return static_cast(parsed); + return static_cast(parsed); } } @@ -91,7 +97,7 @@ int main(int argc, char** argv) auto query = GetRequestObject(); const auto& name = GetOperationName(); - for (size_t i = 0; i < iterations; ++i) + for (std::size_t i = 0; i < iterations; ++i) { const auto startResolve = std::chrono::steady_clock::now(); auto response = service->resolve({ query, name }).get(); diff --git a/samples/client/benchmark/BenchmarkClient.cpp b/samples/client/benchmark/BenchmarkClient.cpp index b7c48d94..4ce3e7d6 100644 --- a/samples/client/benchmark/BenchmarkClient.cpp +++ b/samples/client/benchmark/BenchmarkClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/benchmark/BenchmarkClient.h b/samples/client/benchmark/BenchmarkClient.h index f7c4e41e..9ba57395 100644 --- a/samples/client/benchmark/BenchmarkClient.h +++ b/samples/client/benchmark/BenchmarkClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/benchmark/BenchmarkClient.ixx b/samples/client/benchmark/BenchmarkClient.ixx new file mode 100644 index 00000000..64b88c5b --- /dev/null +++ b/samples/client/benchmark/BenchmarkClient.ixx @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "BenchmarkClient.h" + +export module GraphQL.Benchmark.BenchmarkClient; + +export namespace graphql::client { + + +namespace benchmark { + +using benchmark::GetRequestText; +using benchmark::GetRequestObject; + +} // namespace benchmark + +namespace query::Query { + +using benchmark::GetRequestText; +using benchmark::GetRequestObject; +using Query::GetOperationName; + +using Query::Response; +using Query::parseResponse; + +using Query::Traits; + +} // namespace query::Query + +} // namespace graphql::client diff --git a/samples/client/multiple/MultipleQueriesClient.cpp b/samples/client/multiple/MultipleQueriesClient.cpp index ed6de3e3..5383da2f 100644 --- a/samples/client/multiple/MultipleQueriesClient.cpp +++ b/samples/client/multiple/MultipleQueriesClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -739,7 +740,7 @@ response::Value Variable::serialize(TaskState&& value) response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } diff --git a/samples/client/multiple/MultipleQueriesClient.h b/samples/client/multiple/MultipleQueriesClient.h index af157461..e57ad66d 100644 --- a/samples/client/multiple/MultipleQueriesClient.h +++ b/samples/client/multiple/MultipleQueriesClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/multiple/MultipleQueriesClient.ixx b/samples/client/multiple/MultipleQueriesClient.ixx new file mode 100644 index 00000000..f2b5ce2d --- /dev/null +++ b/samples/client/multiple/MultipleQueriesClient.ixx @@ -0,0 +1,100 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MultipleQueriesClient.h" + +export module GraphQL.MultipleQueries.MultipleQueriesClient; + +export namespace graphql::client { + + +namespace multiple { + +using multiple::GetRequestText; +using multiple::GetRequestObject; + +using multiple::TaskState; + +using multiple::CompleteTaskInput; + +} // namespace multiple + +namespace query::Appointments { + +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Appointments::GetOperationName; + +using Appointments::Response; +using Appointments::parseResponse; + +using Appointments::Traits; + +} // namespace query::Appointments + +namespace query::Tasks { + +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Tasks::GetOperationName; + +using Tasks::Response; +using Tasks::parseResponse; + +using Tasks::Traits; + +} // namespace query::Tasks + +namespace query::UnreadCounts { + +using multiple::GetRequestText; +using multiple::GetRequestObject; +using UnreadCounts::GetOperationName; + +using UnreadCounts::Response; +using UnreadCounts::parseResponse; + +using UnreadCounts::Traits; + +} // namespace query::UnreadCounts + +namespace query::Miscellaneous { + +using multiple::GetRequestText; +using multiple::GetRequestObject; +using Miscellaneous::GetOperationName; + +using multiple::TaskState; + +using Miscellaneous::Response; +using Miscellaneous::parseResponse; + +using Miscellaneous::Traits; + +} // namespace query::Miscellaneous + +namespace mutation::CompleteTaskMutation { + +using multiple::GetRequestText; +using multiple::GetRequestObject; +using CompleteTaskMutation::GetOperationName; + +using multiple::TaskState; + +using multiple::CompleteTaskInput; + +using CompleteTaskMutation::Variables; +using CompleteTaskMutation::serializeVariables; + +using CompleteTaskMutation::Response; +using CompleteTaskMutation::parseResponse; + +using CompleteTaskMutation::Traits; + +} // namespace mutation::CompleteTaskMutation + +} // namespace graphql::client diff --git a/samples/client/mutate/MutateClient.cpp b/samples/client/mutate/MutateClient.cpp index 027a03c9..019f2f43 100644 --- a/samples/client/mutate/MutateClient.cpp +++ b/samples/client/mutate/MutateClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -127,7 +128,7 @@ response::Value Variable::serialize(TaskState&& value) response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } diff --git a/samples/client/mutate/MutateClient.h b/samples/client/mutate/MutateClient.h index a2f304eb..2fbe3a4a 100644 --- a/samples/client/mutate/MutateClient.h +++ b/samples/client/mutate/MutateClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/mutate/MutateClient.ixx b/samples/client/mutate/MutateClient.ixx new file mode 100644 index 00000000..9c4579ee --- /dev/null +++ b/samples/client/mutate/MutateClient.ixx @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutateClient.h" + +export module GraphQL.Mutate.MutateClient; + +export namespace graphql::client { + + +namespace mutate { + +using mutate::GetRequestText; +using mutate::GetRequestObject; + +using mutate::TaskState; + +using mutate::CompleteTaskInput; + +} // namespace mutate + +namespace mutation::CompleteTaskMutation { + +using mutate::GetRequestText; +using mutate::GetRequestObject; +using CompleteTaskMutation::GetOperationName; + +using mutate::TaskState; + +using mutate::CompleteTaskInput; + +using CompleteTaskMutation::Variables; +using CompleteTaskMutation::serializeVariables; + +using CompleteTaskMutation::Response; +using CompleteTaskMutation::parseResponse; + +using CompleteTaskMutation::Traits; + +} // namespace mutation::CompleteTaskMutation + +} // namespace graphql::client diff --git a/samples/client/nestedinput/NestedInputClient.cpp b/samples/client/nestedinput/NestedInputClient.cpp index 2832d921..16708663 100644 --- a/samples/client/nestedinput/NestedInputClient.cpp +++ b/samples/client/nestedinput/NestedInputClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/nestedinput/NestedInputClient.h b/samples/client/nestedinput/NestedInputClient.h index 78eefa17..d3dd2db2 100644 --- a/samples/client/nestedinput/NestedInputClient.h +++ b/samples/client/nestedinput/NestedInputClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/nestedinput/NestedInputClient.ixx b/samples/client/nestedinput/NestedInputClient.ixx new file mode 100644 index 00000000..fe02a9a8 --- /dev/null +++ b/samples/client/nestedinput/NestedInputClient.ixx @@ -0,0 +1,48 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedInputClient.h" + +export module GraphQL.NestedInput.NestedInputClient; + +export namespace graphql::client { + + +namespace nestedinput { + +using nestedinput::GetRequestText; +using nestedinput::GetRequestObject; + +using nestedinput::InputA; +using nestedinput::InputB; +using nestedinput::InputABCD; +using nestedinput::InputBC; + +} // namespace nestedinput + +namespace query::testQuery { + +using nestedinput::GetRequestText; +using nestedinput::GetRequestObject; +using testQuery::GetOperationName; + +using nestedinput::InputA; +using nestedinput::InputB; +using nestedinput::InputABCD; +using nestedinput::InputBC; + +using testQuery::Variables; +using testQuery::serializeVariables; + +using testQuery::Response; +using testQuery::parseResponse; + +using testQuery::Traits; + +} // namespace query::testQuery + +} // namespace graphql::client diff --git a/samples/client/query/QueryClient.cpp b/samples/client/query/QueryClient.cpp index a5752587..61422c40 100644 --- a/samples/client/query/QueryClient.cpp +++ b/samples/client/query/QueryClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/query/QueryClient.h b/samples/client/query/QueryClient.h index fb89bcdd..109ddf5c 100644 --- a/samples/client/query/QueryClient.h +++ b/samples/client/query/QueryClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/query/QueryClient.ixx b/samples/client/query/QueryClient.ixx new file mode 100644 index 00000000..f4d077ef --- /dev/null +++ b/samples/client/query/QueryClient.ixx @@ -0,0 +1,39 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryClient.h" + +export module GraphQL.Query.QueryClient; + +export namespace graphql::client { + + +namespace query { + +using query::GetRequestText; +using query::GetRequestObject; + +using query::TaskState; + +} // namespace query + +namespace query::Query { + +using query::GetRequestText; +using query::GetRequestObject; +using Query::GetOperationName; + +using query::TaskState; + +using Query::Response; +using Query::parseResponse; + +using Query::Traits; + +} // namespace query::Query + +} // namespace graphql::client diff --git a/samples/client/subscribe/SubscribeClient.cpp b/samples/client/subscribe/SubscribeClient.cpp index 6cbcbe52..cf76839b 100644 --- a/samples/client/subscribe/SubscribeClient.cpp +++ b/samples/client/subscribe/SubscribeClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/client/subscribe/SubscribeClient.h b/samples/client/subscribe/SubscribeClient.h index 5d69e191..e01d433e 100644 --- a/samples/client/subscribe/SubscribeClient.h +++ b/samples/client/subscribe/SubscribeClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/client/subscribe/SubscribeClient.ixx b/samples/client/subscribe/SubscribeClient.ixx new file mode 100644 index 00000000..adeae8ed --- /dev/null +++ b/samples/client/subscribe/SubscribeClient.ixx @@ -0,0 +1,35 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscribeClient.h" + +export module GraphQL.Subscribe.SubscribeClient; + +export namespace graphql::client { + + +namespace subscribe { + +using subscribe::GetRequestText; +using subscribe::GetRequestObject; + +} // namespace subscribe + +namespace subscription::TestSubscription { + +using subscribe::GetRequestText; +using subscribe::GetRequestObject; +using TestSubscription::GetOperationName; + +using TestSubscription::Response; +using TestSubscription::parseResponse; + +using TestSubscription::Traits; + +} // namespace subscription::TestSubscription + +} // namespace graphql::client diff --git a/samples/learn/schema/CharacterObject.ixx b/samples/learn/schema/CharacterObject.ixx new file mode 100644 index 00000000..9917b823 --- /dev/null +++ b/samples/learn/schema/CharacterObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CharacterObject.h" + +export module GraphQL.StarWars.CharacterObject; + +export namespace graphql::learn::object { + +using object::Character; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/DroidObject.ixx b/samples/learn/schema/DroidObject.ixx new file mode 100644 index 00000000..166edcc7 --- /dev/null +++ b/samples/learn/schema/DroidObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DroidObject.h" + +export module GraphQL.StarWars.DroidObject; + +export namespace graphql::learn::object { + +using object::Droid; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/HumanObject.ixx b/samples/learn/schema/HumanObject.ixx new file mode 100644 index 00000000..9a218221 --- /dev/null +++ b/samples/learn/schema/HumanObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanObject.h" + +export module GraphQL.StarWars.HumanObject; + +export namespace graphql::learn::object { + +using object::Human; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/MutationObject.ixx b/samples/learn/schema/MutationObject.ixx new file mode 100644 index 00000000..1a2b2cba --- /dev/null +++ b/samples/learn/schema/MutationObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.StarWars.MutationObject; + +export namespace graphql::learn::object { + +using object::Mutation; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/QueryObject.ixx b/samples/learn/schema/QueryObject.ixx new file mode 100644 index 00000000..dfe464c1 --- /dev/null +++ b/samples/learn/schema/QueryObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.StarWars.QueryObject; + +export namespace graphql::learn::object { + +using object::Query; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/ReviewObject.ixx b/samples/learn/schema/ReviewObject.ixx new file mode 100644 index 00000000..067321d1 --- /dev/null +++ b/samples/learn/schema/ReviewObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ReviewObject.h" + +export module GraphQL.StarWars.ReviewObject; + +export namespace graphql::learn::object { + +using object::Review; + +} // namespace graphql::learn::object diff --git a/samples/learn/schema/StarWarsSchema.cpp b/samples/learn/schema/StarWarsSchema.cpp index c14d3696..a5d8e9e2 100644 --- a/samples/learn/schema/StarWarsSchema.cpp +++ b/samples/learn/schema/StarWarsSchema.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -55,7 +56,7 @@ service::AwaitableResolver Result::convert(service::AwaitableSca { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); + resolvedResult.set(std::string { s_namesEpisode[static_cast(value)] }); return resolvedResult; }); @@ -175,9 +176,9 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Mutation)gql"sv, typeMutation); typeEpisode->AddEnumValues({ - { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, - { service::s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } + { service::s_namesEpisode[static_cast(learn::Episode::NEW_HOPE)], R"md()md"sv, std::nullopt }, + { service::s_namesEpisode[static_cast(learn::Episode::EMPIRE)], R"md()md"sv, std::nullopt }, + { service::s_namesEpisode[static_cast(learn::Episode::JEDI)], R"md()md"sv, std::nullopt } }); typeReviewInput->AddInputValues({ diff --git a/samples/learn/schema/StarWarsSchema.h b/samples/learn/schema/StarWarsSchema.h index 2511eac0..43d229b4 100644 --- a/samples/learn/schema/StarWarsSchema.h +++ b/samples/learn/schema/StarWarsSchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace learn { diff --git a/samples/learn/schema/StarWarsSchema.ixx b/samples/learn/schema/StarWarsSchema.ixx new file mode 100644 index 00000000..45885809 --- /dev/null +++ b/samples/learn/schema/StarWarsSchema.ixx @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "StarWarsSchema.h" + +export module GraphQL.StarWars.StarWarsSchema; + +export import GraphQL.StarWars.CharacterObject; +export import GraphQL.StarWars.HumanObject; +export import GraphQL.StarWars.DroidObject; +export import GraphQL.StarWars.QueryObject; +export import GraphQL.StarWars.ReviewObject; +export import GraphQL.StarWars.MutationObject; + +export namespace graphql::learn { + +using learn::Episode; +using learn::getEpisodeNames; +using learn::getEpisodeValues; + +using learn::ReviewInput; + +using learn::Operations; + +using learn::AddCharacterDetails; +using learn::AddHumanDetails; +using learn::AddDroidDetails; +using learn::AddQueryDetails; +using learn::AddReviewDetails; +using learn::AddMutationDetails; + +using learn::GetSchema; + +} // namespace graphql::learn diff --git a/samples/proxy/query/ProxyClient.cpp b/samples/proxy/query/ProxyClient.cpp index fdf41b70..04b6546c 100644 --- a/samples/proxy/query/ProxyClient.cpp +++ b/samples/proxy/query/ProxyClient.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include diff --git a/samples/proxy/query/ProxyClient.h b/samples/proxy/query/ProxyClient.h index 73b15dee..6301f8e6 100644 --- a/samples/proxy/query/ProxyClient.h +++ b/samples/proxy/query/ProxyClient.h @@ -14,14 +14,14 @@ #include "graphqlservice/internal/Version.h" -// Check if the library version is compatible with clientgen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); - #include #include #include +// Check if the library version is compatible with clientgen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with clientgen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with clientgen: minor version mismatch"); + namespace graphql::client { /// diff --git a/samples/proxy/query/ProxyClient.ixx b/samples/proxy/query/ProxyClient.ixx new file mode 100644 index 00000000..65b38f32 --- /dev/null +++ b/samples/proxy/query/ProxyClient.ixx @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ProxyClient.h" + +export module GraphQL.Proxy.ProxyClient; + +export namespace graphql::client { + + +namespace proxy { + +using proxy::GetRequestText; +using proxy::GetRequestObject; + +} // namespace proxy + +namespace query::relayQuery { + +using proxy::GetRequestText; +using proxy::GetRequestObject; +using relayQuery::GetOperationName; + +using relayQuery::Variables; +using relayQuery::serializeVariables; + +using relayQuery::Response; +using relayQuery::parseResponse; + +using relayQuery::Traits; + +} // namespace query::relayQuery + +} // namespace graphql::client diff --git a/samples/proxy/schema/ProxySchema.cpp b/samples/proxy/schema/ProxySchema.cpp index 86781b95..e38783ba 100644 --- a/samples/proxy/schema/ProxySchema.cpp +++ b/samples/proxy/schema/ProxySchema.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include diff --git a/samples/proxy/schema/ProxySchema.h b/samples/proxy/schema/ProxySchema.h index eebe09e9..dbf732ba 100644 --- a/samples/proxy/schema/ProxySchema.h +++ b/samples/proxy/schema/ProxySchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace proxy { namespace object { diff --git a/samples/proxy/schema/ProxySchema.ixx b/samples/proxy/schema/ProxySchema.ixx new file mode 100644 index 00000000..a8d801b7 --- /dev/null +++ b/samples/proxy/schema/ProxySchema.ixx @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ProxySchema.h" + +export module GraphQL.Proxy.ProxySchema; + +namespace included = graphql::proxy; + +export namespace graphql::proxy { + +using proxy::Operations; + +using proxy::AddQueryDetails; + +using proxy::GetSchema; + +} // namespace graphql::proxy diff --git a/samples/proxy/schema/QueryObject.ixx b/samples/proxy/schema/QueryObject.ixx new file mode 100644 index 00000000..fcc61c1d --- /dev/null +++ b/samples/proxy/schema/QueryObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Proxy.QueryObject; + +export namespace graphql::proxy::object { + +using object::Query; + +} // namespace graphql::proxy::object diff --git a/samples/today/CMakeLists.txt b/samples/today/CMakeLists.txt index c3b9b2bb..9b6e1a6e 100644 --- a/samples/today/CMakeLists.txt +++ b/samples/today/CMakeLists.txt @@ -6,14 +6,30 @@ cmake_minimum_required(VERSION 3.28) # todaygraphql add_subdirectory(schema) add_library(todaygraphql STATIC TodayMock.cpp) +target_compile_features(todaygraphql PUBLIC cxx_std_20) target_link_libraries(todaygraphql PUBLIC today_schema) -target_include_directories(todaygraphql PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(todaygraphql PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(todaygraphql PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +endif() # todaygraphql_nointrospection add_subdirectory(nointrospection) add_library(todaygraphql_nointrospection STATIC TodayMock.cpp) +target_compile_features(todaygraphql_nointrospection PUBLIC cxx_std_20) target_link_libraries(todaygraphql_nointrospection PUBLIC today_nointrospection_schema) -target_include_directories(todaygraphql_nointrospection PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_sources(todaygraphql_nointrospection PUBLIC FILE_SET HEADERS + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(todaygraphql_nointrospection PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR} + FILES ${CMAKE_CURRENT_SOURCE_DIR}/TodayMock.ixx) +endif() if(MSVC) # warning C4702: unreachable code diff --git a/samples/today/TodayMock.cpp b/samples/today/TodayMock.cpp index 5e4a6ffd..53b0b35b 100644 --- a/samples/today/TodayMock.cpp +++ b/samples/today/TodayMock.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include @@ -106,7 +105,7 @@ std::unique_ptr mock_service() noexcept return result; } -RequestState::RequestState(size_t id) +RequestState::RequestState(std::size_t id) : requestId(id) { } @@ -477,7 +476,7 @@ auto operator co_await(std::chrono::duration<_Rep, _Period> delay) return true; } - void await_suspend(coro::coroutine_handle<> h) noexcept + void await_suspend(std::coroutine_handle<> h) noexcept { h.resume(); } @@ -845,16 +844,16 @@ std::shared_ptr Subscription::getNodeChange(const response::IdType throw std::runtime_error("Unexpected call to getNodeChange"); } -size_t NextAppointmentChange::_notifySubscribeCount = 0; -size_t NextAppointmentChange::_subscriptionCount = 0; -size_t NextAppointmentChange::_notifyUnsubscribeCount = 0; +std::size_t NextAppointmentChange::_notifySubscribeCount = 0; +std::size_t NextAppointmentChange::_subscriptionCount = 0; +std::size_t NextAppointmentChange::_notifyUnsubscribeCount = 0; NextAppointmentChange::NextAppointmentChange(nextAppointmentChange&& changeNextAppointment) : _changeNextAppointment(std::move(changeNextAppointment)) { } -size_t NextAppointmentChange::getCount(service::ResolverContext resolverContext) +std::size_t NextAppointmentChange::getCount(service::ResolverContext resolverContext) { switch (resolverContext) { @@ -963,9 +962,9 @@ std::stack NestedType::getCapturedParams() noexcept std::mutex Expensive::testMutex {}; std::mutex Expensive::pendingExpensiveMutex {}; std::condition_variable Expensive::pendingExpensiveCondition {}; -size_t Expensive::pendingExpensive = 0; +std::size_t Expensive::pendingExpensive = 0; -std::atomic Expensive::instances = 0; +std::atomic Expensive::instances = 0; bool Expensive::Reset() noexcept { diff --git a/samples/today/TodayMock.h b/samples/today/TodayMock.h index 6ed3a3c5..60f97fa1 100644 --- a/samples/today/TodayMock.h +++ b/samples/today/TodayMock.h @@ -34,26 +34,26 @@ const response::IdType& getFakeFolderId() noexcept; struct TodayMockService { std::shared_ptr service {}; - size_t getAppointmentsCount {}; - size_t getTasksCount {}; - size_t getUnreadCountsCount {}; + std::size_t getAppointmentsCount {}; + std::size_t getTasksCount {}; + std::size_t getUnreadCountsCount {}; }; std::unique_ptr mock_service() noexcept; struct RequestState : service::RequestState { - RequestState(size_t id); + RequestState(std::size_t id); - const size_t requestId; + const std::size_t requestId; - size_t appointmentsRequestId = 0; - size_t tasksRequestId = 0; - size_t unreadCountsRequestId = 0; + std::size_t appointmentsRequestId = 0; + std::size_t tasksRequestId = 0; + std::size_t unreadCountsRequestId = 0; - size_t loadAppointmentsCount = 0; - size_t loadTasksCount = 0; - size_t loadUnreadCountsCount = 0; + std::size_t loadAppointmentsCount = 0; + std::size_t loadTasksCount = 0; + std::size_t loadUnreadCountsCount = 0; }; class Appointment; @@ -318,7 +318,7 @@ class NextAppointmentChange explicit NextAppointmentChange(nextAppointmentChange&& changeNextAppointment); - static size_t getCount(service::ResolverContext resolverContext); + static std::size_t getCount(service::ResolverContext resolverContext); std::shared_ptr getNextAppointmentChange( const service::FieldParams& params) const; @@ -327,9 +327,9 @@ class NextAppointmentChange private: nextAppointmentChange _changeNextAppointment; - static size_t _notifySubscribeCount; - static size_t _subscriptionCount; - static size_t _notifyUnsubscribeCount; + static std::size_t _notifySubscribeCount; + static std::size_t _subscriptionCount; + static std::size_t _notifyUnsubscribeCount; }; class NodeChange @@ -388,20 +388,20 @@ class Expensive std::future getOrder(const service::FieldParams& params) const noexcept; - static constexpr size_t count = 5; + static constexpr std::size_t count = 5; static std::mutex testMutex; private: // Block async calls to getOrder until pendingExpensive == count static std::mutex pendingExpensiveMutex; static std::condition_variable pendingExpensiveCondition; - static size_t pendingExpensive; + static std::size_t pendingExpensive; // Number of instances - static std::atomic instances; + static std::atomic instances; // Initialized in the constructor - const size_t order; + const std::size_t order; }; class EmptyOperations : public service::Request diff --git a/samples/today/TodayMock.ixx b/samples/today/TodayMock.ixx new file mode 100644 index 00000000..3bd76425 --- /dev/null +++ b/samples/today/TodayMock.ixx @@ -0,0 +1,46 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +module; + +#include "TodayMock.h" + +export module GraphQL.Today.Mock; + +export import GraphQL.Today.TodaySchema; + +export namespace graphql::today { + +// clang-format off +using today::getFakeAppointmentId; +using today::getFakeTaskId; +using today::getFakeFolderId; + +using today::TodayMockService; +using today::mock_service; + +using today::RequestState; + +using today::Query; + +using today::PageInfo; +using today::Appointment; +using today::AppointmentEdge; +using today::Task; +using today::TaskEdge; +using today::TaskConnection; +using today::Folder; +using today::FolderEdge; +using today::FolderConnection; +using today::CompleteTaskPayload; +using today::Mutation; +using today::Subscription; +using today::NextAppointmentChange; +using today::NodeChange; +using today::CapturedParams; +using today::NestedType; +using today::Expensive; +using today::EmptyOperations; +// clang-format on + +} // namespace graphql::today diff --git a/samples/today/benchmark.cpp b/samples/today/benchmark.cpp index 20c4bde1..bec9c86d 100644 --- a/samples/today/benchmark.cpp +++ b/samples/today/benchmark.cpp @@ -1,10 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "TodayMock.h" - -#include "graphqlservice/JSONResponse.h" - +#include #include #include #include @@ -13,12 +10,18 @@ #include #include +import GraphQL.Parse; +import GraphQL.JSONResponse; +import GraphQL.Service; + +import GraphQL.Today.Mock; + using namespace graphql; using namespace std::literals; void outputOverview( - size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept + std::size_t iterations, const std::chrono::steady_clock::duration& totalDuration) noexcept { const auto requestsPerSecond = ((static_cast(iterations) @@ -61,14 +64,14 @@ void outputSegment( int main(int argc, char** argv) { - const size_t iterations = [](const char* arg) noexcept -> size_t { + const std::size_t iterations = [](const char* arg) noexcept -> std::size_t { if (arg) { const int parsed = std::atoi(arg); if (parsed > 0) { - return static_cast(parsed); + return static_cast(parsed); } } @@ -88,7 +91,7 @@ int main(int argc, char** argv) try { - for (size_t i = 0; i < iterations; ++i) + for (std::size_t i = 0; i < iterations; ++i) { const auto startParse = std::chrono::steady_clock::now(); auto query = peg::parseString(R"gql(query { diff --git a/samples/today/nointrospection/AppointmentConnectionObject.ixx b/samples/today/nointrospection/AppointmentConnectionObject.ixx new file mode 100644 index 00000000..ec982810 --- /dev/null +++ b/samples/today/nointrospection/AppointmentConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentConnectionObject.h" + +export module GraphQL.Today.AppointmentConnectionObject; + +export namespace graphql::today::object { + +using object::AppointmentConnection; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentEdgeObject.ixx b/samples/today/nointrospection/AppointmentEdgeObject.ixx new file mode 100644 index 00000000..8d283bf9 --- /dev/null +++ b/samples/today/nointrospection/AppointmentEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentEdgeObject.h" + +export module GraphQL.Today.AppointmentEdgeObject; + +export namespace graphql::today::object { + +using object::AppointmentEdge; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/AppointmentObject.ixx b/samples/today/nointrospection/AppointmentObject.ixx new file mode 100644 index 00000000..34131b4b --- /dev/null +++ b/samples/today/nointrospection/AppointmentObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentObject.h" + +export module GraphQL.Today.AppointmentObject; + +export namespace graphql::today::object { + +using object::Appointment; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/CompleteTaskPayloadObject.ixx b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx new file mode 100644 index 00000000..fe9415d9 --- /dev/null +++ b/samples/today/nointrospection/CompleteTaskPayloadObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CompleteTaskPayloadObject.h" + +export module GraphQL.Today.CompleteTaskPayloadObject; + +export namespace graphql::today::object { + +using object::CompleteTaskPayload; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/ExpensiveObject.ixx b/samples/today/nointrospection/ExpensiveObject.ixx new file mode 100644 index 00000000..00bf65f4 --- /dev/null +++ b/samples/today/nointrospection/ExpensiveObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ExpensiveObject.h" + +export module GraphQL.Today.ExpensiveObject; + +export namespace graphql::today::object { + +using object::Expensive; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderConnectionObject.ixx b/samples/today/nointrospection/FolderConnectionObject.ixx new file mode 100644 index 00000000..d5434681 --- /dev/null +++ b/samples/today/nointrospection/FolderConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderConnectionObject.h" + +export module GraphQL.Today.FolderConnectionObject; + +export namespace graphql::today::object { + +using object::FolderConnection; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderEdgeObject.ixx b/samples/today/nointrospection/FolderEdgeObject.ixx new file mode 100644 index 00000000..6a6fdf26 --- /dev/null +++ b/samples/today/nointrospection/FolderEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderEdgeObject.h" + +export module GraphQL.Today.FolderEdgeObject; + +export namespace graphql::today::object { + +using object::FolderEdge; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/FolderObject.ixx b/samples/today/nointrospection/FolderObject.ixx new file mode 100644 index 00000000..ca0ee0a7 --- /dev/null +++ b/samples/today/nointrospection/FolderObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderObject.h" + +export module GraphQL.Today.FolderObject; + +export namespace graphql::today::object { + +using object::Folder; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/MutationObject.ixx b/samples/today/nointrospection/MutationObject.ixx new file mode 100644 index 00000000..1f20b3b3 --- /dev/null +++ b/samples/today/nointrospection/MutationObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Today.MutationObject; + +export namespace graphql::today::object { + +using object::Mutation; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/NestedTypeObject.ixx b/samples/today/nointrospection/NestedTypeObject.ixx new file mode 100644 index 00000000..15db6dc2 --- /dev/null +++ b/samples/today/nointrospection/NestedTypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedTypeObject.h" + +export module GraphQL.Today.NestedTypeObject; + +export namespace graphql::today::object { + +using object::NestedType; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/NodeObject.ixx b/samples/today/nointrospection/NodeObject.ixx new file mode 100644 index 00000000..89446202 --- /dev/null +++ b/samples/today/nointrospection/NodeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Today.NodeObject; + +export namespace graphql::today::object { + +using object::Node; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/PageInfoObject.ixx b/samples/today/nointrospection/PageInfoObject.ixx new file mode 100644 index 00000000..ecb6ce42 --- /dev/null +++ b/samples/today/nointrospection/PageInfoObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PageInfoObject.h" + +export module GraphQL.Today.PageInfoObject; + +export namespace graphql::today::object { + +using object::PageInfo; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/QueryObject.ixx b/samples/today/nointrospection/QueryObject.ixx new file mode 100644 index 00000000..84d3715c --- /dev/null +++ b/samples/today/nointrospection/QueryObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Today.QueryObject; + +export namespace graphql::today::object { + +using object::Query; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/SubscriptionObject.ixx b/samples/today/nointrospection/SubscriptionObject.ixx new file mode 100644 index 00000000..d84fdbd8 --- /dev/null +++ b/samples/today/nointrospection/SubscriptionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Today.SubscriptionObject; + +export namespace graphql::today::object { + +using object::Subscription; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskConnectionObject.ixx b/samples/today/nointrospection/TaskConnectionObject.ixx new file mode 100644 index 00000000..8225fa7f --- /dev/null +++ b/samples/today/nointrospection/TaskConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskConnectionObject.h" + +export module GraphQL.Today.TaskConnectionObject; + +export namespace graphql::today::object { + +using object::TaskConnection; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskEdgeObject.ixx b/samples/today/nointrospection/TaskEdgeObject.ixx new file mode 100644 index 00000000..bdf2bba7 --- /dev/null +++ b/samples/today/nointrospection/TaskEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskEdgeObject.h" + +export module GraphQL.Today.TaskEdgeObject; + +export namespace graphql::today::object { + +using object::TaskEdge; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TaskObject.ixx b/samples/today/nointrospection/TaskObject.ixx new file mode 100644 index 00000000..dcf0d814 --- /dev/null +++ b/samples/today/nointrospection/TaskObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskObject.h" + +export module GraphQL.Today.TaskObject; + +export namespace graphql::today::object { + +using object::Task; + +} // namespace graphql::today::object diff --git a/samples/today/nointrospection/TodaySchema.cpp b/samples/today/nointrospection/TodaySchema.cpp index aee07aac..4dd8886a 100644 --- a/samples/today/nointrospection/TodaySchema.cpp +++ b/samples/today/nointrospection/TodaySchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); return resolvedResult; }); @@ -802,10 +803,10 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ diff --git a/samples/today/nointrospection/TodaySchema.h b/samples/today/nointrospection/TodaySchema.h index ef18f867..8128495e 100644 --- a/samples/today/nointrospection/TodaySchema.h +++ b/samples/today/nointrospection/TodaySchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace today { diff --git a/samples/today/nointrospection/TodaySchema.ixx b/samples/today/nointrospection/TodaySchema.ixx new file mode 100644 index 00000000..7bfef47c --- /dev/null +++ b/samples/today/nointrospection/TodaySchema.ixx @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySchema.h" + +export module GraphQL.Today.TodaySchema; + +export import GraphQL.Today.NodeObject; +export import GraphQL.Today.UnionTypeObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.PageInfoObject; +export import GraphQL.Today.AppointmentEdgeObject; +export import GraphQL.Today.AppointmentConnectionObject; +export import GraphQL.Today.TaskEdgeObject; +export import GraphQL.Today.TaskConnectionObject; +export import GraphQL.Today.FolderEdgeObject; +export import GraphQL.Today.FolderConnectionObject; +export import GraphQL.Today.CompleteTaskPayloadObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; +export import GraphQL.Today.AppointmentObject; +export import GraphQL.Today.TaskObject; +export import GraphQL.Today.FolderObject; +export import GraphQL.Today.NestedTypeObject; +export import GraphQL.Today.ExpensiveObject; + +export namespace graphql::today { + +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +using today::Operations; + +using today::AddNodeDetails; +using today::AddUnionTypeDetails; +using today::AddQueryDetails; +using today::AddPageInfoDetails; +using today::AddAppointmentEdgeDetails; +using today::AddAppointmentConnectionDetails; +using today::AddTaskEdgeDetails; +using today::AddTaskConnectionDetails; +using today::AddFolderEdgeDetails; +using today::AddFolderConnectionDetails; +using today::AddCompleteTaskPayloadDetails; +using today::AddMutationDetails; +using today::AddSubscriptionDetails; +using today::AddAppointmentDetails; +using today::AddTaskDetails; +using today::AddFolderDetails; +using today::AddNestedTypeDetails; +using today::AddExpensiveDetails; + +using today::GetSchema; + +} // namespace graphql::today diff --git a/samples/today/nointrospection/UnionTypeObject.ixx b/samples/today/nointrospection/UnionTypeObject.ixx new file mode 100644 index 00000000..bfd588fd --- /dev/null +++ b/samples/today/nointrospection/UnionTypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "UnionTypeObject.h" + +export module GraphQL.Today.UnionTypeObject; + +export namespace graphql::today::object { + +using object::UnionType; + +} // namespace graphql::today::object diff --git a/samples/today/sample.cpp b/samples/today/sample.cpp index e47f6bda..e4a313bd 100644 --- a/samples/today/sample.cpp +++ b/samples/today/sample.cpp @@ -1,20 +1,22 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. -#include "TodayMock.h" - -#include "graphqlservice/JSONResponse.h" - #include #include #include #include +import GraphQL.Parse; +import GraphQL.JSONResponse; +import GraphQL.Service; + +import GraphQL.Today.Mock; + using namespace graphql; int main(int argc, char** argv) { - const auto mockService = today::mock_service(); + const auto mockService = graphql::today::mock_service(); const auto& service = mockService->service; std::cout << "Created the service..." << std::endl; diff --git a/samples/today/schema/AppointmentConnectionObject.ixx b/samples/today/schema/AppointmentConnectionObject.ixx new file mode 100644 index 00000000..ec982810 --- /dev/null +++ b/samples/today/schema/AppointmentConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentConnectionObject.h" + +export module GraphQL.Today.AppointmentConnectionObject; + +export namespace graphql::today::object { + +using object::AppointmentConnection; + +} // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentEdgeObject.ixx b/samples/today/schema/AppointmentEdgeObject.ixx new file mode 100644 index 00000000..8d283bf9 --- /dev/null +++ b/samples/today/schema/AppointmentEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentEdgeObject.h" + +export module GraphQL.Today.AppointmentEdgeObject; + +export namespace graphql::today::object { + +using object::AppointmentEdge; + +} // namespace graphql::today::object diff --git a/samples/today/schema/AppointmentObject.ixx b/samples/today/schema/AppointmentObject.ixx new file mode 100644 index 00000000..34131b4b --- /dev/null +++ b/samples/today/schema/AppointmentObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AppointmentObject.h" + +export module GraphQL.Today.AppointmentObject; + +export namespace graphql::today::object { + +using object::Appointment; + +} // namespace graphql::today::object diff --git a/samples/today/schema/CompleteTaskPayloadObject.ixx b/samples/today/schema/CompleteTaskPayloadObject.ixx new file mode 100644 index 00000000..fe9415d9 --- /dev/null +++ b/samples/today/schema/CompleteTaskPayloadObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CompleteTaskPayloadObject.h" + +export module GraphQL.Today.CompleteTaskPayloadObject; + +export namespace graphql::today::object { + +using object::CompleteTaskPayload; + +} // namespace graphql::today::object diff --git a/samples/today/schema/ExpensiveObject.ixx b/samples/today/schema/ExpensiveObject.ixx new file mode 100644 index 00000000..00bf65f4 --- /dev/null +++ b/samples/today/schema/ExpensiveObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ExpensiveObject.h" + +export module GraphQL.Today.ExpensiveObject; + +export namespace graphql::today::object { + +using object::Expensive; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderConnectionObject.ixx b/samples/today/schema/FolderConnectionObject.ixx new file mode 100644 index 00000000..d5434681 --- /dev/null +++ b/samples/today/schema/FolderConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderConnectionObject.h" + +export module GraphQL.Today.FolderConnectionObject; + +export namespace graphql::today::object { + +using object::FolderConnection; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderEdgeObject.ixx b/samples/today/schema/FolderEdgeObject.ixx new file mode 100644 index 00000000..6a6fdf26 --- /dev/null +++ b/samples/today/schema/FolderEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderEdgeObject.h" + +export module GraphQL.Today.FolderEdgeObject; + +export namespace graphql::today::object { + +using object::FolderEdge; + +} // namespace graphql::today::object diff --git a/samples/today/schema/FolderObject.ixx b/samples/today/schema/FolderObject.ixx new file mode 100644 index 00000000..ca0ee0a7 --- /dev/null +++ b/samples/today/schema/FolderObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FolderObject.h" + +export module GraphQL.Today.FolderObject; + +export namespace graphql::today::object { + +using object::Folder; + +} // namespace graphql::today::object diff --git a/samples/today/schema/MutationObject.ixx b/samples/today/schema/MutationObject.ixx new file mode 100644 index 00000000..1f20b3b3 --- /dev/null +++ b/samples/today/schema/MutationObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Today.MutationObject; + +export namespace graphql::today::object { + +using object::Mutation; + +} // namespace graphql::today::object diff --git a/samples/today/schema/NestedTypeObject.ixx b/samples/today/schema/NestedTypeObject.ixx new file mode 100644 index 00000000..15db6dc2 --- /dev/null +++ b/samples/today/schema/NestedTypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NestedTypeObject.h" + +export module GraphQL.Today.NestedTypeObject; + +export namespace graphql::today::object { + +using object::NestedType; + +} // namespace graphql::today::object diff --git a/samples/today/schema/NodeObject.ixx b/samples/today/schema/NodeObject.ixx new file mode 100644 index 00000000..89446202 --- /dev/null +++ b/samples/today/schema/NodeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Today.NodeObject; + +export namespace graphql::today::object { + +using object::Node; + +} // namespace graphql::today::object diff --git a/samples/today/schema/PageInfoObject.ixx b/samples/today/schema/PageInfoObject.ixx new file mode 100644 index 00000000..ecb6ce42 --- /dev/null +++ b/samples/today/schema/PageInfoObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PageInfoObject.h" + +export module GraphQL.Today.PageInfoObject; + +export namespace graphql::today::object { + +using object::PageInfo; + +} // namespace graphql::today::object diff --git a/samples/today/schema/QueryObject.ixx b/samples/today/schema/QueryObject.ixx new file mode 100644 index 00000000..84d3715c --- /dev/null +++ b/samples/today/schema/QueryObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Today.QueryObject; + +export namespace graphql::today::object { + +using object::Query; + +} // namespace graphql::today::object diff --git a/samples/today/schema/SubscriptionObject.ixx b/samples/today/schema/SubscriptionObject.ixx new file mode 100644 index 00000000..d84fdbd8 --- /dev/null +++ b/samples/today/schema/SubscriptionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Today.SubscriptionObject; + +export namespace graphql::today::object { + +using object::Subscription; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskConnectionObject.ixx b/samples/today/schema/TaskConnectionObject.ixx new file mode 100644 index 00000000..8225fa7f --- /dev/null +++ b/samples/today/schema/TaskConnectionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskConnectionObject.h" + +export module GraphQL.Today.TaskConnectionObject; + +export namespace graphql::today::object { + +using object::TaskConnection; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskEdgeObject.ixx b/samples/today/schema/TaskEdgeObject.ixx new file mode 100644 index 00000000..bdf2bba7 --- /dev/null +++ b/samples/today/schema/TaskEdgeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskEdgeObject.h" + +export module GraphQL.Today.TaskEdgeObject; + +export namespace graphql::today::object { + +using object::TaskEdge; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TaskObject.ixx b/samples/today/schema/TaskObject.ixx new file mode 100644 index 00000000..dcf0d814 --- /dev/null +++ b/samples/today/schema/TaskObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TaskObject.h" + +export module GraphQL.Today.TaskObject; + +export namespace graphql::today::object { + +using object::Task; + +} // namespace graphql::today::object diff --git a/samples/today/schema/TodaySchema.cpp b/samples/today/schema/TodaySchema.cpp index d11e9e23..27cd44ce 100644 --- a/samples/today/schema/TodaySchema.cpp +++ b/samples/today/schema/TodaySchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::AwaitableS { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTaskState[static_cast(value)] }); return resolvedResult; }); @@ -805,10 +806,10 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Expensive)gql"sv, typeExpensive); typeTaskState->AddEnumValues({ - { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, - { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, - { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } + { service::s_namesTaskState[static_cast(today::TaskState::Unassigned)], R"md()md"sv, std::make_optional(R"md(Need to deprecate an [enum value](https://spec.graphql.org/October2021/#sec-Schema-Introspection.Deprecation))md"sv) }, + { service::s_namesTaskState[static_cast(today::TaskState::New)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Started)], R"md()md"sv, std::nullopt }, + { service::s_namesTaskState[static_cast(today::TaskState::Complete)], R"md()md"sv, std::nullopt } }); typeCompleteTaskInput->AddInputValues({ diff --git a/samples/today/schema/TodaySchema.h b/samples/today/schema/TodaySchema.h index ef18f867..8128495e 100644 --- a/samples/today/schema/TodaySchema.h +++ b/samples/today/schema/TodaySchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace today { diff --git a/samples/today/schema/TodaySchema.ixx b/samples/today/schema/TodaySchema.ixx new file mode 100644 index 00000000..7bfef47c --- /dev/null +++ b/samples/today/schema/TodaySchema.ixx @@ -0,0 +1,70 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TodaySchema.h" + +export module GraphQL.Today.TodaySchema; + +export import GraphQL.Today.NodeObject; +export import GraphQL.Today.UnionTypeObject; +export import GraphQL.Today.QueryObject; +export import GraphQL.Today.PageInfoObject; +export import GraphQL.Today.AppointmentEdgeObject; +export import GraphQL.Today.AppointmentConnectionObject; +export import GraphQL.Today.TaskEdgeObject; +export import GraphQL.Today.TaskConnectionObject; +export import GraphQL.Today.FolderEdgeObject; +export import GraphQL.Today.FolderConnectionObject; +export import GraphQL.Today.CompleteTaskPayloadObject; +export import GraphQL.Today.MutationObject; +export import GraphQL.Today.SubscriptionObject; +export import GraphQL.Today.AppointmentObject; +export import GraphQL.Today.TaskObject; +export import GraphQL.Today.FolderObject; +export import GraphQL.Today.NestedTypeObject; +export import GraphQL.Today.ExpensiveObject; + +export namespace graphql::today { + +using today::TaskState; +using today::getTaskStateNames; +using today::getTaskStateValues; + +using today::CompleteTaskInput; +using today::ThirdNestedInput; +using today::FourthNestedInput; +using today::IncludeNullableSelfInput; +using today::IncludeNonNullableListSelfInput; +using today::StringOperationFilterInput; +using today::SecondNestedInput; +using today::ForwardDeclaredInput; +using today::FirstNestedInput; + +using today::Operations; + +using today::AddNodeDetails; +using today::AddUnionTypeDetails; +using today::AddQueryDetails; +using today::AddPageInfoDetails; +using today::AddAppointmentEdgeDetails; +using today::AddAppointmentConnectionDetails; +using today::AddTaskEdgeDetails; +using today::AddTaskConnectionDetails; +using today::AddFolderEdgeDetails; +using today::AddFolderConnectionDetails; +using today::AddCompleteTaskPayloadDetails; +using today::AddMutationDetails; +using today::AddSubscriptionDetails; +using today::AddAppointmentDetails; +using today::AddTaskDetails; +using today::AddFolderDetails; +using today::AddNestedTypeDetails; +using today::AddExpensiveDetails; + +using today::GetSchema; + +} // namespace graphql::today diff --git a/samples/today/schema/UnionTypeObject.ixx b/samples/today/schema/UnionTypeObject.ixx new file mode 100644 index 00000000..bfd588fd --- /dev/null +++ b/samples/today/schema/UnionTypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "UnionTypeObject.h" + +export module GraphQL.Today.UnionTypeObject; + +export namespace graphql::today::object { + +using object::UnionType; + +} // namespace graphql::today::object diff --git a/samples/validation/schema/AlienObject.ixx b/samples/validation/schema/AlienObject.ixx new file mode 100644 index 00000000..54db3153 --- /dev/null +++ b/samples/validation/schema/AlienObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "AlienObject.h" + +export module GraphQL.Validation.AlienObject; + +export namespace graphql::validation::object { + +using object::Alien; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ArgumentsObject.ixx b/samples/validation/schema/ArgumentsObject.ixx new file mode 100644 index 00000000..dc4502c7 --- /dev/null +++ b/samples/validation/schema/ArgumentsObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ArgumentsObject.h" + +export module GraphQL.Validation.ArgumentsObject; + +export namespace graphql::validation::object { + +using object::Arguments; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/CatObject.ixx b/samples/validation/schema/CatObject.ixx new file mode 100644 index 00000000..74415bca --- /dev/null +++ b/samples/validation/schema/CatObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CatObject.h" + +export module GraphQL.Validation.CatObject; + +export namespace graphql::validation::object { + +using object::Cat; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/CatOrDogObject.ixx b/samples/validation/schema/CatOrDogObject.ixx new file mode 100644 index 00000000..ed07b094 --- /dev/null +++ b/samples/validation/schema/CatOrDogObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "CatOrDogObject.h" + +export module GraphQL.Validation.CatOrDogObject; + +export namespace graphql::validation::object { + +using object::CatOrDog; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/DogObject.ixx b/samples/validation/schema/DogObject.ixx new file mode 100644 index 00000000..14b6f3e8 --- /dev/null +++ b/samples/validation/schema/DogObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DogObject.h" + +export module GraphQL.Validation.DogObject; + +export namespace graphql::validation::object { + +using object::Dog; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/DogOrHumanObject.ixx b/samples/validation/schema/DogOrHumanObject.ixx new file mode 100644 index 00000000..e301fe5b --- /dev/null +++ b/samples/validation/schema/DogOrHumanObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DogOrHumanObject.h" + +export module GraphQL.Validation.DogOrHumanObject; + +export namespace graphql::validation::object { + +using object::DogOrHuman; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanObject.ixx b/samples/validation/schema/HumanObject.ixx new file mode 100644 index 00000000..cc70f3ce --- /dev/null +++ b/samples/validation/schema/HumanObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanObject.h" + +export module GraphQL.Validation.HumanObject; + +export namespace graphql::validation::object { + +using object::Human; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/HumanOrAlienObject.ixx b/samples/validation/schema/HumanOrAlienObject.ixx new file mode 100644 index 00000000..8deb8777 --- /dev/null +++ b/samples/validation/schema/HumanOrAlienObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "HumanOrAlienObject.h" + +export module GraphQL.Validation.HumanOrAlienObject; + +export namespace graphql::validation::object { + +using object::HumanOrAlien; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MessageObject.ixx b/samples/validation/schema/MessageObject.ixx new file mode 100644 index 00000000..3ee9c892 --- /dev/null +++ b/samples/validation/schema/MessageObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MessageObject.h" + +export module GraphQL.Validation.MessageObject; + +export namespace graphql::validation::object { + +using object::Message; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MutateDogResultObject.ixx b/samples/validation/schema/MutateDogResultObject.ixx new file mode 100644 index 00000000..fb8915c7 --- /dev/null +++ b/samples/validation/schema/MutateDogResultObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutateDogResultObject.h" + +export module GraphQL.Validation.MutateDogResultObject; + +export namespace graphql::validation::object { + +using object::MutateDogResult; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/MutationObject.ixx b/samples/validation/schema/MutationObject.ixx new file mode 100644 index 00000000..3e61de52 --- /dev/null +++ b/samples/validation/schema/MutationObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "MutationObject.h" + +export module GraphQL.Validation.MutationObject; + +export namespace graphql::validation::object { + +using object::Mutation; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/NodeObject.ixx b/samples/validation/schema/NodeObject.ixx new file mode 100644 index 00000000..f3d91fde --- /dev/null +++ b/samples/validation/schema/NodeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "NodeObject.h" + +export module GraphQL.Validation.NodeObject; + +export namespace graphql::validation::object { + +using object::Node; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/PetObject.ixx b/samples/validation/schema/PetObject.ixx new file mode 100644 index 00000000..9c77c197 --- /dev/null +++ b/samples/validation/schema/PetObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "PetObject.h" + +export module GraphQL.Validation.PetObject; + +export namespace graphql::validation::object { + +using object::Pet; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/QueryObject.ixx b/samples/validation/schema/QueryObject.ixx new file mode 100644 index 00000000..f25b794a --- /dev/null +++ b/samples/validation/schema/QueryObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "QueryObject.h" + +export module GraphQL.Validation.QueryObject; + +export namespace graphql::validation::object { + +using object::Query; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ResourceObject.ixx b/samples/validation/schema/ResourceObject.ixx new file mode 100644 index 00000000..6fd30498 --- /dev/null +++ b/samples/validation/schema/ResourceObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ResourceObject.h" + +export module GraphQL.Validation.ResourceObject; + +export namespace graphql::validation::object { + +using object::Resource; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/SentientObject.ixx b/samples/validation/schema/SentientObject.ixx new file mode 100644 index 00000000..9793549c --- /dev/null +++ b/samples/validation/schema/SentientObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SentientObject.h" + +export module GraphQL.Validation.SentientObject; + +export namespace graphql::validation::object { + +using object::Sentient; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/SubscriptionObject.ixx b/samples/validation/schema/SubscriptionObject.ixx new file mode 100644 index 00000000..db16c987 --- /dev/null +++ b/samples/validation/schema/SubscriptionObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SubscriptionObject.h" + +export module GraphQL.Validation.SubscriptionObject; + +export namespace graphql::validation::object { + +using object::Subscription; + +} // namespace graphql::validation::object diff --git a/samples/validation/schema/ValidationSchema.cpp b/samples/validation/schema/ValidationSchema.cpp index 9a49b7e7..40410c97 100644 --- a/samples/validation/schema/ValidationSchema.cpp +++ b/samples/validation/schema/ValidationSchema.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -56,7 +57,7 @@ service::AwaitableResolver Result::convert(service::Awai { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); + resolvedResult.set(std::string { s_namesDogCommand[static_cast(value)] }); return resolvedResult; }); @@ -112,7 +113,7 @@ service::AwaitableResolver Result::convert(service::Awai { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); + resolvedResult.set(std::string { s_namesCatCommand[static_cast(value)] }); return resolvedResult; }); @@ -258,12 +259,12 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(Arguments)gql"sv, typeArguments); typeDogCommand->AddEnumValues({ - { service::s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, - { service::s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } + { service::s_namesDogCommand[static_cast(validation::DogCommand::SIT)], R"md()md"sv, std::nullopt }, + { service::s_namesDogCommand[static_cast(validation::DogCommand::DOWN)], R"md()md"sv, std::nullopt }, + { service::s_namesDogCommand[static_cast(validation::DogCommand::HEEL)], R"md()md"sv, std::nullopt } }); typeCatCommand->AddEnumValues({ - { service::s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } + { service::s_namesCatCommand[static_cast(validation::CatCommand::JUMP)], R"md()md"sv, std::nullopt } }); typeComplexInput->AddInputValues({ diff --git a/samples/validation/schema/ValidationSchema.h b/samples/validation/schema/ValidationSchema.h index 66208163..980bba28 100644 --- a/samples/validation/schema/ValidationSchema.h +++ b/samples/validation/schema/ValidationSchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace validation { diff --git a/samples/validation/schema/ValidationSchema.ixx b/samples/validation/schema/ValidationSchema.ixx new file mode 100644 index 00000000..0501c3ec --- /dev/null +++ b/samples/validation/schema/ValidationSchema.ixx @@ -0,0 +1,64 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "ValidationSchema.h" + +export module GraphQL.Validation.ValidationSchema; + +export import GraphQL.Validation.SentientObject; +export import GraphQL.Validation.PetObject; +export import GraphQL.Validation.NodeObject; +export import GraphQL.Validation.ResourceObject; +export import GraphQL.Validation.CatOrDogObject; +export import GraphQL.Validation.DogOrHumanObject; +export import GraphQL.Validation.HumanOrAlienObject; +export import GraphQL.Validation.QueryObject; +export import GraphQL.Validation.DogObject; +export import GraphQL.Validation.AlienObject; +export import GraphQL.Validation.HumanObject; +export import GraphQL.Validation.CatObject; +export import GraphQL.Validation.MutationObject; +export import GraphQL.Validation.MutateDogResultObject; +export import GraphQL.Validation.SubscriptionObject; +export import GraphQL.Validation.MessageObject; +export import GraphQL.Validation.ArgumentsObject; + +export namespace graphql::validation { + +using validation::DogCommand; +using validation::getDogCommandNames; +using validation::getDogCommandValues; + +using validation::CatCommand; +using validation::getCatCommandNames; +using validation::getCatCommandValues; + +using validation::ComplexInput; + +using validation::Operations; + +using validation::AddSentientDetails; +using validation::AddPetDetails; +using validation::AddNodeDetails; +using validation::AddResourceDetails; +using validation::AddCatOrDogDetails; +using validation::AddDogOrHumanDetails; +using validation::AddHumanOrAlienDetails; +using validation::AddQueryDetails; +using validation::AddDogDetails; +using validation::AddAlienDetails; +using validation::AddHumanDetails; +using validation::AddCatDetails; +using validation::AddMutationDetails; +using validation::AddMutateDogResultDetails; +using validation::AddSubscriptionDetails; +using validation::AddMessageDetails; +using validation::AddArgumentsDetails; + +using validation::GetSchema; + +} // namespace graphql::validation diff --git a/src/Base64.cpp b/src/Base64.cpp index 94e571f5..b40bc6ee 100644 --- a/src/Base64.cpp +++ b/src/Base64.cpp @@ -4,6 +4,7 @@ #include "graphqlservice/internal/Base64.h" #include +#include #include namespace graphql::internal { @@ -111,7 +112,7 @@ std::string Base64::toBase64(const std::vector& bytes) return result; } - size_t count = bytes.size(); + std::size_t count = bytes.size(); const std::uint8_t* data = bytes.data(); result.reserve((count + (count % 3)) * 4 / 3); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6bab8b34..64d1d21f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -71,60 +71,79 @@ function(add_bigobj_flag target) endif() endfunction() -add_library(graphqlcoro INTERFACE) -target_compile_features(graphqlcoro INTERFACE cxx_std_20) - -function(check_coroutine_impl COROUTINE_HEADER COROUTINE_NAMESPACE OPTIONAL_FLAGS OUT_RESULT) - set(TEST_FILE "test_${OUT_RESULT}.cpp") - configure_file(${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_coroutine.cpp.in ${TEST_FILE} @ONLY) - - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - CXX_STANDARD 20) - - if(NOT TEST_RESULT) - # Retry with each of the optional flags. - foreach(OPTIONAL_FLAG IN LISTS OPTIONAL_FLAGS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - CMAKE_FLAGS "-DCOMPILE_DEFINITIONS:STRING=${OPTIONAL_FLAG}" - CXX_STANDARD 20) - - if(TEST_RESULT) - # Looks like the optional flag was required, go ahead and add it to the compile options. - target_compile_options(graphqlcoro INTERFACE ${OPTIONAL_FLAG}) - break() - endif() - endforeach(OPTIONAL_FLAG) - endif() - - set(${OUT_RESULT} ${TEST_RESULT} PARENT_SCOPE) -endfunction() +file(REAL_PATH ../include/ INCLUDE_ROOT) + +# graphql_internal_modules +add_library(graphql_internal_modules OBJECT) +add_library(cppgraphqlgen::graphql_internal_modules ALIAS graphql_internal_modules) +set_target_properties(graphql_internal_modules PROPERTIES LINKER_LANGUAGE CXX) +target_compile_features(graphql_internal_modules PUBLIC cxx_std_20) +target_link_libraries(graphql_internal_modules PUBLIC taocpp::pegtl) +target_include_directories(graphql_internal_modules PUBLIC + $ + $) +target_sources(graphql_internal_modules PUBLIC FILE_SET HEADERS + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.h + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.h + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.h + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.h + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.h + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.h + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.h + ${INCLUDE_ROOT}/graphqlservice/internal/Version.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphql_internal_modules PUBLIC FILE_SET CXX_MODULES + BASE_DIRS + ${INCLUDE_ROOT} + FILES + ${INCLUDE_ROOT}/graphqlservice/internal/Awaitable.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Base64.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Grammar.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Introspection.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Schema.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SortedMap.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/SyntaxTree.ixx + ${INCLUDE_ROOT}/graphqlservice/internal/Version.ixx) +endif() -check_coroutine_impl("coroutine" "std" "-fcoroutines" STD_COROUTINE) -if(STD_COROUTINE) - message(STATUS "Using std coroutine") -else() - check_coroutine_impl("experimental/coroutine" "std::experimental" "" STD_EXPERIMENTAL_COROUTINE) - if(STD_EXPERIMENTAL_COROUTINE) - message(STATUS "Using std::experimental coroutine") - target_compile_definitions(graphqlcoro INTERFACE USE_STD_EXPERIMENTAL_COROUTINE) - else() - message(FATAL_ERROR "Missing coroutine support") - endif() +# graphql_introspection_modules +add_library(graphql_introspection_modules OBJECT) +add_library(cppgraphqlgen::graphql_introspection_modules ALIAS graphql_introspection_modules) +set_target_properties(graphql_introspection_modules PROPERTIES LINKER_LANGUAGE CXX) +target_compile_features(graphql_introspection_modules PUBLIC cxx_std_20) +target_link_libraries(graphql_introspection_modules PUBLIC taocpp::pegtl) +target_include_directories(graphql_introspection_modules PUBLIC + $ + $) +file(GLOB INTROSPECTION_HEADERS ${INCLUDE_ROOT}/graphqlservice/introspection/*.h) +target_sources(graphql_introspection_modules PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INTROSPECTION_HEADERS}) +if(GRAPHQL_BUILD_MODULES) + file(GLOB INTROSPECTION_MODULES ${INCLUDE_ROOT}/graphqlservice/introspection/*.ixx) + target_sources(graphql_introspection_modules PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INTROSPECTION_MODULES}) endif() # graphqlpeg add_library(graphqlpeg SyntaxTree.cpp) add_library(cppgraphqlgen::graphqlpeg ALIAS graphqlpeg) -target_link_libraries(graphqlpeg PUBLIC - graphqlcoro - taocpp::pegtl) +target_compile_features(graphqlpeg PUBLIC cxx_std_20) +target_link_libraries(graphqlpeg PUBLIC taocpp::pegtl) +target_sources(graphqlpeg PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLParse.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlpeg PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Parse.ixx) +endif() target_include_directories(graphqlpeg PUBLIC $ - $ $) add_bigobj_flag(graphqlpeg) @@ -145,10 +164,19 @@ add_library(graphqlresponse Base64.cpp GraphQLResponse.cpp) add_library(cppgraphqlgen::graphqlresponse ALIAS graphqlresponse) +target_compile_features(graphqlresponse PUBLIC cxx_std_20) target_include_directories(graphqlresponse PUBLIC $ $) -target_link_libraries(graphqlresponse PUBLIC graphqlcoro) +target_link_libraries(graphqlresponse PUBLIC graphql_internal_modules) +target_sources(graphqlresponse PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLResponse.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlresponse PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Response.ixx) +endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlresponse) @@ -168,6 +196,7 @@ if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) SchemaLoader.cpp GeneratorLoader.cpp GeneratorUtil.cpp) + target_compile_features(generator_util PUBLIC cxx_std_20) target_link_libraries(generator_util PUBLIC graphqlpeg graphqlresponse) @@ -271,44 +300,9 @@ if(GRAPHQL_BUILD_SCHEMAGEN) RUNTIME DESTINATION ${GRAPHQL_INSTALL_TOOLS_DIR}/${PROJECT_NAME}) endif() -# Common schemagen and clientgen filesystem and Boost dependencies +# Common schemagen and clientgen Boost dependencies if(GRAPHQL_BUILD_SCHEMAGEN OR GRAPHQL_BUILD_CLIENTGEN) - # Try compiling a test program with std::filesystem or one of its alternatives. - function(check_filesystem_impl OPTIONAL_LIBS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/test_filesystem.cpp - CXX_STANDARD 20) - - if(NOT TEST_RESULT) - # Retry with each of the optional libraries. - foreach(OPTIONAL_LIB IN LISTS OPTIONAL_LIBS) - try_compile(TEST_RESULT - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/${TEST_FILE} - LINK_LIBRARIES ${OPTIONAL_LIB} - CXX_STANDARD 20) - - if(TEST_RESULT) - # Looks like the optional library was required, go ahead and add it to the link options. - if(GRAPHQL_BUILD_SCHEMAGEN) - target_link_libraries(schemagen PRIVATE ${OPTIONAL_LIB}) - endif() - if(GRAPHQL_BUILD_CLIENTGEN) - target_link_libraries(clientgen PRIVATE ${OPTIONAL_LIB}) - endif() - break() - endif() - endforeach(OPTIONAL_LIB) - endif() - endfunction(check_filesystem_impl) - - # Try compiling a minimal program without any extra libraries, then with each optional library until it succeeded: - # stdc++fs - # c++fs - check_filesystem_impl("stdc++fs;c++fs" STD_FILESYTEM) - - find_package(Boost QUIET REQUIRED COMPONENTS program_options) + find_package(boost_program_options CONFIG REQUIRED) if(GRAPHQL_BUILD_SCHEMAGEN) target_link_libraries(schemagen PRIVATE Boost::program_options) endif() @@ -329,10 +323,21 @@ add_library(graphqlservice Introspection.cpp ${INTROSPECTION_SCHEMA_FILES}) add_library(cppgraphqlgen::graphqlservice ALIAS graphqlservice) +target_compile_features(graphqlservice PUBLIC cxx_std_20) target_link_libraries(graphqlservice PUBLIC + graphql_internal_modules + graphql_introspection_modules graphqlpeg graphqlresponse Threads::Threads) +target_sources(graphqlservice PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLService.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlservice PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Service.ixx) +endif() if(GRAPHQL_UPDATE_SAMPLES) add_dependencies(graphqlservice copy_introspection_schema_headers) @@ -357,9 +362,18 @@ endif() # graphqlclient add_library(graphqlclient GraphQLClient.cpp) add_library(cppgraphqlgen::graphqlclient ALIAS graphqlclient) +target_compile_features(graphqlclient PUBLIC cxx_std_20) target_link_libraries(graphqlclient PUBLIC graphqlpeg graphqlresponse) +target_sources(graphqlclient PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/GraphQLClient.h) +if(GRAPHQL_BUILD_MODULES) + target_sources(graphqlclient PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/Client.ixx) +endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqlclient) @@ -385,8 +399,17 @@ if(GRAPHQL_USE_RAPIDJSON) set(BUILD_GRAPHQLJSON ON) add_library(graphqljson JSONResponse.cpp) add_library(cppgraphqlgen::graphqljson ALIAS graphqljson) + target_compile_features(graphqljson PUBLIC cxx_std_20) target_link_libraries(graphqljson PUBLIC graphqlresponse) target_include_directories(graphqljson SYSTEM PRIVATE ${RAPIDJSON_INCLUDE_DIRS}) + target_sources(graphqljson PUBLIC FILE_SET HEADERS + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/JSONResponse.h) + if(GRAPHQL_BUILD_MODULES) + target_sources(graphqljson PUBLIC FILE_SET CXX_MODULES + BASE_DIRS ${INCLUDE_ROOT} + FILES ${INCLUDE_ROOT}/graphqlservice/JSONResponse.ixx) + endif() if(GRAPHQL_UPDATE_VERSION) update_version_rc(graphqljson) @@ -402,35 +425,34 @@ if(GRAPHQL_USE_RAPIDJSON) endif() install(TARGETS + graphql_internal_modules + graphql_introspection_modules graphqlclient graphqlpeg - graphqlcoro graphqlresponse graphqlservice EXPORT cppgraphqlgen-targets RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLClient.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLParse.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLResponse.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/GraphQLService.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice) - -install(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Awaitable.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Base64.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Grammar.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Introspection.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Schema.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/SortedMap.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/SyntaxTree.h - ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/internal/Version.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice/internal) + LIBRARY DESTINATION lib + FILE_SET HEADERS + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR} + FILE_SET CXX_MODULES + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) + +if(WIN32 AND BUILD_SHARED_LIBS) + install(TARGETS + graphqlpeg_version + graphqlresponse_version + graphqlservice_version + graphqlclient_version + graphqljson_version + EXPORT cppgraphqlgen-targets + ARCHIVE DESTINATION lib + LIBRARY DESTINATION lib) +endif() # graphqljson if(BUILD_GRAPHQLJSON) @@ -440,10 +462,13 @@ if(BUILD_GRAPHQLJSON) EXPORT cppgraphqlgen-targets RUNTIME DESTINATION bin ARCHIVE DESTINATION lib - LIBRARY DESTINATION lib) - install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../include/graphqlservice/JSONResponse.h - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice) + LIBRARY DESTINATION lib + FILE_SET HEADERS + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR} + FILE_SET CXX_MODULES + CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} + DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}) else() set(GRAPHQL_BUILD_TESTS OFF CACHE BOOL "GRAPHQL_BUILD_TESTS depends on BUILD_GRAPHQLJSON" FORCE) endif() diff --git a/src/ClientGenerator.cpp b/src/ClientGenerator.cpp index 1a747ec5..e3bca07d 100644 --- a/src/ClientGenerator.cpp +++ b/src/ClientGenerator.cpp @@ -5,7 +5,6 @@ #include "GeneratorUtil.h" #include "graphqlservice/internal/Version.h" - #include "graphqlservice/introspection/IntrospectionSchema.h" #ifdef _MSC_VER @@ -20,6 +19,7 @@ #pragma warning(pop) #endif // _MSC_VER +#include #include #include #include @@ -40,6 +40,7 @@ Generator::Generator( , _headerDir(getHeaderDir()) , _sourceDir(getSourceDir()) , _headerPath(getHeaderPath()) + , _modulePath(getModulePath()) , _sourcePath(getSourcePath()) { } @@ -77,6 +78,15 @@ std::string Generator::getHeaderPath() const noexcept return fullPath.string(); } +std::string Generator::getModulePath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _schemaLoader.getFilenamePrefix() } + "Client.ixx"); + + return fullPath.string(); +} + std::string Generator::getSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; @@ -156,6 +166,11 @@ std::vector Generator::Build() const noexcept builtFiles.push_back(_headerPath); } + if (outputModule() && _options.verbose) + { + builtFiles.push_back(_modulePath); + } + if (outputSource()) { builtFiles.push_back(_sourcePath); @@ -176,6 +191,10 @@ bool Generator::outputHeader() const noexcept #include "graphqlservice/internal/Version.h" +#include +#include +#include + // Check if the library version is compatible with clientgen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 @@ -186,10 +205,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with clientgen: minor version mismatch"); -#include -#include -#include - )cpp"; PendingBlankLine pendingSeparator { headerFile }; @@ -531,7 +546,7 @@ void Generator::outputGetOperationNameDeclaration(std::ostream& headerFile) cons } bool Generator::outputResponseFieldType(std::ostream& headerFile, - const ResponseField& responseField, size_t indent /* = 0 */) const noexcept + const ResponseField& responseField, std::size_t indent /* = 0 */) const noexcept { switch (responseField.type->kind()) { @@ -601,6 +616,188 @@ bool Generator::outputResponseFieldType(std::ostream& headerFile, return true; } +bool Generator::outputModule() const noexcept +{ + std::ofstream moduleFile(_modulePath, std::ios_base::trunc); + std::ostringstream ossNamespace; + + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << _schemaLoader.getFilenamePrefix() + << + R"cpp(Client.h" + +export module GraphQL.)cpp" + << _schemaLoader.getFilenamePrefix() << R"cpp(.)cpp" + << _schemaLoader.getFilenamePrefix() << + R"cpp(Client; + +export )cpp"; + + NamespaceScope graphqlNamespace { moduleFile, getClientNamespace() }; + + moduleFile << std::endl; + + NamespaceScope schemaNamespace { moduleFile, _schemaLoader.getSchemaNamespace(), true }; + PendingBlankLine pendingSeparator { moduleFile }; + + pendingSeparator.reset(); + if (schemaNamespace.enter()) + { + moduleFile << R"cpp( +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestText; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestObject; +)cpp"; + pendingSeparator.add(); + } + + const auto& operations = _requestLoader.getOperations(); + std::unordered_set declaredEnum; + + for (const auto& operation : operations) + { + if (!_requestLoader.getReferencedEnums(operation).empty()) + { + pendingSeparator.reset(); + + // Define all of the enums referenced either in variables or the response. + for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) + { + const auto cppType = _schemaLoader.getCppType(enumType->name()); + + if (!declaredEnum.insert(cppType).second) + { + continue; + } + + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << cppType << R"cpp(; +)cpp"; + } + } + } + + if (!declaredEnum.empty()) + { + pendingSeparator.add(); + } + + std::unordered_set declaredInput; + std::unordered_set forwardDeclaredInput; + + for (const auto& operation : operations) + { + if (!_requestLoader.getReferencedInputTypes(operation).empty()) + { + pendingSeparator.reset(); + + // Define all of the input object structs referenced in variables. + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + { + const auto cppType = _schemaLoader.getCppType(inputType.type->name()); + + if (!declaredInput.insert(cppType).second) + { + continue; + } + + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::)cpp" << cppType << R"cpp(; +)cpp"; + } + } + } + + if (!declaredInput.empty()) + { + pendingSeparator.add(); + } + + pendingSeparator.reset(); + if (schemaNamespace.exit()) + { + pendingSeparator.add(); + } + + for (const auto& operation : operations) + { + pendingSeparator.reset(); + + NamespaceScope operationNamespaceScope { moduleFile, getOperationNamespace(operation) }; + const auto operationNamespace = _requestLoader.getOperationNamespace(operation); + + moduleFile << R"cpp( +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestText; +using )cpp" << _schemaLoader.getSchemaNamespace() + << R"cpp(::GetRequestObject; +using )cpp" << operationNamespace + << R"cpp(::GetOperationName; + +)cpp"; + + // Alias all of the enums referenced either in variables or the response. + for (const auto& enumType : _requestLoader.getReferencedEnums(operation)) + { + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" + << _schemaLoader.getCppType(enumType->name()) << R"cpp(; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + // Alias all of the input object structs referenced in variables. + for (const auto& inputType : _requestLoader.getReferencedInputTypes(operation)) + { + moduleFile << R"cpp(using )cpp" << _schemaLoader.getSchemaNamespace() << R"cpp(::)cpp" + << _schemaLoader.getCppType(inputType.type->name()) << R"cpp(; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + const auto& variables = _requestLoader.getVariables(operation); + + if (!variables.empty()) + { + moduleFile << R"cpp(using )cpp" << operationNamespace << R"cpp(::Variables; +using )cpp" << operationNamespace + << R"cpp(::serializeVariables; +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + moduleFile << R"cpp(using )cpp" << operationNamespace << R"cpp(::Response; +using )cpp" << operationNamespace + << R"cpp(::parseResponse; + +using )cpp" << operationNamespace + << R"cpp(::Traits; + +)cpp"; + + pendingSeparator.add(); + } + + pendingSeparator.reset(); + + return true; +} + bool Generator::outputSource() const noexcept { std::ofstream sourceFile(_sourcePath, std::ios_base::trunc); @@ -617,6 +814,7 @@ bool Generator::outputSource() const noexcept #include #include +#include #include #include #include @@ -846,7 +1044,7 @@ response::Value Variable<)cpp" response::Value result { response::Type::EnumValue }; - result.set(std::string { s_names[static_cast(value)] }); + result.set(std::string { s_names[static_cast(value)] }); return result; } @@ -1448,9 +1646,9 @@ int main(int argc, char** argv) for (const auto& segment : error.path) { - if (std::holds_alternative(segment)) + if (std::holds_alternative(segment)) { - std::cerr << '[' << std::get(segment) << ']'; + std::cerr << '[' << std::get(segment) << ']'; } else { diff --git a/src/GraphQLClient.cpp b/src/GraphQLClient.cpp index df616f21..f56b0a24 100644 --- a/src/GraphQLClient.cpp +++ b/src/GraphQLClient.cpp @@ -3,6 +3,8 @@ #include "graphqlservice/GraphQLClient.h" +#include + using namespace std::literals; namespace graphql::client { @@ -21,7 +23,7 @@ ErrorLocation parseServiceErrorLocation(response::Value&& location) { if (member.second.type() == response::Type::Int) { - result.line = static_cast(member.second.get()); + result.line = static_cast(member.second.get()); } continue; @@ -31,7 +33,7 @@ ErrorLocation parseServiceErrorLocation(response::Value&& location) { if (member.second.type() == response::Type::Int) { - result.column = static_cast(member.second.get()); + result.column = static_cast(member.second.get()); } continue; diff --git a/src/GraphQLResponse.cpp b/src/GraphQLResponse.cpp index 4036d628..25b4ba56 100644 --- a/src/GraphQLResponse.cpp +++ b/src/GraphQLResponse.cpp @@ -6,11 +6,16 @@ #include "graphqlservice/internal/Base64.h" #include +#include +#include #include #include #include #include +#include +#include #include +#include namespace graphql::response { @@ -31,7 +36,7 @@ IdType::~IdType() // omitted, declare it explicitly and define it in graphqlresponse. } -IdType::IdType(size_t count, typename ByteData::value_type value /* = 0 */) +IdType::IdType(std::size_t count, typename ByteData::value_type value /* = 0 */) : _data { ByteData(count, value) } { } @@ -95,9 +100,9 @@ bool IdType::operator==(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? internal::Base64::compareBase64(std::get(_data), - std::get(rhs._data)) + std::get(rhs._data)) : internal::Base64::compareBase64(std::get(rhs._data), - std::get(_data))) + std::get(_data))) == internal::Base64::Comparison::EqualTo; } @@ -140,7 +145,7 @@ bool IdType::operator<(const IdType& rhs) const noexcept return (std::holds_alternative(_data) ? (internal::Base64::compareBase64(std::get(_data), std::get(rhs._data)) - < internal::Base64::Comparison::EqualTo) + < internal::Base64::Comparison::EqualTo) : (internal::Base64::compareBase64(std::get(rhs._data), std::get(_data))) > internal::Base64::Comparison::EqualTo); @@ -161,7 +166,7 @@ bool IdType::empty() const noexcept _data); } -size_t IdType::size() const noexcept +std::size_t IdType::size() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -170,7 +175,7 @@ size_t IdType::size() const noexcept _data); } -size_t IdType::max_size() const noexcept +std::size_t IdType::max_size() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -179,7 +184,7 @@ size_t IdType::max_size() const noexcept _data); } -void IdType::reserve(size_t new_cap) +void IdType::reserve(std::size_t new_cap) { std::visit( [new_cap](auto& data) { @@ -188,7 +193,7 @@ void IdType::reserve(size_t new_cap) _data); } -size_t IdType::capacity() const noexcept +std::size_t IdType::capacity() const noexcept { return std::visit( [](const auto& data) noexcept { @@ -215,7 +220,7 @@ void IdType::clear() noexcept _data); } -const std::uint8_t& IdType::at(size_t pos) const +const std::uint8_t& IdType::at(std::size_t pos) const { if (!std::holds_alternative(_data)) { @@ -225,7 +230,7 @@ const std::uint8_t& IdType::at(size_t pos) const return std::get(_data).at(pos); } -std::uint8_t& IdType::at(size_t pos) +std::uint8_t& IdType::at(std::size_t pos) { if (!std::holds_alternative(_data)) { @@ -235,7 +240,7 @@ std::uint8_t& IdType::at(size_t pos) return std::get(_data).at(pos); } -const std::uint8_t& IdType::operator[](size_t pos) const +const std::uint8_t& IdType::operator[](std::size_t pos) const { if (!std::holds_alternative(_data)) { @@ -245,7 +250,7 @@ const std::uint8_t& IdType::operator[](size_t pos) const return std::get(_data)[pos]; } -std::uint8_t& IdType::operator[](size_t pos) +std::uint8_t& IdType::operator[](std::size_t pos) { if (!std::holds_alternative(_data)) { @@ -1003,7 +1008,7 @@ Value::Value(const Value& other) copy.map.push_back({ entry.first, Value { entry.second } }); } - std::map members; + std::map members; for (const auto& entry : copy.map) { @@ -1027,7 +1032,7 @@ Value::Value(const Value& other) ListType copy {}; copy.reserve(other.size()); - for (size_t i = 0; i < other.size(); ++i) + for (std::size_t i = 0; i < other.size(); ++i) { copy.push_back(Value { other[i] }); } @@ -1090,38 +1095,40 @@ Type Value::typeOf(const TypeData& data) noexcept // As long as the order of the variant alternatives matches the Type enum, we can cast the index // to the Type in one step. static_assert( - std::is_same_v(Type::Map), TypeData>, + std::is_same_v(Type::Map), TypeData>, MapData>, "type mistmatch"); static_assert( - std::is_same_v(Type::List), TypeData>, + std::is_same_v(Type::List), TypeData>, ListType>, "type mistmatch"); static_assert( - std::is_same_v(Type::String), TypeData>, + std::is_same_v(Type::String), TypeData>, StringData>, "type mistmatch"); - static_assert( - std::is_same_v(Type::Boolean), TypeData>, - BooleanType>, + static_assert(std::is_same_v< + std::variant_alternative_t(Type::Boolean), TypeData>, + BooleanType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Int), TypeData>, + std::is_same_v(Type::Int), TypeData>, IntType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Float), TypeData>, + std::is_same_v(Type::Float), TypeData>, FloatType>, "type mistmatch"); static_assert( - std::is_same_v(Type::EnumValue), TypeData>, + std::is_same_v< + std::variant_alternative_t(Type::EnumValue), TypeData>, EnumData>, "type mistmatch"); static_assert( - std::is_same_v(Type::ID), TypeData>, IdType>, + std::is_same_v(Type::ID), TypeData>, + IdType>, "type mistmatch"); static_assert( - std::is_same_v(Type::Scalar), TypeData>, + std::is_same_v(Type::Scalar), TypeData>, ScalarData>, "type mistmatch"); @@ -1270,7 +1277,7 @@ bool Value::maybe_id() const noexcept return false; } -void Value::reserve(size_t count) +void Value::reserve(std::size_t count) { if (std::holds_alternative(_data)) { @@ -1299,7 +1306,7 @@ void Value::reserve(size_t count) } } -size_t Value::size() const +std::size_t Value::size() const { switch (type()) { @@ -1334,7 +1341,7 @@ bool Value::emplace_back(std::string&& name, Value&& value) const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), mapData.members.cend(), std::nullopt, - [&mapData, &name](std::optional lhs, std::optional rhs) noexcept { + [&mapData, &name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; std::string_view rhsName { rhs == std::nullopt ? name : mapData.map[*rhs].first }; return lhsName < rhsName; @@ -1364,7 +1371,7 @@ MapType::const_iterator Value::find(std::string_view name) const const auto [itr, itrEnd] = std::equal_range(mapData.members.cbegin(), mapData.members.cend(), std::nullopt, - [&mapData, name](std::optional lhs, std::optional rhs) noexcept { + [&mapData, name](std::optional lhs, std::optional rhs) noexcept { std::string_view lhsName { lhs == std::nullopt ? name : mapData.map[*lhs].first }; std::string_view rhsName { rhs == std::nullopt ? name : mapData.map[*rhs].first }; return lhsName < rhsName; @@ -1429,7 +1436,7 @@ void Value::emplace_back(Value&& value) std::get(_data).emplace_back(std::move(value)); } -const Value& Value::operator[](size_t index) const +const Value& Value::operator[](std::size_t index) const { const auto& typeData = data(); diff --git a/src/GraphQLService.cpp b/src/GraphQLService.cpp index d3cd2095..af87a2c3 100644 --- a/src/GraphQLService.cpp +++ b/src/GraphQLService.cpp @@ -9,8 +9,11 @@ #include #include +#include #include +using namespace std::literals; + namespace graphql::service { void addErrorMessage(std::string&& message, response::Value& error) @@ -58,9 +61,10 @@ void addErrorPath(const error_path& path, response::Value& error) errorPath.emplace_back( response::Value { std::string { std::get(segment) } }); } - else if (std::holds_alternative(segment)) + else if (std::holds_alternative(segment)) { - errorPath.emplace_back(response::Value(static_cast(std::get(segment)))); + errorPath.emplace_back( + response::Value(static_cast(std::get(segment)))); } } @@ -179,10 +183,10 @@ std::string unimplemented_method::getMessage(std::string_view methodName) noexce return oss.str(); } -void await_worker_thread::await_suspend(coro::coroutine_handle<> h) const +void await_worker_thread::await_suspend(std::coroutine_handle<> h) const { std::thread( - [](coro::coroutine_handle<>&& h) { + [](std::coroutine_handle<>&& h) { h.resume(); }, std::move(h)) @@ -213,7 +217,7 @@ bool await_worker_queue::await_ready() const return std::this_thread::get_id() != _startId; } -void await_worker_queue::await_suspend(coro::coroutine_handle<> h) +void await_worker_queue::await_suspend(std::coroutine_handle<> h) { std::unique_lock lock { _mutex }; @@ -232,7 +236,7 @@ void await_worker_queue::resumePending() return _shutdown || !_pending.empty(); }); - std::list> pending; + std::list> pending; std::swap(pending, _pending); @@ -250,7 +254,7 @@ void await_worker_queue::resumePending() // Default to immediate synchronous execution. await_async::await_async() : _pimpl { std::static_pointer_cast( - std::make_shared>(std::make_shared())) } + std::make_shared>(std::make_shared())) } { } @@ -258,9 +262,9 @@ await_async::await_async() await_async::await_async(std::launch launch) : _pimpl { ((launch & std::launch::async) == std::launch::async) ? std::static_pointer_cast(std::make_shared>( - std::make_shared())) - : std::static_pointer_cast(std::make_shared>( - std::make_shared())) } + std::make_shared())) + : std::static_pointer_cast(std::make_shared>( + std::make_shared())) } { } @@ -269,7 +273,7 @@ bool await_async::await_ready() const return _pimpl->await_ready(); } -void await_async::await_suspend(coro::coroutine_handle<> h) const +void await_async::await_suspend(std::coroutine_handle<> h) const { _pimpl->await_suspend(std::move(h)); } @@ -885,7 +889,7 @@ class SelectionVisitor public: explicit SelectionVisitor(const SelectionSetParams& selectionSetParams, const FragmentMap& fragments, const response::Value& variables, const TypeNames& typeNames, - const ResolverMap& resolvers, size_t count); + const ResolverMap& resolvers, std::size_t count); void visit(const peg::ast_node& selection); @@ -922,7 +926,7 @@ class SelectionVisitor SelectionVisitor::SelectionVisitor(const SelectionSetParams& selectionSetParams, const FragmentMap& fragments, const response::Value& variables, const TypeNames& typeNames, - const ResolverMap& resolvers, size_t count) + const ResolverMap& resolvers, std::size_t count) : _resolverContext(selectionSetParams.resolverContext) , _state(selectionSetParams.state) , _operationDirectives(selectionSetParams.operationDirectives) @@ -1152,7 +1156,7 @@ void SelectionVisitor::visitFragmentSpread(const peg::ast_node& fragmentSpread) _fragmentDefinitionDirectives->push_front(itr->second.getDirectives()); _fragmentSpreadDirectives->push_front(directiveVisitor.getDirectives()); - const size_t count = itr->second.getSelection().children.size(); + const std::size_t count = itr->second.getSelection().children.size(); if (count > 1) { @@ -1197,7 +1201,7 @@ void SelectionVisitor::visitInlineFragment(const peg::ast_node& inlineFragment) [this, &directiveVisitor](const peg::ast_node& child) { _inlineFragmentDirectives->push_front(directiveVisitor.getDirectives()); - const size_t count = child.children.size(); + const std::size_t count = child.children.size(); if (count > 1) { diff --git a/src/RequestLoader.cpp b/src/RequestLoader.cpp index 4b36020c..44d2a47b 100644 --- a/src/RequestLoader.cpp +++ b/src/RequestLoader.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -162,7 +163,7 @@ std::string RequestLoader::getInputCppType( const RequestSchemaType& inputType, const TypeModifierStack& modifiers) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream cppType; for (auto modifier : modifiers) @@ -211,7 +212,7 @@ std::string RequestLoader::getInputCppType( cppType << _schemaLoader.getCppType(inputType->name()); - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { cppType << R"cpp(>)cpp"; } @@ -223,7 +224,7 @@ std::string RequestLoader::getOutputCppType( std::string_view outputCppType, const TypeModifierStack& modifiers) noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream cppType; for (auto modifier : modifiers) @@ -260,7 +261,7 @@ std::string RequestLoader::getOutputCppType( cppType << outputCppType; - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { cppType << R"cpp(>)cpp"; } @@ -572,8 +573,7 @@ void RequestLoader::addTypesToSchema() locationValue.set(std::string { locationName }); - return service::Argument::convert( - locationValue); + return service::Argument::convert(locationValue); }); std::vector> arguments( @@ -701,7 +701,8 @@ std::string_view RequestLoader::trimWhitespace(std::string_view content) noexcep if (skip >= 0 && length >= skip) { - content = content.substr(static_cast(skip), static_cast(length - skip)); + content = + content.substr(static_cast(skip), static_cast(length - skip)); } return content; diff --git a/src/SchemaGenerator.cpp b/src/SchemaGenerator.cpp index 6feaea8d..c6ef33df 100644 --- a/src/SchemaGenerator.cpp +++ b/src/SchemaGenerator.cpp @@ -4,6 +4,8 @@ #include "SchemaGenerator.h" #include "GeneratorUtil.h" +#include "graphqlservice/internal/Version.h" + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 26495) @@ -16,7 +18,9 @@ #pragma warning(pop) #endif // _MSC_VER +#include #include +#include #include #include #include @@ -35,6 +39,7 @@ Generator::Generator(SchemaOptions&& schemaOptions, GeneratorOptions&& options) , _headerDir(getHeaderDir()) , _sourceDir(getSourceDir()) , _headerPath(getHeaderPath()) + , _modulePath(getModulePath()) , _sourcePath(getSourcePath()) { } @@ -71,6 +76,14 @@ std::string Generator::getHeaderPath() const noexcept return fullPath.string(); } +std::string Generator::getModulePath() const noexcept +{ + std::filesystem::path fullPath { _headerDir }; + + fullPath /= (std::string { _loader.getFilenamePrefix() } + "Schema.ixx"); + return fullPath.string(); +} + std::string Generator::getSourcePath() const noexcept { std::filesystem::path fullPath { _sourceDir }; @@ -88,6 +101,11 @@ std::vector Generator::Build() const noexcept builtFiles.push_back(_headerPath); } + if (outputModule() && _options.verbose) + { + builtFiles.push_back(_modulePath); + } + if (outputSource()) { builtFiles.push_back(_sourcePath); @@ -112,8 +130,14 @@ bool Generator::outputHeader() const noexcept headerFile << R"cpp(#include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" +#include +#include +#include +#include + // Check if the library version is compatible with schemagen )cpp" << graphql::internal::MajorVersion << R"cpp(.)cpp" << graphql::internal::MinorVersion << R"cpp(.0 @@ -124,11 +148,6 @@ static_assert(graphql::internal::MinorVersion == )cpp" << graphql::internal::MinorVersion << R"cpp(, "regenerate with schemagen: minor version mismatch"); -#include -#include -#include -#include - )cpp"; NamespaceScope graphqlNamespace { headerFile, "graphql" }; @@ -667,6 +686,172 @@ GRAPHQLSERVICE_EXPORT )cpp" << _loader.getSchemaNamespace() return true; } +bool Generator::outputModule() const noexcept +{ + std::ofstream moduleFile(_modulePath, std::ios_base::trunc); + std::ostringstream ossNamespace; + + ossNamespace << R"cpp(graphql::)cpp" << _loader.getSchemaNamespace(); + + const auto schemaNamespace = ossNamespace.str(); + + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << _loader.getFilenamePrefix() + << + R"cpp(Schema.h" + +export module GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << _loader.getFilenamePrefix() << + R"cpp(Schema; +)cpp"; + + PendingBlankLine pendingSeparator { moduleFile }; + + if (!_loader.getInterfaceTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& interfaceType : _loader.getInterfaceTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << interfaceType.cppType << R"cpp(Object; +)cpp"; + } + } + + if (!_loader.getUnionTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& unionType : _loader.getUnionTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << unionType.cppType << R"cpp(Object; +)cpp"; + } + } + + if (!_loader.getObjectTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& objectType : _loader.getObjectTypes()) + { + moduleFile << R"cpp(export import GraphQL.)cpp" << _loader.getFilenamePrefix() + << R"cpp(.)cpp" << objectType.cppType << R"cpp(Object; +)cpp"; + } + } + + moduleFile << R"cpp( +export )cpp"; + + NamespaceScope graphqlNamespace { moduleFile, schemaNamespace }; + + pendingSeparator.add(); + + if (!_loader.getEnumTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& enumType : _loader.getEnumTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << enumType.cppType << R"cpp(; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Names; +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::get)cpp" << enumType.cppType << R"cpp(Values; + +)cpp"; + } + } + + if (!_loader.getInputTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& inputType : _loader.getInputTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::)cpp" + << inputType.cppType << R"cpp(; +)cpp"; + } + + moduleFile << std::endl; + } + + if (!_loader.isIntrospection()) + { + pendingSeparator.reset(); + + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Operations; + +)cpp"; + } + + if (!_loader.getInterfaceTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& interfaceType : _loader.getInterfaceTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << interfaceType.cppType << R"cpp(Details; +)cpp"; + } + } + + if (!_loader.getUnionTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& unionType : _loader.getUnionTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << unionType.cppType << R"cpp(Details; +)cpp"; + } + } + + if (!_loader.getObjectTypes().empty()) + { + pendingSeparator.reset(); + + for (const auto& objectType : _loader.getObjectTypes()) + { + moduleFile << R"cpp(using )cpp" << _loader.getSchemaNamespace() << R"cpp(::Add)cpp" + << objectType.cppType << R"cpp(Details; +)cpp"; + } + } + + if (_loader.isIntrospection()) + { + moduleFile << R"cpp( +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::AddTypesToSchema; + +)cpp"; + } + else + { + moduleFile << R"cpp( +using )cpp" << _loader.getSchemaNamespace() + << R"cpp(::GetSchema; + +)cpp"; + } + + return true; +} + void Generator::outputInterfaceDeclaration(std::ostream& headerFile, std::string_view cppType) const { headerFile @@ -741,6 +926,33 @@ void Generator::outputInterfaceDeclaration(std::ostream& headerFile, std::string )cpp"; } +void Generator::outputObjectModule( + std::ostream& moduleFile, std::string_view objectNamespace, std::string_view cppType) const +{ + moduleFile << R"cpp(// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include ")cpp" << cppType + << R"cpp(Object.h" + +export module GraphQL.)cpp" + << _loader.getFilenamePrefix() << R"cpp(.)cpp" << cppType << R"cpp(Object; + +export namespace )cpp" + << objectNamespace << R"cpp( { + +using object::)cpp" + << cppType << R"cpp(; + +} // namespace )cpp" + << objectNamespace << R"cpp( +)cpp"; +} + void Generator::outputObjectImplements(std::ostream& headerFile, const ObjectType& objectType) const { headerFile << R"cpp(template @@ -1272,6 +1484,7 @@ bool Generator::outputSource() const noexcept sourceFile << R"cpp( #include #include +#include #include #include #include @@ -1342,7 +1555,7 @@ service::AwaitableResolver Result<)cpp" response::Value resolvedResult(response::Type::EnumValue); resolvedResult.set(std::string { s_names)cpp" - << enumType.cppType << R"cpp([static_cast(value)] }); + << enumType.cppType << R"cpp([static_cast(value)] }); return resolvedResult; }); @@ -1902,9 +2115,9 @@ Operations::Operations()cpp"; firstValue = false; sourceFile << R"cpp( { service::s_names)cpp" << enumType.cppType - << R"cpp([static_cast()cpp" << _loader.getSchemaNamespace() - << R"cpp(::)cpp" << enumType.cppType << R"cpp(::)cpp" - << enumValue.cppValue << R"cpp()], R"md()cpp"; + << R"cpp([static_cast()cpp" + << _loader.getSchemaNamespace() << R"cpp(::)cpp" << enumType.cppType + << R"cpp(::)cpp" << enumValue.cppValue << R"cpp()], R"md()cpp"; if (!_options.noIntrospection) { @@ -2646,7 +2859,7 @@ void Generator::outputIntrospectionFields( } std::string Generator::getArgumentDefaultValue( - size_t level, const response::Value& defaultValue) const noexcept + std::size_t level, const response::Value& defaultValue) const noexcept { const std::string padding(level, '\t'); std::ostringstream argumentDefaultValue; @@ -2933,7 +3146,7 @@ std::string Generator::getTypeModifiers(const TypeModifierStack& modifiers) cons std::string Generator::getIntrospectionType( std::string_view type, const TypeModifierStack& modifiers) const noexcept { - size_t wrapperCount = 0; + std::size_t wrapperCount = 0; bool nonNull = true; std::ostringstream introspectionType; @@ -2995,7 +3208,7 @@ std::string Generator::getIntrospectionType( introspectionType << R"cpp(schema->LookupType(R"gql()cpp" << type << R"cpp()gql"sv))cpp"; - for (size_t i = 0; i < wrapperCount; ++i) + for (std::size_t i = 0; i < wrapperCount; ++i) { introspectionType << R"cpp())cpp"; } @@ -3050,11 +3263,21 @@ std::vector Generator::outputSeparateFiles() const noexcept headerFile << std::endl; outputInterfaceDeclaration(headerFile, interfaceType.cppType); headerFile << std::endl; + } - if (_options.verbose) - { - files.push_back(std::move(headerPath)); - } + const auto moduleFilename = std::string(interfaceType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, interfaceType.cppType); + } + + if (_options.verbose) + { + files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(interfaceType.cppType) + "Object.cpp"; @@ -3126,9 +3349,19 @@ using namespace std::literals; headerFile << std::endl; } + const auto moduleFilename = std::string(unionType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, unionType.cppType); + } + if (_options.verbose) { files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(unionType.cppType) + "Object.cpp"; @@ -3225,9 +3458,19 @@ using namespace std::literals; headerFile << std::endl; } + const auto moduleFilename = std::string(objectType.cppType) + "Object.ixx"; + auto modulePath = (headerDir / moduleFilename).string(); + + { + std::ofstream moduleFile(modulePath, std::ios_base::trunc); + + outputObjectModule(moduleFile, objectNamespace, objectType.cppType); + } + if (_options.verbose) { files.push_back(std::move(headerPath)); + files.push_back(std::move(modulePath)); } const auto sourceFilename = std::string(objectType.cppType) + "Object.cpp"; diff --git a/src/SchemaLoader.cpp b/src/SchemaLoader.cpp index 9129ec48..3e0827a8 100644 --- a/src/SchemaLoader.cpp +++ b/src/SchemaLoader.cpp @@ -4,6 +4,7 @@ #include "SchemaLoader.h" #include +#include #include #include #include @@ -1614,7 +1615,7 @@ const tao::graphqlpeg::position& SchemaLoader::getTypePosition(std::string_view return _typePositions.at(type); } -size_t SchemaLoader::getScalarIndex(std::string_view type) const +std::size_t SchemaLoader::getScalarIndex(std::string_view type) const { return _scalarNames.at(type); } @@ -1624,7 +1625,7 @@ const ScalarTypeList& SchemaLoader::getScalarTypes() const noexcept return _scalarTypes; } -size_t SchemaLoader::getEnumIndex(std::string_view type) const +std::size_t SchemaLoader::getEnumIndex(std::string_view type) const { return _enumNames.at(type); } @@ -1634,7 +1635,7 @@ const EnumTypeList& SchemaLoader::getEnumTypes() const noexcept return _enumTypes; } -size_t SchemaLoader::getInputIndex(std::string_view type) const +std::size_t SchemaLoader::getInputIndex(std::string_view type) const { return _inputNames.at(type); } @@ -1644,7 +1645,7 @@ const InputTypeList& SchemaLoader::getInputTypes() const noexcept return _inputTypes; } -size_t SchemaLoader::getUnionIndex(std::string_view type) const +std::size_t SchemaLoader::getUnionIndex(std::string_view type) const { return _unionNames.at(type); } @@ -1654,7 +1655,7 @@ const UnionTypeList& SchemaLoader::getUnionTypes() const noexcept return _unionTypes; } -size_t SchemaLoader::getInterfaceIndex(std::string_view type) const +std::size_t SchemaLoader::getInterfaceIndex(std::string_view type) const { return _interfaceNames.at(type); } @@ -1664,7 +1665,7 @@ const InterfaceTypeList& SchemaLoader::getInterfaceTypes() const noexcept return _interfaceTypes; } -size_t SchemaLoader::getObjectIndex(std::string_view type) const +std::size_t SchemaLoader::getObjectIndex(std::string_view type) const { return _objectNames.at(type); } @@ -1695,9 +1696,9 @@ std::string_view SchemaLoader::getCppType(std::string_view type) const noexcept if (itrBuiltin != s_builtinTypes.cend()) { - if (static_cast(itrBuiltin->second) < s_builtinCppTypes.size()) + if (static_cast(itrBuiltin->second) < s_builtinCppTypes.size()) { - return s_builtinCppTypes[static_cast(itrBuiltin->second)]; + return s_builtinCppTypes[static_cast(itrBuiltin->second)]; } } else @@ -1716,7 +1717,7 @@ std::string_view SchemaLoader::getCppType(std::string_view type) const noexcept std::string SchemaLoader::getInputCppType(const InputField& field) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream inputType; for (auto modifier : field.modifiers) @@ -1765,7 +1766,7 @@ std::string SchemaLoader::getInputCppType(const InputField& field) const noexcep inputType << getCppType(field.type); - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { inputType << R"cpp(>)cpp"; } @@ -1776,7 +1777,7 @@ std::string SchemaLoader::getInputCppType(const InputField& field) const noexcep std::string SchemaLoader::getOutputCppType(const OutputField& field) const noexcept { bool nonNull = true; - size_t templateCount = 0; + std::size_t templateCount = 0; std::ostringstream outputType; switch (field.fieldType) @@ -1855,7 +1856,7 @@ std::string SchemaLoader::getOutputCppType(const OutputField& field) const noexc break; } - for (size_t i = 0; i < templateCount; ++i) + for (std::size_t i = 0; i < templateCount; ++i) { outputType << R"cpp(>)cpp"; } diff --git a/src/SyntaxTree.cpp b/src/SyntaxTree.cpp index 60743538..b0882ac1 100644 --- a/src/SyntaxTree.cpp +++ b/src/SyntaxTree.cpp @@ -8,6 +8,7 @@ #include +#include #include #include #include @@ -50,14 +51,14 @@ std::string_view ast_node::unescaped_view() const && child->children.front()->is_type() && child->children.back()->is_type()) ? std::make_optional(std::make_pair(child->children.front()->string_view(), - child->children.back()->unescaped_view())) + child->children.back()->unescaped_view())) : std::nullopt; }); // Calculate the common indent const auto commonIndent = std::accumulate(lines.cbegin(), lines.cend(), - std::optional {}, + std::optional {}, [](auto value, const auto& line) noexcept { if (line) { @@ -79,7 +80,7 @@ std::string_view ast_node::unescaped_view() const { joined.reserve(std::accumulate(lines.cbegin(), lines.cend(), - size_t {}, + std::size_t {}, [trimIndent](auto value, const auto& line) noexcept { if (line) { @@ -118,8 +119,8 @@ std::string_view ast_node::unescaped_view() const joined.reserve(std::accumulate(children.cbegin(), children.cend(), - size_t(0), - [](size_t total, const std::unique_ptr& child) { + std::size_t(0), + [](std::size_t total, const std::unique_ptr& child) { return total + child->string_view().size(); })); @@ -642,7 +643,7 @@ struct ast_action : nothing struct [[nodiscard("unnecessary construction")]] depth_guard { - explicit depth_guard(size_t & depth) noexcept + explicit depth_guard(std::size_t& depth) noexcept : _depth(depth) { ++_depth; @@ -653,14 +654,14 @@ struct [[nodiscard("unnecessary construction")]] depth_guard --_depth; } - depth_guard(depth_guard &&) noexcept = delete; + depth_guard(depth_guard&&) noexcept = delete; depth_guard(const depth_guard&) = delete; depth_guard& operator=(depth_guard&&) noexcept = delete; depth_guard& operator=(const depth_guard&) = delete; private: - size_t& _depth; + std::size_t& _depth; }; template <> @@ -981,21 +982,21 @@ class [[nodiscard("unnecessary construction")]] depth_limit_input : public Parse { public: template - explicit depth_limit_input(size_t depthLimit, Args && ... args) noexcept + explicit depth_limit_input(std::size_t depthLimit, Args&&... args) noexcept : ParseInput(std::forward(args)...) , _depthLimit(depthLimit) { } - size_t depthLimit() const noexcept + std::size_t depthLimit() const noexcept { return _depthLimit; } - size_t selectionSetDepth = 0; + std::size_t selectionSetDepth = 0; private: - const size_t _depthLimit; + const std::size_t _depthLimit; }; using ast_file = depth_limit_input>; @@ -1018,7 +1019,7 @@ struct [[nodiscard("unnecessary construction")]] ast_input std::variant, ast_string_view> data; }; -ast parseSchemaString(std::string_view input, size_t depthLimit) +ast parseSchemaString(std::string_view input, std::size_t depthLimit) { ast result { std::make_shared( ast_input { ast_string { { input.cbegin(), input.cend() } } }), @@ -1050,7 +1051,7 @@ ast parseSchemaString(std::string_view input, size_t depthLimit) return result; } -ast parseSchemaFile(std::string_view filename, size_t depthLimit) +ast parseSchemaFile(std::string_view filename, std::size_t depthLimit) { ast result; @@ -1081,7 +1082,7 @@ ast parseSchemaFile(std::string_view filename, size_t depthLimit) return result; } -ast parseString(std::string_view input, size_t depthLimit) +ast parseString(std::string_view input, std::size_t depthLimit) { ast result { std::make_shared( ast_input { ast_string { { input.cbegin(), input.cend() } } }), @@ -1114,7 +1115,7 @@ ast parseString(std::string_view input, size_t depthLimit) return result; } -ast parseFile(std::string_view filename, size_t depthLimit) +ast parseFile(std::string_view filename, std::size_t depthLimit) { ast result; @@ -1148,7 +1149,7 @@ ast parseFile(std::string_view filename, size_t depthLimit) } // namespace peg -peg::ast operator"" _graphql(const char* text, size_t size) +peg::ast operator"" _graphql(const char* text, std::size_t size) { peg::ast result { std::make_shared( peg::ast_input { peg::ast_string_view { { text, size } } }), diff --git a/src/Validation.cpp b/src/Validation.cpp index a95c8624..9ed417e1 100644 --- a/src/Validation.cpp +++ b/src/Validation.cpp @@ -9,6 +9,7 @@ #include "graphqlservice/introspection/IntrospectionSchema.h" #include +#include #include #include #include @@ -1770,7 +1771,7 @@ void ValidateExecutableVisitor::visitField(const peg::ast_node& field) selection = &child; }); - size_t subFieldCount = 0; + std::size_t subFieldCount = 0; if (selection != nullptr) { diff --git a/src/introspection/CMakeLists.txt b/src/introspection/CMakeLists.txt index 329b95a7..a30faa97 100644 --- a/src/introspection/CMakeLists.txt +++ b/src/introspection/CMakeLists.txt @@ -10,18 +10,14 @@ if(GRAPHQL_UPDATE_SAMPLES) update_graphql_schema_files(introspection schema.introspection.graphql Introspection introspection --introspection) file(GLOB PRIVATE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/*.h) + file(GLOB PRIVATE_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/*.ixx) add_custom_command( OUTPUT copied_introspection_schema_headers - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PRIVATE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/ + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${PRIVATE_HEADERS} ${PRIVATE_MODULES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/ COMMAND ${CMAKE_COMMAND} -E touch copied_introspection_schema_headers - DEPENDS ${PRIVATE_HEADERS} ${CMAKE_CURRENT_SOURCE_DIR}/introspection_schema_files + DEPENDS ${PRIVATE_HEADERS} ${PRIVATE_MODULES} ${CMAKE_CURRENT_SOURCE_DIR}/introspection_schema_files COMMENT "Updating IntrospectionSchema headers") add_custom_target(copy_introspection_schema_headers ALL DEPENDS copied_introspection_schema_headers) endif() - -file(GLOB PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/graphqlservice/introspection/*.h) -install(FILES ${PUBLIC_HEADERS} - CONFIGURATIONS ${GRAPHQL_INSTALL_CONFIGURATIONS} - DESTINATION ${GRAPHQL_INSTALL_INCLUDE_DIR}/graphqlservice/introspection) diff --git a/src/introspection/DirectiveObject.ixx b/src/introspection/DirectiveObject.ixx new file mode 100644 index 00000000..8a00c78d --- /dev/null +++ b/src/introspection/DirectiveObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "DirectiveObject.h" + +export module GraphQL.Introspection.DirectiveObject; + +export namespace graphql::introspection::object { + +using object::Directive; + +} // namespace graphql::introspection::object diff --git a/src/introspection/EnumValueObject.ixx b/src/introspection/EnumValueObject.ixx new file mode 100644 index 00000000..45be5d13 --- /dev/null +++ b/src/introspection/EnumValueObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "EnumValueObject.h" + +export module GraphQL.Introspection.EnumValueObject; + +export namespace graphql::introspection::object { + +using object::EnumValue; + +} // namespace graphql::introspection::object diff --git a/src/introspection/FieldObject.ixx b/src/introspection/FieldObject.ixx new file mode 100644 index 00000000..aa5c8305 --- /dev/null +++ b/src/introspection/FieldObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "FieldObject.h" + +export module GraphQL.Introspection.FieldObject; + +export namespace graphql::introspection::object { + +using object::Field; + +} // namespace graphql::introspection::object diff --git a/src/introspection/InputValueObject.ixx b/src/introspection/InputValueObject.ixx new file mode 100644 index 00000000..252760df --- /dev/null +++ b/src/introspection/InputValueObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "InputValueObject.h" + +export module GraphQL.Introspection.InputValueObject; + +export namespace graphql::introspection::object { + +using object::InputValue; + +} // namespace graphql::introspection::object diff --git a/src/introspection/IntrospectionSchema.cpp b/src/introspection/IntrospectionSchema.cpp index 81b28bf4..048cbcc9 100644 --- a/src/introspection/IntrospectionSchema.cpp +++ b/src/introspection/IntrospectionSchema.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include #include @@ -50,7 +51,7 @@ service::AwaitableResolver Result::convert(service::Awa { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); + resolvedResult.set(std::string { s_namesTypeKind[static_cast(value)] }); return resolvedResult; }); @@ -106,7 +107,7 @@ service::AwaitableResolver Result::convert(ser { response::Value resolvedResult(response::Type::EnumValue); - resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); + resolvedResult.set(std::string { s_namesDirectiveLocation[static_cast(value)] }); return resolvedResult; }); @@ -160,35 +161,35 @@ void AddTypesToSchema(const std::shared_ptr& schema) schema->AddType(R"gql(__Directive)gql"sv, typeDirective); typeTypeKind->AddEnumValues({ - { service::s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, - { service::s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } + { service::s_namesTypeKind[static_cast(introspection::TypeKind::SCALAR)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::INTERFACE)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::UNION)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::ENUM)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::LIST)], R"md()md"sv, std::nullopt }, + { service::s_namesTypeKind[static_cast(introspection::TypeKind::NON_NULL)], R"md()md"sv, std::nullopt } }); typeDirectiveLocation->AddEnumValues({ - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, - { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::QUERY)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::MUTATION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SUBSCRIPTION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FRAGMENT_SPREAD)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INLINE_FRAGMENT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::VARIABLE_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCHEMA)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::SCALAR)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::FIELD_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ARGUMENT_DEFINITION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INTERFACE)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::UNION)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::ENUM_VALUE)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_OBJECT)], R"md()md"sv, std::nullopt }, + { service::s_namesDirectiveLocation[static_cast(introspection::DirectiveLocation::INPUT_FIELD_DEFINITION)], R"md()md"sv, std::nullopt } }); AddSchemaDetails(typeSchema, schema); diff --git a/src/introspection/IntrospectionSchema.h b/src/introspection/IntrospectionSchema.h index 363d67f2..b8e76fe3 100644 --- a/src/introspection/IntrospectionSchema.h +++ b/src/introspection/IntrospectionSchema.h @@ -11,17 +11,18 @@ #include "graphqlservice/GraphQLResponse.h" #include "graphqlservice/GraphQLService.h" +#include "graphqlservice/internal/Version.h" #include "graphqlservice/internal/Schema.h" -// Check if the library version is compatible with schemagen 4.5.0 -static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); -static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); - #include #include #include #include +// Check if the library version is compatible with schemagen 4.5.0 +static_assert(graphql::internal::MajorVersion == 4, "regenerate with schemagen: major version mismatch"); +static_assert(graphql::internal::MinorVersion == 5, "regenerate with schemagen: minor version mismatch"); + namespace graphql { namespace introspection { diff --git a/src/introspection/IntrospectionSchema.ixx b/src/introspection/IntrospectionSchema.ixx new file mode 100644 index 00000000..45f3f14a --- /dev/null +++ b/src/introspection/IntrospectionSchema.ixx @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "IntrospectionSchema.h" + +export module GraphQL.Introspection.IntrospectionSchema; + +export import GraphQL.Introspection.SchemaObject; +export import GraphQL.Introspection.TypeObject; +export import GraphQL.Introspection.FieldObject; +export import GraphQL.Introspection.InputValueObject; +export import GraphQL.Introspection.EnumValueObject; +export import GraphQL.Introspection.DirectiveObject; + +export namespace graphql::introspection { + +using introspection::TypeKind; +using introspection::getTypeKindNames; +using introspection::getTypeKindValues; + +using introspection::DirectiveLocation; +using introspection::getDirectiveLocationNames; +using introspection::getDirectiveLocationValues; + +using introspection::AddSchemaDetails; +using introspection::AddTypeDetails; +using introspection::AddFieldDetails; +using introspection::AddInputValueDetails; +using introspection::AddEnumValueDetails; +using introspection::AddDirectiveDetails; + +using introspection::AddTypesToSchema; + +} // namespace graphql::introspection diff --git a/src/introspection/SchemaObject.ixx b/src/introspection/SchemaObject.ixx new file mode 100644 index 00000000..56735d85 --- /dev/null +++ b/src/introspection/SchemaObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "SchemaObject.h" + +export module GraphQL.Introspection.SchemaObject; + +export namespace graphql::introspection::object { + +using object::Schema; + +} // namespace graphql::introspection::object diff --git a/src/introspection/TypeObject.ixx b/src/introspection/TypeObject.ixx new file mode 100644 index 00000000..001ccdd6 --- /dev/null +++ b/src/introspection/TypeObject.ixx @@ -0,0 +1,16 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// WARNING! Do not edit this file manually, your changes will be overwritten. + +module; + +#include "TypeObject.h" + +export module GraphQL.Introspection.TypeObject; + +export namespace graphql::introspection::object { + +using object::Type; + +} // namespace graphql::introspection::object diff --git a/test/ArgumentTests.cpp b/test/ArgumentTests.cpp index aa255700..557d4e71 100644 --- a/test/ArgumentTests.cpp +++ b/test/ArgumentTests.cpp @@ -7,6 +7,8 @@ #include "graphqlservice/JSONResponse.h" +#include + using namespace graphql; TEST(ArgumentsCase, ListArgumentStrings) @@ -27,7 +29,7 @@ TEST(ArgumentsCase, ListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 3 }, actual.size()) << "should get 3 entries"; + ASSERT_EQ(std::size_t { 3 }, actual.size()) << "should get 3 entries"; EXPECT_EQ("string1", actual[0]) << "entry should match"; EXPECT_EQ("string2", actual[1]) << "entry should match"; EXPECT_EQ("string3", actual[2]) << "entry should match"; @@ -80,7 +82,7 @@ TEST(ArgumentsCase, ListArgumentStringsNullable) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 4 }, actual.size()) << "should get 4 entries"; + ASSERT_EQ(std::size_t { 4 }, actual.size()) << "should get 4 entries"; ASSERT_TRUE(actual[0].has_value()) << "should not be null"; EXPECT_EQ("string1", *actual[0]) << "entry should match"; ASSERT_TRUE(actual[1].has_value()) << "should not be null"; @@ -108,11 +110,11 @@ TEST(ArgumentsCase, ListArgumentListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 2 }, actual.size()) << "should get 2 entries"; - ASSERT_EQ(size_t { 2 }, actual[0].size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual.size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[0].size()) << "should get 2 entries"; EXPECT_EQ("list1string1", actual[0][0]) << "entry should match"; EXPECT_EQ("list1string2", actual[0][1]) << "entry should match"; - ASSERT_EQ(size_t { 2 }, actual[1].size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[1].size()) << "should get 2 entries"; EXPECT_EQ("list2string1", actual[1][0]) << "entry should match"; EXPECT_EQ("list2string2", actual[1][1]) << "entry should match"; } @@ -136,9 +138,9 @@ TEST(ArgumentsCase, ListArgumentNullableListArgumentStrings) FAIL() << response::toJSON(ex.getErrors()); } - ASSERT_EQ(size_t { 2 }, actual.size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual.size()) << "should get 2 entries"; EXPECT_FALSE(actual[0].has_value()) << "should be null"; - ASSERT_EQ(size_t { 2 }, actual[1]->size()) << "should get 2 entries"; + ASSERT_EQ(std::size_t { 2 }, actual[1]->size()) << "should get 2 entries"; EXPECT_EQ("list2string1", (*actual[1])[0]) << "entry should match"; EXPECT_EQ("list2string2", (*actual[1])[1]) << "entry should match"; } @@ -241,7 +243,7 @@ TEST(ArgumentsCase, ScalarArgumentMap) ASSERT_EQ(response::Type::Map, actual.type()) << "should parse the object"; values = actual.release(); - ASSERT_EQ(size_t { 1 }, values.size()) << "should have a single key/value"; + ASSERT_EQ(std::size_t { 1 }, values.size()) << "should have a single key/value"; ASSERT_EQ("foo", values.front().first) << "should match the key"; ASSERT_EQ("bar", values.front().second.get()) << "should match the value"; } @@ -264,7 +266,7 @@ TEST(ArgumentsCase, ScalarArgumentList) ASSERT_EQ(response::Type::List, actual.type()) << "should parse the array"; values = actual.release(); - ASSERT_EQ(size_t { 2 }, values.size()) << "should have 2 values"; + ASSERT_EQ(std::size_t { 2 }, values.size()) << "should have 2 values"; ASSERT_EQ("foo", values.front().get()) << "should match the value"; ASSERT_EQ("bar", values.back().get()) << "should match the value"; } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9e0a8150..062f2995 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -14,51 +14,53 @@ target_link_libraries(validation_tests PRIVATE add_bigobj_flag(validation_tests) gtest_add_tests(TARGET validation_tests) -add_executable(today_tests TodayTests.cpp) -target_link_libraries(today_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(today_tests) -gtest_add_tests(TARGET today_tests) +if(GRAPHQL_BUILD_MODULES) + add_executable(today_tests TodayTests.cpp) + target_link_libraries(today_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(today_tests) + gtest_add_tests(TARGET today_tests) -add_executable(coroutine_tests CoroutineTests.cpp) -target_link_libraries(coroutine_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -gtest_add_tests(TARGET coroutine_tests) + add_executable(coroutine_tests CoroutineTests.cpp) + target_link_libraries(coroutine_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + gtest_add_tests(TARGET coroutine_tests) -add_executable(client_tests ClientTests.cpp) -target_link_libraries(client_tests PRIVATE - todaygraphql - query_client - mutate_client - subscribe_client - GTest::GTest - GTest::Main) -add_bigobj_flag(client_tests) -gtest_add_tests(TARGET client_tests) + add_executable(client_tests ClientTests.cpp) + target_link_libraries(client_tests PRIVATE + todaygraphql + query_client + mutate_client + subscribe_client + GTest::GTest + GTest::Main) + add_bigobj_flag(client_tests) + gtest_add_tests(TARGET client_tests) -add_executable(nointrospection_tests NoIntrospectionTests.cpp) -target_link_libraries(nointrospection_tests PRIVATE - todaygraphql_nointrospection - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(nointrospection_tests) -gtest_add_tests(TARGET nointrospection_tests) + add_executable(nointrospection_tests NoIntrospectionTests.cpp) + target_link_libraries(nointrospection_tests PRIVATE + todaygraphql_nointrospection + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(nointrospection_tests) + gtest_add_tests(TARGET nointrospection_tests) -add_executable(argument_tests ArgumentTests.cpp) -target_link_libraries(argument_tests PRIVATE - todaygraphql - graphqljson - GTest::GTest - GTest::Main) -add_bigobj_flag(argument_tests) -gtest_add_tests(TARGET argument_tests) + add_executable(argument_tests ArgumentTests.cpp) + target_link_libraries(argument_tests PRIVATE + todaygraphql + graphqljson + GTest::GTest + GTest::Main) + add_bigobj_flag(argument_tests) + gtest_add_tests(TARGET argument_tests) +endif() add_executable(pegtl_combined_tests PegtlCombinedTests.cpp) target_link_libraries(pegtl_combined_tests PRIVATE @@ -118,10 +120,12 @@ if(WIN32 AND BUILD_SHARED_LIBS) add_custom_target(copy_test_dlls DEPENDS copied_test_dlls) add_dependencies(validation_tests copy_test_dlls) - add_dependencies(today_tests copy_test_dlls) - add_dependencies(client_tests copy_test_dlls) - add_dependencies(nointrospection_tests copy_test_dlls) - add_dependencies(argument_tests copy_test_dlls) + if(GRAPHQL_BUILD_MODULES) + add_dependencies(today_tests copy_test_dlls) + add_dependencies(client_tests copy_test_dlls) + add_dependencies(nointrospection_tests copy_test_dlls) + add_dependencies(argument_tests copy_test_dlls) + endif() add_dependencies(pegtl_combined_tests copy_test_dlls) add_dependencies(pegtl_executable_tests copy_test_dlls) add_dependencies(pegtl_schema_tests copy_test_dlls) diff --git a/test/ClientTests.cpp b/test/ClientTests.cpp index 99835f32..5a576b66 100644 --- a/test/ClientTests.cpp +++ b/test/ClientTests.cpp @@ -3,12 +3,19 @@ #include -#include "MutateClient.h" -#include "QueryClient.h" -#include "SubscribeClient.h" -#include "TodayMock.h" - #include +#include +#include + +import GraphQL.Parse; +import GraphQL.Client; +import GraphQL.Service; + +import GraphQL.Mutate.MutateClient; +import GraphQL.Query.QueryClient; +import GraphQL.Subscribe.SubscribeClient; + +import GraphQL.Today.Mock; using namespace graphql; @@ -42,20 +49,23 @@ TEST_F(ClientCase, QueryEverything) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -63,10 +73,10 @@ TEST_F(ClientCase, QueryEverything) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; ASSERT_TRUE(response.appointments.edges.has_value()) << "appointments should be set"; - ASSERT_EQ(size_t { 1 }, response.appointments.edges->size()) + ASSERT_EQ(std::size_t { 1 }, response.appointments.edges->size()) << "appointments should have 1 entry"; ASSERT_TRUE((*response.appointments.edges)[0].has_value()) << "edge should be set"; const auto& appointmentNode = (*response.appointments.edges)[0]->node; @@ -81,7 +91,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ("Appointment", appointmentNode->_typename) << "__typename should match"; ASSERT_TRUE(response.tasks.edges.has_value()) << "tasks should be set"; - ASSERT_EQ(size_t { 1 }, response.tasks.edges->size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, response.tasks.edges->size()) << "tasks should have 1 entry"; ASSERT_TRUE((*response.tasks.edges)[0].has_value()) << "edge should be set"; const auto& taskNode = (*response.tasks.edges)[0]->node; ASSERT_TRUE(taskNode.has_value()) << "node should be set"; @@ -92,7 +102,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ("Task", taskNode->_typename) << "__typename should match"; ASSERT_TRUE(response.unreadCounts.edges.has_value()) << "unreadCounts should be set"; - ASSERT_EQ(size_t { 1 }, response.unreadCounts.edges->size()) + ASSERT_EQ(std::size_t { 1 }, response.unreadCounts.edges->size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE((*response.unreadCounts.edges)[0].has_value()) << "edge should be set"; const auto& unreadCountNode = (*response.unreadCounts.edges)[0]->node; @@ -107,7 +117,7 @@ TEST_F(ClientCase, QueryEverything) EXPECT_EQ(client::query::Query::TaskState::Unassigned, response.testTaskState) << "testTaskState should match"; - ASSERT_EQ(size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, response.anyType.size()) << "anyType should have 1 entry"; ASSERT_TRUE(response.anyType[0].has_value()) << "appointment should be set"; const auto& anyType = *response.anyType[0]; EXPECT_EQ("Appointment", anyType._typename) << "__typename should match"; @@ -148,7 +158,7 @@ TEST_F(ClientCase, MutateCompleteTask) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; const auto& completedTask = response.completedTask; const auto& task = completedTask.completedTask; @@ -197,7 +207,7 @@ TEST_F(ClientCase, SubscribeNextAppointmentChangeDefault) auto serviceResponse = client::parseServiceResponse(std::move(result)); const auto response = parseResponse(std::move(serviceResponse.data)); - EXPECT_EQ(size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; + EXPECT_EQ(std::size_t { 0 }, serviceResponse.errors.size()) << "no errors expected"; const auto& appointmentNode = response.nextAppointment; ASSERT_TRUE(appointmentNode.has_value()) << "should get back a task"; diff --git a/test/CoroutineTests.cpp b/test/CoroutineTests.cpp index 5cf074f8..435e0df8 100644 --- a/test/CoroutineTests.cpp +++ b/test/CoroutineTests.cpp @@ -3,9 +3,14 @@ #include -#include "TodayMock.h" +#include +#include -#include "graphqlservice/JSONResponse.h" +import GraphQL.Parse; +import GraphQL.JSONResponse; +import GraphQL.Service; + +import GraphQL.Today.Mock; using namespace graphql; @@ -25,7 +30,7 @@ class CoroutineCase : public ::testing::Test } protected: - std::unique_ptr _mockService; + std::unique_ptr _mockService; }; TEST_F(CoroutineCase, QueryEverythingSync) @@ -66,7 +71,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) })"_graphql; response::Value variables(response::Type::Map); auto state = std::make_shared(1); - const auto worker = std::make_shared(); + const auto worker = std::make_shared(); auto result = _mockService->service ->resolve({ query, "Everything"sv, @@ -74,20 +79,23 @@ TEST_F(CoroutineCase, QueryEverythingSync) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -102,7 +110,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -121,7 +129,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -136,7 +144,7 @@ TEST_F(CoroutineCase, QueryEverythingSync) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -201,20 +209,23 @@ TEST_F(CoroutineCase, QueryEverythingQueued) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 2 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 2 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 2 }, state->unreadCountsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -229,7 +240,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -248,7 +259,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -263,7 +274,7 @@ TEST_F(CoroutineCase, QueryEverythingQueued) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -328,20 +339,23 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) service::await_async { worker }, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 3 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 3 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -356,7 +370,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -375,7 +389,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -390,7 +404,7 @@ TEST_F(CoroutineCase, QueryEverythingThreaded) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); diff --git a/test/NoIntrospectionTests.cpp b/test/NoIntrospectionTests.cpp index 371e807f..c8779b42 100644 --- a/test/NoIntrospectionTests.cpp +++ b/test/NoIntrospectionTests.cpp @@ -3,11 +3,15 @@ #include -#include "TodayMock.h" +#include +#include +#include -#include "graphqlservice/JSONResponse.h" +import GraphQL.Parse; +import GraphQL.JSONResponse; +import GraphQL.Service; -#include +import GraphQL.Today.Mock; using namespace graphql; @@ -75,20 +79,23 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) _mockService->service ->resolve({ query, "Everything"sv, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -103,7 +110,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -122,7 +129,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -137,7 +144,7 @@ TEST_F(NoIntrospectionServiceCase, QueryEverything) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); diff --git a/test/PegtlCombinedTests.cpp b/test/PegtlCombinedTests.cpp index 170c751f..a4e54521 100644 --- a/test/PegtlCombinedTests.cpp +++ b/test/PegtlCombinedTests.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -14,6 +16,6 @@ using namespace tao::graphqlpeg; TEST(PegtlCombinedCase, AnalyzeMixedGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } diff --git a/test/PegtlExecutableTests.cpp b/test/PegtlExecutableTests.cpp index 4dc47120..af14bd4d 100644 --- a/test/PegtlExecutableTests.cpp +++ b/test/PegtlExecutableTests.cpp @@ -9,6 +9,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -138,7 +140,7 @@ TEST(PegtlExecutableCase, ParseVariableDefaultEmptyList) TEST(PegtlExecutableCase, AnalyzeExecutableGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } @@ -248,8 +250,7 @@ TEST(PegtlExecutableCase, ParseFloatWithFractionalAndExponentialParts) TEST(PegtlExecutableCase, ParseIgnoreUnicodeBOM) { - memory_input<> input("query { \xEF\xBB\xBF __typename }", - "ParseIgnoreUnicodeBOM"); + memory_input<> input("query { \xEF\xBB\xBF __typename }", "ParseIgnoreUnicodeBOM"); const bool result = parse(input); diff --git a/test/PegtlSchemaTests.cpp b/test/PegtlSchemaTests.cpp index 330a6d72..24e621fd 100644 --- a/test/PegtlSchemaTests.cpp +++ b/test/PegtlSchemaTests.cpp @@ -7,6 +7,8 @@ #include +#include + using namespace graphql; using namespace graphql::peg; @@ -219,6 +221,6 @@ TEST(PegtlSchemaCase, ParseTodaySchema) TEST(PegtlSchemaCase, AnalyzeSchemaGrammar) { - ASSERT_EQ(size_t { 0 }, analyze(true)) + ASSERT_EQ(std::size_t { 0 }, analyze(true)) << "there shouldn't be any infinite loops in the PEG version of the grammar"; } diff --git a/test/TodayTests.cpp b/test/TodayTests.cpp index 95ed9414..48699123 100644 --- a/test/TodayTests.cpp +++ b/test/TodayTests.cpp @@ -3,11 +3,15 @@ #include -#include "TodayMock.h" +#include +#include +#include -#include "graphqlservice/JSONResponse.h" +import GraphQL.Parse; +import GraphQL.JSONResponse; +import GraphQL.Service; -#include +import GraphQL.Today.Mock; using namespace graphql; @@ -72,20 +76,23 @@ TEST_F(TodayServiceCase, QueryEverything) _mockService->service ->resolve({ query, "Everything"sv, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 1 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->appointmentsRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 1 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -100,7 +107,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -119,7 +126,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("id", taskNode)) @@ -134,7 +141,7 @@ TEST_F(TodayServiceCase, QueryEverything) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -171,20 +178,21 @@ TEST_F(TodayServiceCase, QueryAppointments) auto state = std::make_shared(2); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -200,7 +208,7 @@ TEST_F(TodayServiceCase, QueryAppointments) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -239,20 +247,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceError) auto state = std::make_shared(2); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -275,7 +284,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceError) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -315,20 +324,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceErrorAsync) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 2 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 2 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -351,7 +361,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsWithForceErrorAsync) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); @@ -388,21 +398,22 @@ TEST_F(TodayServiceCase, QueryTasks) auto state = std::make_shared(3); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_GE(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getTasksCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 0 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->appointmentsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 3 }, state->tasksRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 3 }, state->tasksRequestId) + << "today service passed the same RequestState"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadAppointmentsCount) + EXPECT_EQ(std::size_t { 0 }, state->loadAppointmentsCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadTasksCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -418,7 +429,7 @@ TEST_F(TodayServiceCase, QueryTasks) const auto tasks = service::ScalarArgument::require("tasks", data); const auto taskEdges = service::ScalarArgument::require("edges", tasks); - ASSERT_EQ(size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, taskEdges.size()) << "tasks should have 1 entry"; ASSERT_TRUE(taskEdges[0].type() == response::Type::Map) << "task should be an object"; const auto taskNode = service::ScalarArgument::require("node", taskEdges[0]); EXPECT_EQ(today::getFakeTaskId(), service::IdArgument::require("taskId", taskNode)) @@ -451,21 +462,22 @@ TEST_F(TodayServiceCase, QueryUnreadCounts) auto state = std::make_shared(4); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_GE(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_EQ(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 0 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->appointmentsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 4 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 4 }, state->unreadCountsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->loadAppointmentsCount) + EXPECT_EQ(std::size_t { 0 }, state->loadAppointmentsCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadUnreadCountsCount) << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 1 }, state->loadUnreadCountsCount) + << "today service called the loader once"; try { @@ -480,7 +492,7 @@ TEST_F(TodayServiceCase, QueryUnreadCounts) const auto unreadCounts = service::ScalarArgument::require("unreadCounts", data); const auto unreadCountEdges = service::ScalarArgument::require("edges", unreadCounts); - ASSERT_EQ(size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, unreadCountEdges.size()) << "unreadCounts should have 1 entry"; ASSERT_TRUE(unreadCountEdges[0].type() == response::Type::Map) << "unreadCount should be an object"; const auto unreadCountNode = service::ScalarArgument::require("node", unreadCountEdges[0]); @@ -615,7 +627,8 @@ TEST_F(TodayServiceCase, SubscribeNextAppointmentChangeOverride) auto subscriptionObject = std::make_shared( [](const std::shared_ptr& state) -> std::shared_ptr { - EXPECT_EQ(size_t { 7 }, std::static_pointer_cast(state)->requestId) + EXPECT_EQ(std::size_t { 7 }, + std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; return std::make_shared( response::IdType(today::getFakeAppointmentId()), @@ -963,7 +976,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) capturedParams.pop(); const auto params1 = std::move(capturedParams.top()); capturedParams.pop(); - ASSERT_EQ(size_t { 1 }, params1.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params1.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag1 = params1.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag1->first == "queryTag"sv) << "missing required directive"; @@ -972,18 +985,19 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto fragmentDefinitionCount1 = params1.fragmentDefinitionDirectives.size(); const auto fragmentSpreadCount1 = params1.fragmentSpreadDirectives.size(); const auto inlineFragmentCount1 = params1.inlineFragmentDirectives.size(); - ASSERT_EQ(size_t { 1 }, params1.fieldDirectives.size()) << "missing operation directive"; + ASSERT_EQ(std::size_t { 1 }, params1.fieldDirectives.size()) + << "missing operation directive"; const auto itrFieldTag1 = params1.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag1->first == "fieldTag"sv) << "missing required directive"; const auto& fieldTag1 = itrFieldTag1->second; const auto field1 = service::StringArgument::require("field", fieldTag1); - ASSERT_EQ(size_t { 1 }, params2.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag2 = params2.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag2->first == "queryTag"sv) << "missing required directive"; const auto& queryTag2 = itrQueryTag2->second; const auto query2 = service::StringArgument::require("query", queryTag2); - ASSERT_EQ(size_t { 1 }, params2.fragmentDefinitionDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.fragmentDefinitionDirectives.size()) << "missing fragment definition directive"; const auto itrFragmentDefinitionTag2 = params2.fragmentDefinitionDirectives.cbegin(); ASSERT_TRUE(itrFragmentDefinitionTag2->first == "fragmentDefinitionTag"sv) @@ -991,7 +1005,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentDefinitionTag2 = itrFragmentDefinitionTag2->second; const auto fragmentDefinition2 = service::StringArgument::require("fragmentDefinition", fragmentDefinitionTag2); - ASSERT_EQ(size_t { 1 }, params2.fragmentSpreadDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params2.fragmentSpreadDirectives.size()) << "missing fragment spread directive"; const auto itrFragmentSpreadTag2 = params2.fragmentSpreadDirectives.cbegin(); ASSERT_TRUE(itrFragmentSpreadTag2->first == "fragmentSpreadTag"sv) @@ -1000,18 +1014,18 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto fragmentSpread2 = service::StringArgument::require("fragmentSpread", fragmentSpreadTag2); const auto inlineFragmentCount2 = params2.inlineFragmentDirectives.size(); - ASSERT_EQ(size_t { 1 }, params2.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 1 }, params2.fieldDirectives.size()) << "missing field directive"; const auto itrFieldTag2 = params2.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag2->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag2 = itrFieldTag2->second; const auto field2 = service::StringArgument::require("field", fieldTag2); - ASSERT_EQ(size_t { 1 }, params3.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag3 = params3.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag3->first == "queryTag"sv) << "missing required directive"; const auto& queryTag3 = itrQueryTag3->second; const auto query3 = service::StringArgument::require("query", queryTag3); - ASSERT_EQ(size_t { 1 }, params3.fragmentDefinitionDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.fragmentDefinitionDirectives.size()) << "missing fragment definition directive"; const auto itrFragmentDefinitionTag3 = params3.fragmentDefinitionDirectives.cbegin(); ASSERT_TRUE(itrFragmentDefinitionTag3->first == "fragmentDefinitionTag"sv) @@ -1019,7 +1033,7 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentDefinitionTag3 = itrFragmentDefinitionTag3->second; const auto fragmentDefinition3 = service::StringArgument::require("fragmentDefinition", fragmentDefinitionTag3); - ASSERT_EQ(size_t { 1 }, params3.fragmentSpreadDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.fragmentSpreadDirectives.size()) << "missing fragment spread directive"; const auto itrFragmentSpreadTag3 = params3.fragmentSpreadDirectives.cbegin(); ASSERT_TRUE(itrFragmentSpreadTag3->first == "fragmentSpreadTag"sv) @@ -1027,19 +1041,19 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto& fragmentSpreadTag3 = itrFragmentSpreadTag3->second; const auto fragmentSpread3 = service::StringArgument::require("fragmentSpread", fragmentSpreadTag3); - ASSERT_EQ(size_t { 1 }, params3.inlineFragmentDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params3.inlineFragmentDirectives.size()) << "missing inline fragment directive"; const auto itrInlineFragmentTag3 = params3.inlineFragmentDirectives.cbegin(); ASSERT_TRUE(itrInlineFragmentTag3->first == "inlineFragmentTag"sv); const auto& inlineFragmentTag3 = itrInlineFragmentTag3->second; const auto inlineFragment3 = service::StringArgument::require("inlineFragment", inlineFragmentTag3); - ASSERT_EQ(size_t { 1 }, params3.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 1 }, params3.fieldDirectives.size()) << "missing field directive"; const auto itrFieldTag3 = params3.fieldDirectives.cbegin(); ASSERT_TRUE(itrFieldTag3->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag3 = itrFieldTag3->second; const auto field3 = service::StringArgument::require("field", fieldTag3); - ASSERT_EQ(size_t { 1 }, params4.operationDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params4.operationDirectives.size()) << "missing operation directive"; const auto itrQueryTag4 = params4.operationDirectives.cbegin(); ASSERT_TRUE(itrQueryTag4->first == "queryTag"sv) << "missing required directive"; @@ -1047,19 +1061,20 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) const auto query4 = service::StringArgument::require("query", queryTag4); const auto fragmentDefinitionCount4 = params4.fragmentDefinitionDirectives.size(); const auto fragmentSpreadCount4 = params4.fragmentSpreadDirectives.size(); - ASSERT_EQ(size_t { 1 }, params4.inlineFragmentDirectives.size()) + ASSERT_EQ(std::size_t { 1 }, params4.inlineFragmentDirectives.size()) << "missing inline fragment directive"; const auto itrInlineFragmentTag4 = params4.inlineFragmentDirectives.cbegin(); ASSERT_TRUE(itrInlineFragmentTag4->first == "inlineFragmentTag"sv); const auto& inlineFragmentTag4 = itrInlineFragmentTag4->second; const auto inlineFragment4 = service::StringArgument::require("inlineFragment", inlineFragmentTag4); - ASSERT_EQ(size_t { 3 }, params4.fieldDirectives.size()) << "missing field directive"; + ASSERT_EQ(std::size_t { 3 }, params4.fieldDirectives.size()) << "missing field directive"; const auto itrRepeatable1 = params4.fieldDirectives.cbegin(); ASSERT_TRUE(itrRepeatable1->first == "repeatableOnField"sv) << "missing field directive"; EXPECT_TRUE(response::Type::Map == itrRepeatable1->second.type()) << "unexpected arguments type directive"; - EXPECT_EQ(size_t { 0 }, itrRepeatable1->second.size()) << "extra arguments on directive"; + EXPECT_EQ(std::size_t { 0 }, itrRepeatable1->second.size()) + << "extra arguments on directive"; const auto itrFieldTag4 = itrRepeatable1 + 1; ASSERT_TRUE(itrFieldTag4->first == "fieldTag"sv) << "missing field directive"; const auto& fieldTag4 = itrFieldTag4->second; @@ -1067,7 +1082,8 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) ASSERT_TRUE(itrRepeatable2->first == "repeatableOnField"sv) << "missing field directive"; EXPECT_TRUE(response::Type::Map == itrRepeatable2->second.type()) << "unexpected arguments type directive"; - EXPECT_EQ(size_t { 0 }, itrRepeatable2->second.size()) << "extra arguments on directive"; + EXPECT_EQ(std::size_t { 0 }, itrRepeatable2->second.size()) + << "extra arguments on directive"; const auto field4 = service::StringArgument::require("field", fieldTag4); ASSERT_EQ(1, depth1); @@ -1076,16 +1092,16 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) ASSERT_EQ(4, depth4); ASSERT_TRUE(capturedParams.empty()); ASSERT_EQ("nested", query1) << "remember the operation directives"; - ASSERT_EQ(size_t { 0 }, fragmentDefinitionCount1); - ASSERT_EQ(size_t { 0 }, fragmentSpreadCount1); - ASSERT_EQ(size_t { 0 }, inlineFragmentCount1); + ASSERT_EQ(std::size_t { 0 }, fragmentDefinitionCount1); + ASSERT_EQ(std::size_t { 0 }, fragmentSpreadCount1); + ASSERT_EQ(std::size_t { 0 }, inlineFragmentCount1); ASSERT_EQ("nested1", field1) << "remember the field directives"; ASSERT_EQ("nested", query2) << "remember the operation directives"; ASSERT_EQ("fragmentDefinition1", fragmentDefinition2) << "remember the directives from the fragment definition"; ASSERT_EQ("fragmentSpread1", fragmentSpread2) << "remember the directives from the fragment spread"; - ASSERT_EQ(size_t { 0 }, inlineFragmentCount2); + ASSERT_EQ(std::size_t { 0 }, inlineFragmentCount2); ASSERT_EQ("nested2", field2) << "remember the field directives"; ASSERT_EQ("nested", query3) << "remember the operation directives"; ASSERT_EQ("fragmentDefinition2", fragmentDefinition3) @@ -1096,10 +1112,10 @@ TEST_F(TodayServiceCase, NestedFragmentDirectives) << "remember the directives from the inline fragment"; ASSERT_EQ("nested3", field3) << "remember the field directives"; ASSERT_EQ("nested", query4) << "remember the operation directives"; - ASSERT_EQ(size_t { 0 }, fragmentDefinitionCount4) + ASSERT_EQ(std::size_t { 0 }, fragmentDefinitionCount4) << "traversing a field to a nested object SelectionSet resets the fragment " "directives"; - ASSERT_EQ(size_t { 0 }, fragmentSpreadCount4) + ASSERT_EQ(std::size_t { 0 }, fragmentSpreadCount4) << "traversing a field to a nested object SelectionSet resets the fragment " "directives"; ASSERT_EQ("inlineFragment5", inlineFragment4) @@ -1128,20 +1144,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsById) auto state = std::make_shared(12); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 12 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 12 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1156,7 +1173,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1186,7 +1203,7 @@ TEST_F(TodayServiceCase, UnimplementedFieldError) ASSERT_TRUE(result.type() == response::Type::Map); const auto& errors = result["errors"]; ASSERT_TRUE(errors.type() == response::Type::List); - ASSERT_EQ(size_t { 1 }, errors.size()); + ASSERT_EQ(std::size_t { 1 }, errors.size()); response::Value error { errors[0] }; ASSERT_TRUE(error.type() == response::Type::Map); ASSERT_EQ( @@ -1219,7 +1236,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeMatchingId) const std::shared_ptr& state, response::IdType&& idArg) -> std::shared_ptr { EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 13 }, + EXPECT_EQ(std::size_t { 13 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(today::getFakeTaskId(), idArg); @@ -1366,7 +1383,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeFuzzyComparator) const response::IdType fuzzyId { 'f', 'a', 'k' }; EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 14 }, + EXPECT_EQ(std::size_t { 14 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(fuzzyId, idArg); @@ -1514,7 +1531,7 @@ TEST_F(TodayServiceCase, SubscribeNodeChangeMatchingVariable) const std::shared_ptr& state, response::IdType&& idArg) -> std::shared_ptr { EXPECT_EQ(expectedContext, resolverContext); - EXPECT_EQ(size_t { 14 }, + EXPECT_EQ(std::size_t { 14 }, std::static_pointer_cast(state)->requestId) << "should pass the RequestState to the subscription resolvers"; EXPECT_EQ(today::getFakeTaskId(), idArg); @@ -1587,20 +1604,21 @@ TEST_F(TodayServiceCase, DeferredQueryAppointmentsById) auto state = std::make_shared(15); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 15 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 15 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1615,7 +1633,7 @@ TEST_F(TodayServiceCase, DeferredQueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1650,20 +1668,21 @@ TEST_F(TodayServiceCase, NonBlockingQueryAppointmentsById) auto result = _mockService->service ->resolve({ query, {}, std::move(variables), std::launch::async, state }) .get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 16 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 16 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1678,7 +1697,7 @@ TEST_F(TodayServiceCase, NonBlockingQueryAppointmentsById) const auto appointmentsById = service::ScalarArgument::require("appointmentsById", data); - ASSERT_EQ(size_t { 1 }, appointmentsById.size()); + ASSERT_EQ(std::size_t { 1 }, appointmentsById.size()); const auto& appointmentEntry = appointmentsById.front(); EXPECT_EQ(today::getFakeAppointmentId(), service::IdArgument::require("appointmentId", appointmentEntry)) @@ -1868,20 +1887,21 @@ TEST_F(TodayServiceCase, QueryAppointmentsThroughUnionTypeFragment) auto state = std::make_shared(20); auto result = _mockService->service->resolve({ query, {}, std::move(variables), {}, state }).get(); - EXPECT_EQ(size_t { 1 }, _mockService->getAppointmentsCount) + EXPECT_EQ(std::size_t { 1 }, _mockService->getAppointmentsCount) << "today service lazy loads the appointments and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getTasksCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getTasksCount) << "today service lazy loads the tasks and caches the result"; - EXPECT_GE(size_t { 1 }, _mockService->getUnreadCountsCount) + EXPECT_GE(std::size_t { 1 }, _mockService->getUnreadCountsCount) << "today service lazy loads the unreadCounts and caches the result"; - EXPECT_EQ(size_t { 20 }, state->appointmentsRequestId) + EXPECT_EQ(std::size_t { 20 }, state->appointmentsRequestId) << "today service passed the same RequestState"; - EXPECT_EQ(size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->unreadCountsRequestId) + EXPECT_EQ(std::size_t { 0 }, state->tasksRequestId) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->unreadCountsRequestId) << "today service did not call the loader"; - EXPECT_EQ(size_t { 1 }, state->loadAppointmentsCount) << "today service called the loader once"; - EXPECT_EQ(size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; - EXPECT_EQ(size_t { 0 }, state->loadUnreadCountsCount) + EXPECT_EQ(std::size_t { 1 }, state->loadAppointmentsCount) + << "today service called the loader once"; + EXPECT_EQ(std::size_t { 0 }, state->loadTasksCount) << "today service did not call the loader"; + EXPECT_EQ(std::size_t { 0 }, state->loadUnreadCountsCount) << "today service did not call the loader"; try @@ -1897,7 +1917,7 @@ TEST_F(TodayServiceCase, QueryAppointmentsThroughUnionTypeFragment) const auto appointments = service::ScalarArgument::require("appointments", data); const auto appointmentEdges = service::ScalarArgument::require("edges", appointments); - ASSERT_EQ(size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; + ASSERT_EQ(std::size_t { 1 }, appointmentEdges.size()) << "appointments should have 1 entry"; ASSERT_TRUE(appointmentEdges[0].type() == response::Type::Map) << "appointment should be an object"; const auto appointmentNode = service::ScalarArgument::require("node", appointmentEdges[0]); diff --git a/test/ValidationTests.cpp b/test/ValidationTests.cpp index 06af8b05..de1cb550 100644 --- a/test/ValidationTests.cpp +++ b/test/ValidationTests.cpp @@ -8,6 +8,7 @@ #include "graphqlservice/JSONResponse.h" #include +#include using namespace graphql; @@ -50,7 +51,7 @@ TEST_F(ValidationExamplesCase, CounterExample102) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 2 }); + ASSERT_EQ(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined field type: Dog name: color","locations":[{"line":4,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -102,7 +103,7 @@ TEST_F(ValidationExamplesCase, CounterExample104) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate operation name: getName","locations":[{"line":7,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -127,7 +128,7 @@ TEST_F(ValidationExamplesCase, CounterExample105) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate operation name: dogOperation","locations":[{"line":7,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -168,7 +169,7 @@ TEST_F(ValidationExamplesCase, CounterExample107) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Anonymous operation not alone","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -223,7 +224,7 @@ TEST_F(ValidationExamplesCase, CounterExample110) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with more than one root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -248,7 +249,7 @@ TEST_F(ValidationExamplesCase, CounterExample111) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with more than one root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -265,7 +266,7 @@ TEST_F(ValidationExamplesCase, CounterExample112) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 1 }); + ASSERT_EQ(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Subscription with Introspection root field name: sub","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -286,8 +287,8 @@ TEST_F(ValidationExamplesCase, CounterExample113) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 undefined fields + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 undefined fields + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined field type: Dog name: meowVolume","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -326,8 +327,8 @@ TEST_F(ValidationExamplesCase, CounterExample115) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined field type: Pet name: nickname","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -369,8 +370,8 @@ TEST_F(ValidationExamplesCase, CounterExample117) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) << "2 undefined fields + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "2 undefined fields + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Field on union type: CatOrDog name: name","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -417,8 +418,8 @@ TEST_F(ValidationExamplesCase, CounterExample119) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Dog name: name","locations":[{"line":3,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -481,9 +482,9 @@ TEST_F(ValidationExamplesCase, CounterExample121) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 9 }) + EXPECT_EQ(errors.size(), std::size_t { 9 }) << "4 conflicting fields + 1 missing argument + 4 unused fragments"; - ASSERT_GE(errors.size(), size_t { 4 }); + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Dog name: doesKnowCommand","locations":[{"line":3,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -550,8 +551,8 @@ TEST_F(ValidationExamplesCase, CounterExample123) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting field type: Cat name: meowVolume","locations":[{"line":6,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -588,8 +589,8 @@ TEST_F(ValidationExamplesCase, CounterExample125) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 invalid field + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 invalid field + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Field on scalar type: Int name: sinceWhen","locations":[{"line":3,"column":5}]})js", response::toJSON(std::move(errors[0]))) @@ -639,7 +640,7 @@ TEST_F(ValidationExamplesCase, CounterExample127) auto errors = service::buildErrorValues(_service->validate(query)).release(); - ASSERT_EQ(errors.size(), size_t { 3 }) << "3 invalid fields"; + ASSERT_EQ(errors.size(), std::size_t { 3 }) << "3 invalid fields"; EXPECT_EQ( R"js({"message":"Missing fields on non-scalar type: Human","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -687,9 +688,9 @@ TEST_F(ValidationExamplesCase, CounterExample129) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 undefined argument + 1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined argument type: Dog field: doesKnowCommand name: command","locations":[{"line":2,"column":20}]})js", response::toJSON(std::move(errors[0]))) @@ -706,9 +707,9 @@ TEST_F(ValidationExamplesCase, CounterExample130) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 undefined argument + 1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined argument directive: include name: unless","locations":[{"line":2,"column":48}]})js", response::toJSON(std::move(errors[0]))) @@ -808,8 +809,8 @@ TEST_F(ValidationExamplesCase, CounterExample135) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 missing argument + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Missing argument type: Arguments field: nonNullBooleanArgField name: nonNullBooleanArg","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -826,8 +827,8 @@ TEST_F(ValidationExamplesCase, CounterExample136) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 missing argument + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 missing argument + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Required non-null argument type: Arguments field: nonNullBooleanArgField name: nonNullBooleanArg","locations":[{"line":2,"column":4}]})js", response::toJSON(std::move(errors[0]))) @@ -881,8 +882,8 @@ TEST_F(ValidationExamplesCase, CounterExample138) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 duplicate fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 duplicate fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Duplicate fragment name: fragmentOne","locations":[{"line":11,"column":3}]})js", response::toJSON(std::move(errors[0]))) @@ -937,8 +938,8 @@ TEST_F(ValidationExamplesCase, CounterExample140) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 not existing types + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 not existing types + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined target type on fragment definition: notOnExistingType name: NotInSchema","locations":[{"line":1,"column":28}]})js", response::toJSON(std::move(errors[0]))) @@ -995,8 +996,8 @@ TEST_F(ValidationExamplesCase, CounterExample142) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 not existing types + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 not existing types + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Scalar target type on fragment definition: fragOnScalar name: Int","locations":[{"line":1,"column":23}]})js", response::toJSON(std::move(errors[0]))) @@ -1023,8 +1024,8 @@ TEST_F(ValidationExamplesCase, CounterExample143) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused fragment definition name: nameFragment","locations":[{"line":1,"column":1}]})js", response::toJSON(std::move(errors[0]))) @@ -1043,8 +1044,8 @@ TEST_F(ValidationExamplesCase, CounterExample144) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined fragment + 1 missing field"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined fragment + 1 missing field"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined fragment spread name: undefinedFragment","locations":[{"line":3,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1073,8 +1074,8 @@ TEST_F(ValidationExamplesCase, CounterExample145) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "2 cyclic fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "2 cyclic fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Cyclic fragment spread name: nameFragment","locations":[{"line":14,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1134,8 +1135,8 @@ TEST_F(ValidationExamplesCase, CounterExample147) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "2 cyclic fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "2 cyclic fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Cyclic fragment spread name: dogFragment","locations":[{"line":19,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1178,8 +1179,8 @@ TEST_F(ValidationExamplesCase, CounterExample149) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible type + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 incompatible type + 1 unused fragment"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible target type on inline fragment name: Cat","locations":[{"line":2,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1278,8 +1279,8 @@ TEST_F(ValidationExamplesCase, CounterExample153) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "2 incompatible type + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "2 incompatible type + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Incompatible target type on inline fragment name: Dog","locations":[{"line":2,"column":8}]})js", response::toJSON(std::move(errors[0]))) @@ -1328,8 +1329,8 @@ TEST_F(ValidationExamplesCase, CounterExample155) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 3 }) << "1 incompatible type + 2 unused fragments"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 3 }) << "1 incompatible type + 2 unused fragments"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible fragment spread target type: Sentient name: sentientFragment","locations":[{"line":2,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1402,9 +1403,9 @@ TEST_F(ValidationExamplesCase, CounterExample158) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 5 }) + EXPECT_EQ(errors.size(), std::size_t { 5 }) << "2 expected values + 2 incompatible arguments + 1 unused fragment"; - ASSERT_GE(errors.size(), size_t { 4 }); + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ(R"js({"message":"Expected Int value","locations":[{"line":2,"column":24}]})js", response::toJSON(std::move(errors[0]))) << "error should match"; @@ -1447,8 +1448,8 @@ TEST_F(ValidationExamplesCase, CounterExample160) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined field + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 2 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined field + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 2 }); EXPECT_EQ( R"js({"message":"Undefined Input Object field type: ComplexInput name: favoriteCookieFlavor","locations":[{"line":2,"column":45}]})js", response::toJSON(std::move(errors[0]))) @@ -1471,8 +1472,8 @@ TEST_F(ValidationExamplesCase, CounterExample161) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 conflicting field"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 conflicting field"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting input field name: name","locations":[{"line":2,"column":37}]})js", response::toJSON(std::move(errors[0]))) @@ -1491,8 +1492,8 @@ TEST_F(ValidationExamplesCase, CounterExample162) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unexpected location"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unexpected location"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unexpected location for directive: skip name: QUERY","locations":[{"line":1,"column":7}]})js", response::toJSON(std::move(errors[0]))) @@ -1511,8 +1512,8 @@ TEST_F(ValidationExamplesCase, CounterExample163) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 conflicting directive + 1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 conflicting directive + 1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting directive name: skip","locations":[{"line":2,"column":24}]})js", response::toJSON(std::move(errors[0]))) @@ -1548,8 +1549,8 @@ TEST_F(ValidationExamplesCase, CounterExample165) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 conflicting variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 conflicting variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Conflicting variable operation: houseTrainedQuery name: atOtherHomes","locations":[{"line":1,"column":49}]})js", response::toJSON(std::move(errors[0]))) @@ -1646,8 +1647,8 @@ TEST_F(ValidationExamplesCase, CounterExample169) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 4 }) << "4 invalid variable types"; - ASSERT_GE(errors.size(), size_t { 4 }); + EXPECT_EQ(errors.size(), std::size_t { 4 }) << "4 invalid variable types"; + ASSERT_GE(errors.size(), std::size_t { 4 }); EXPECT_EQ( R"js({"message":"Invalid variable type operation: takesCat name: cat","locations":[{"line":1,"column":22}]})js", response::toJSON(std::move(errors[0]))) @@ -1692,8 +1693,8 @@ TEST_F(ValidationExamplesCase, CounterExample171) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":3,"column":34}]})js", response::toJSON(std::move(errors[0]))) @@ -1734,8 +1735,8 @@ TEST_F(ValidationExamplesCase, CounterExample173) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":8,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1762,8 +1763,8 @@ TEST_F(ValidationExamplesCase, CounterExample174) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":12,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1816,8 +1817,8 @@ TEST_F(ValidationExamplesCase, CounterExample176) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) << "1 undefined variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Undefined variable name: atOtherHomes","locations":[{"line":14,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1836,8 +1837,8 @@ TEST_F(ValidationExamplesCase, CounterExample177) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: atOtherHomes","locations":[{"line":1,"column":22}]})js", response::toJSON(std::move(errors[0]))) @@ -1878,8 +1879,8 @@ TEST_F(ValidationExamplesCase, CounterExample179) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: atOtherHomes","locations":[{"line":1,"column":37}]})js", response::toJSON(std::move(errors[0]))) @@ -1908,8 +1909,8 @@ TEST_F(ValidationExamplesCase, CounterExample180) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 1 }) << "1 unused variable"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 1 }) << "1 unused variable"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Unused variable name: extra","locations":[{"line":7,"column":51}]})js", response::toJSON(std::move(errors[0]))) @@ -1928,8 +1929,9 @@ TEST_F(ValidationExamplesCase, CounterExample181) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Incompatible variable type: Int name: Boolean","locations":[{"line":3,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1948,8 +1950,9 @@ TEST_F(ValidationExamplesCase, CounterExample182) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Scalar variable type","locations":[{"line":3,"column":33}]})js", response::toJSON(std::move(errors[0]))) @@ -1968,8 +1971,9 @@ TEST_F(ValidationExamplesCase, CounterExample183) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Non-Null variable type","locations":[{"line":3,"column":47}]})js", response::toJSON(std::move(errors[0]))) @@ -2002,8 +2006,9 @@ TEST_F(ValidationExamplesCase, CounterExample185) auto errors = service::buildErrorValues(_service->validate(query)).release(); - EXPECT_EQ(errors.size(), size_t { 2 }) << "1 incompatible variable + 1 incompatible argument"; - ASSERT_GE(errors.size(), size_t { 1 }); + EXPECT_EQ(errors.size(), std::size_t { 2 }) + << "1 incompatible variable + 1 incompatible argument"; + ASSERT_GE(errors.size(), std::size_t { 1 }); EXPECT_EQ( R"js({"message":"Expected Non-Null variable type","locations":[{"line":3,"column":52}]})js", response::toJSON(std::move(errors[0])))