Repository: graphql-markdown/graphql-markdown
Pull request #932 (2023-08-09 09:02:24)

:recycle:  improve core checks and tests
# Description

Minor improvements on core methods, and add generator tests.

# Checklist

- [x] My changes follow the [contributing guidelines](https://github.com/graphql-markdown/graphql-markdown/blob/main/CONTRIBUTING.md) of this project.
- [x] I have performed a self-review of my code.
- [ ] I have made corresponding changes to the documentation.
- [x] I have added tests that prove my fix is effective or that my changes work.
- [x] New and existing unit tests pass locally with my changes.


codesee-maps[bot]: <details open>
<summary><b>👇 <a href="https://app.codesee.io/r/reviews?pr=932&src=https%3A%2F%2Fgithub.com%2Fgraphql-markdown%2Fgraphql-markdown">Click on the image</a> for a new way to code review</b>
</summary>

####

[![Review these changes using an interactive CodeSee Map](https://s3.us-east-2.amazonaws.com/maps.codesee.io/images/github/graphql-markdown/graphql-markdown/932/952c9cd4/321f48d876da4ee73a8f605eb03afa9e5cfe4ab1.svg)](https://app.codesee.io/r/reviews?pr=932&src=https%3A%2F%2Fgithub.com%2Fgraphql-markdown%2Fgraphql-markdown)

#### Legend
<img src="https://app.codesee.io/Legend_v3.png" alt="CodeSee Map legend" width="220" height="156">
</details>
sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [1 Code Smell](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![0.0%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/3-16px.png '0.0%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [0.0% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)


coveralls: 
[![Coverage Status](https://coveralls.io/builds/61873543/badge)](https://coveralls.io/builds/61873543)

coverage: 93.514% (+0.1%) from 93.39% when pulling **321f48d876da4ee73a8f605eb03afa9e5cfe4ab1 on chore/improve-core** into **ace34753e56704bf5a8721a7643cca374127d6ee on main**.

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![7.2%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/10-16px.png '7.2%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [7.2% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [1 Security Hotspot](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![4.2%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '4.2%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [4.2% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![E](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/E-16px.png 'E')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [1 Security Hotspot](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![3.6%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.6%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [3.6% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![3.6%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.6%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [3.6% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=graphql-markdown_graphql-markdown&pullRequest=932)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=graphql-markdown_graphql-markdown&pullRequest=932&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932) No Coverage information  
[![3.6%](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/5-16px.png '3.6%')](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list) [3.6% Duplication](https://sonarcloud.io/component_measures?id=graphql-markdown_graphql-markdown&pullRequest=932&metric=new_duplicated_lines_density&view=list)



Patch:
diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts
index ae3634b0..0fac64dc 100644
--- a/packages/core/src/config.ts
+++ b/packages/core/src/config.ts
@@ -14,6 +14,7 @@ import type {
   Maybe,
   Options,
   PackageName,
+  TypeDeprecatedOption,
   TypeDiffMethod,
 } from "@graphql-markdown/types";
 
@@ -90,7 +91,7 @@ export async function buildConfig(
     ...configFileOpts,
   } as const;
 
-  const baseURL = cliOpts.base ?? config.baseURL!;
+  const baseURL: string = cliOpts.base ?? config.baseURL!;
   const skipDocDirective = getSkipDocDirectives(cliOpts, config);
 
   return {
@@ -118,7 +119,7 @@ export async function buildConfig(
     schemaLocation: cliOpts.schema ?? config.schema ?? DEFAULT_OPTIONS.schema,
     skipDocDirective,
     tmpDir: cliOpts.tmp ?? config.tmpDir ?? DEFAULT_OPTIONS.tmpDir,
-  };
+  } as Options;
 }
 
 export function getCustomDirectives(
@@ -142,8 +143,9 @@ export function getCustomDirectives(
     ) {
       delete customDirectiveOptions[name as DirectiveName];
     } else if (
-      (!("descriptor" in option) || typeof option.descriptor !== "function") &&
-      (!("tag" in option) || typeof option.tag !== "function")
+      ("descriptor" in option && typeof option.descriptor !== "function") ||
+      ("tag" in option && typeof option.tag !== "function") ||
+      !("tag" in option || "descriptor" in option)
     ) {
       throw new Error(
         `Wrong format for plugin custom directive "${name}".\nPlease refer to ${DOCS_URL}/advanced/custom-directive`,
@@ -160,7 +162,9 @@ export function getDiffMethod(
   diff: TypeDiffMethod,
   force: boolean = false,
 ): TypeDiffMethod {
-  return force ? DiffMethod.FORCE : diff;
+  return force
+    ? DiffMethod.FORCE
+    : (diff.toLocaleUpperCase() as TypeDiffMethod);
 }
 
 export function getDocOptions(
@@ -177,7 +181,7 @@ export function getDocOptions(
     index:
       (cliOpts?.index || configOptions?.index) ??
       DEFAULT_OPTIONS.docOptions.index!,
-  };
+  } as Required<ConfigDocOptions>;
 }
 
 export function getPrintTypeOptions(
@@ -188,10 +192,11 @@ export function getPrintTypeOptions(
     codeSection:
       (!cliOpts?.noCode && configOptions?.codeSection) ??
       DEFAULT_OPTIONS.printTypeOptions.codeSection!,
-    deprecated:
-      cliOpts?.deprecated ??
-      configOptions?.deprecated ??
-      DEFAULT_OPTIONS.printTypeOptions.deprecated!,
+    deprecated: (
+      (cliOpts?.deprecated ??
+        configOptions?.deprecated ??
+        DEFAULT_OPTIONS.printTypeOptions.deprecated!) as string
+    ).toLocaleLowerCase() as TypeDeprecatedOption,
     parentTypePrefix:
       (!cliOpts?.noParentType && configOptions?.parentTypePrefix) ??
       DEFAULT_OPTIONS.printTypeOptions.parentTypePrefix!,
@@ -201,7 +206,7 @@ export function getPrintTypeOptions(
     typeBadges:
       (!cliOpts?.noTypeBadges && configOptions?.typeBadges) ??
       DEFAULT_OPTIONS.printTypeOptions.typeBadges!,
-  };
+  } as Required<ConfigPrintTypeOptions>;
 }
 
 export function getSkipDocDirectives(
diff --git a/packages/core/src/generator.ts b/packages/core/src/generator.ts
index af6d6437..4ce0b218 100644
--- a/packages/core/src/generator.ts
+++ b/packages/core/src/generator.ts
@@ -1,6 +1,6 @@
 import type {
   DiffMethodName,
-  Options,
+  GeneratorOptions,
   SchemaEntity,
 } from "@graphql-markdown/types";
 
@@ -21,35 +21,31 @@ import { DiffMethod } from "./config";
 const NS_PER_SEC = 1e9 as const;
 const SEC_DECIMALS = 3 as const;
 
-export type GeneratorOptions = Options & { loggerModule?: string };
-
 export const generateDocFromSchema = async ({
   baseURL,
-  schemaLocation,
-  outputDir,
-  linkRoot,
-  homepageLocation,
+  customDirective,
   diffMethod,
-  tmpDir,
-  loaders: loadersList,
+  docOptions,
   groupByDirective,
+  homepageLocation,
+  linkRoot,
+  loaders: loadersList,
+  loggerModule,
+  outputDir,
   prettify,
-  docOptions,
-  printTypeOptions,
   printer: printerModule,
+  printTypeOptions,
+  schemaLocation,
   skipDocDirective,
-  customDirective,
-  loggerModule,
+  tmpDir,
 }: GeneratorOptions): Promise<void> => {
   const start = process.hrtime.bigint();
 
   const logger = Logger.setInstance(loggerModule);
 
-  const loaders = loadersList
-    ? await getDocumentLoaders(loadersList)
-    : undefined;
+  const loaders = await getDocumentLoaders(loadersList);
 
-  if (typeof loaders === "undefined") {
+  if (typeof loaders === "undefined" || loaders === null) {
     logger.error(
       `An error occurred while loading GraphQL loader.\nCheck your dependencies and configuration.`,
     );
@@ -78,17 +74,17 @@ export const generateDocFromSchema = async ({
 
     // config mandatory
     {
-      schema,
       baseURL,
       linkRoot,
+      schema,
     },
 
     // options
     {
+      customDirectives,
       groups,
       printTypeOptions,
       skipDocDirective,
-      customDirectives,
     },
   );
   const renderer = new Renderer(printer, outputDir, baseURL, groups, prettify, {
diff --git a/packages/core/src/graphql-config.ts b/packages/core/src/graphql-config.ts
index a5695f5d..e466adbc 100644
--- a/packages/core/src/graphql-config.ts
+++ b/packages/core/src/graphql-config.ts
@@ -13,6 +13,7 @@ import { Logger } from "@graphql-markdown/utils";
 const logger = Logger.getInstance();
 
 export const EXTENSION_NAME = "graphql-markdown" as const;
+export const GraphQLConfigExtension = () => ({ name: EXTENSION_NAME }) as const;
 
 type ThrowOptions = {
   throwOnMissing: boolean;
@@ -23,7 +24,7 @@ type Writeable<T> = { -readonly [P in keyof T]: T[P] };
 export type ExtensionProjectConfig = Writeable<GraphQLProjectConfig> &
   Omit<ConfigOptions, "schema">;
 
-const setLoaderOptions = (
+export const setLoaderOptions = (
   loaders: LoaderOption,
   options: PackageOptionsConfig,
 ) => {
@@ -66,22 +67,29 @@ export const loadConfiguration = async (
 
   const config = await GraphQLConfig.loadConfig({
     ...options,
-    extensions: [() => ({ name: EXTENSION_NAME })],
+    extensions: [GraphQLConfigExtension],
     throwOnMissing,
     throwOnEmpty,
   });
 
+  if (typeof config === "undefined") {
+    return undefined;
+  }
+
   try {
-    const projectConfig: ExtensionProjectConfig = config!
+    const projectConfig: ExtensionProjectConfig = config
       .getProject(id)
       .extension(EXTENSION_NAME);
 
-    if (Array.isArray(projectConfig?.schema)) {
-      const schema = projectConfig?.schema[0];
+    if (Array.isArray(projectConfig.schema)) {
+      const schema = projectConfig.schema[0];
       if (typeof schema === "string") {
         projectConfig.schema = schema;
-      } else {
+      }
+
+      if (typeof projectConfig.schema === "object") {
         projectConfig.schema = Object.keys(schema)[0];
+
         if (typeof projectConfig.loaders !== "undefined") {
           projectConfig.loaders = setLoaderOptions(
             projectConfig.loaders,
@@ -90,6 +98,7 @@ export const loadConfiguration = async (
         }
       }
     }
+
     return projectConfig as Readonly<ExtensionProjectConfig>;
   } catch (error) {
     return undefined;
diff --git a/packages/core/src/renderer.ts b/packages/core/src/renderer.ts
index 8243ec01..7e06c6cf 100644
--- a/packages/core/src/renderer.ts
+++ b/packages/core/src/renderer.ts
@@ -29,7 +29,6 @@ import {
 const logger = Logger.getInstance();
 
 const SIDEBAR = "sidebar-schema.js" as const;
-const HOMEPAGE_ID = "schema" as const;
 const CATEGORY_YAML = "_category_.yml" as const;
 
 enum SIDEBAR_POSITION {
@@ -161,7 +160,7 @@ export class Renderer {
     type: unknown,
   ): Promise<Maybe<Category>> {
     const PageRegex =
-      /(?<category>[A-Za-z0-9-]+)[\\/]+(?<pageId>[A-Za-z0-9-]+).mdx?$/;
+      /(?<category>[A-Za-z0-9-]+)[\\/]+(?<pageId>[A-Za-z0-9-]+).mdx$/;
 
     const fileName = toSlug(name);
     const filePath = join(normalize(dirPath), `${fileName}.mdx`);
@@ -193,7 +192,7 @@ export class Renderer {
 
     if (typeof page === "undefined" || typeof page?.groups === "undefined") {
       logger.warn(
-        `An error occurred while processing file $filePath for type "${type}"`,
+        `An error occurred while processing file ${filePath} for type "${type}"`,
       );
       return undefined;
     }
@@ -207,30 +206,13 @@ export class Renderer {
   }
 
   async renderSidebar(): Promise<string> {
-    const schemaSidebar = [
-      {
-        type: "autogenerated",
-        dirName: ".",
-      },
-    ];
-
-    type SidebarItem = { type: string; id: string; dirName: string };
-
     const sidebar = {
-      schemaSidebar: (schemaSidebar as unknown as SidebarItem[]).map(
-        (entry) => {
-          switch (entry.type) {
-            case "doc":
-              entry.id = pathUrl.join(this.baseURL, HOMEPAGE_ID);
-              break;
-            case "autogenerated":
-              entry.dirName = this.baseURL;
-              break;
-            default: //do nothing
-          }
-          return entry;
+      schemaSidebar: [
+        {
+          type: "autogenerated",
+          dirName: this.baseURL,
         },
-      ),
+      ],
     };
 
     const jsonSidebar = `
@@ -246,7 +228,7 @@ module.exports = ${JSON.stringify(sidebar, null, 2)};
       this.prettify ? prettifyJavascript : undefined,
     );
 
-    return relative("./", filePath);
+    return filePath;
   }
 
   async renderHomepage(homepageLocation: string): Promise<void> {
@@ -262,6 +244,7 @@ module.exports = ${JSON.stringify(sidebar, null, 2)};
       .toString()
       .replace(/##baseURL##/gm, slug)
       .replace(/##generated-date-time##/gm, new Date().toLocaleString());
+
     await saveFile(destLocation, data);
   }
 }
diff --git a/packages/types/src/core.d.ts b/packages/types/src/core.d.ts
index 7544a4fd..d5332d03 100644
--- a/packages/types/src/core.d.ts
+++ b/packages/types/src/core.d.ts
@@ -3,10 +3,10 @@ import type { UnnormalizedTypeDefPointer } from "@graphql-tools/load";
 
 import type {
   CustomDirective,
+  DirectiveName,
   GroupByDirectiveOptions,
-  PackageName,
   LoaderOption,
-  DirectiveName,
+  PackageName,
 } from ".";
 
 export type ConfigDocOptions = {
@@ -32,13 +32,13 @@ export type TypeDiffMethod = DiffMethodName | "NONE" | "FORCE";
 type Pointer = string | UnnormalizedTypeDefPointer;
 
 export type ConfigOptions = {
-  id?: Maybe<string>;
   baseURL?: Maybe<string>;
   customDirective?: Maybe<CustomDirective>;
   diffMethod?: Maybe<TypeDiffMethod>;
   docOptions?: Maybe<ConfigDocOptions>;
   groupByDirective?: Maybe<GroupByDirectiveOptions>;
   homepage?: Maybe<string>;
+  id?: Maybe<string>;
   linkRoot?: Maybe<string>;
   loaders?: Maybe<LoaderOption>;
   pretty?: Maybe<boolean>;
@@ -46,47 +46,47 @@ export type ConfigOptions = {
   printTypeOptions?: Maybe<ConfigPrintTypeOptions>;
   rootPath?: Maybe<string>;
   schema?: Maybe<Pointer>;
-  tmpDir?: Maybe<string>;
   skipDocDirective?: Maybe<DirectiveName[] | DirectiveName>;
+  tmpDir?: Maybe<string>;
 };
 
 export type CliOptions = {
-  schema?: Pointer;
-  root?: string;
   base?: string;
-  link?: string;
+  deprecated?: TypeDeprecatedOption;
+  diff?: TypeDiffMethod;
+  force?: boolean;
+  groupByDirective?: string;
   homepage?: string;
+  index?: boolean;
+  link?: string;
   noCode?: boolean;
   noPagination?: boolean;
   noParentType?: boolean;
   noRelatedType?: boolean;
   noToc?: boolean;
   noTypeBadges?: boolean;
-  index?: boolean;
-  force?: boolean;
-  diff?: TypeDiffMethod;
-  tmp?: string;
-  groupByDirective?: string;
-  skip?: string[] | string;
-  deprecated?: TypeDeprecatedOption;
   pretty?: boolean;
+  root?: string;
+  schema?: Pointer;
+  skip?: string[] | string;
+  tmp?: string;
 };
 
 export type Options = Omit<
   ConfigOptions,
   "homepage" | "pretty" | "schema" | "rootPath"
 > & {
+  baseURL: string;
+  docOptions: Required<ConfigDocOptions>;
   homepageLocation: string;
+  linkRoot: string;
   outputDir: string;
   prettify: boolean;
-  schemaLocation: Pointer;
   printer: PackageName;
-  tmpDir: string;
-  baseURL: string;
-  linkRoot: string;
-  skipDocDirective: DirectiveName[];
-  docOptions: Required<ConfigDocOptions>;
   printTypeOptions: Required<ConfigPrintTypeOptions>;
+  schemaLocation: Pointer;
+  skipDocDirective: DirectiveName[];
+  tmpDir: string;
 };
 
 export type FunctionCheckSchemaChanges = (
@@ -95,4 +95,6 @@ export type FunctionCheckSchemaChanges = (
   diffMethod?: DiffMethodName,
 ) => Promise<boolean>;
 
+export type GeneratorOptions = Options & { loggerModule?: string };
+
 export type { GraphQLProjectConfig } from "graphql-config";
diff --git a/packages/types/src/utils.d.ts b/packages/types/src/utils.d.ts
index f0c89ac1..f2c38ad4 100644
--- a/packages/types/src/utils.d.ts
+++ b/packages/types/src/utils.d.ts
@@ -115,3 +115,5 @@ export type Category = { category: string; slug: string };
 
 export type MDXString = string & { _opaque: typeof MDXString };
 declare const MDXString: unique symbol;
+
+export type { LoadSchemaOptions } from "@graphql-tools/load";
diff --git a/packages/utils/src/graphql.ts b/packages/utils/src/graphql.ts
index 14770e72..93c3b475 100644
--- a/packages/utils/src/graphql.ts
+++ b/packages/utils/src/graphql.ts
@@ -1,6 +1,19 @@
 import {
   getDirectiveValues,
   getNamedType,
+  GraphQLBoolean,
+  GraphQLDirective,
+  GraphQLEnumType,
+  GraphQLFloat,
+  GraphQLID,
+  GraphQLInputObjectType,
+  GraphQLInt,
+  GraphQLInterfaceType,
+  GraphQLObjectType,
+  GraphQLScalarType,
+  GraphQLSchema,
+  GraphQLString,
+  GraphQLUnionType,
   isDirective as isDirectiveType,
   isEnumType,
   isInterfaceType,
@@ -9,36 +22,16 @@ import {
   isObjectType,
   isUnionType,
   OperationTypeNode,
-  GraphQLSchema,
-  GraphQLInt,
-  GraphQLFloat,
-  GraphQLBoolean,
-  GraphQLID,
-  GraphQLString,
-  GraphQLDirective,
-  GraphQLObjectType,
-  GraphQLScalarType,
-  GraphQLUnionType,
-  GraphQLInputObjectType,
-  GraphQLInterfaceType,
-  GraphQLEnumType,
 } from "graphql";
-import {
-  loadSchema as asyncLoadSchema,
-  LoadSchemaOptions,
-} from "@graphql-tools/load";
+import { loadSchema as asyncLoadSchema } from "@graphql-tools/load";
 import { Loader } from "graphql-config";
 
 import type {
-  LoaderOption,
-  PackageOptionsConfig,
+  ASTNode,
   CustomDirectiveMap,
-  DirectiveName,
   CustomDirectiveMapItem,
-  SchemaMap,
-  SchemaEntity,
-  ASTNode,
   DirectiveDefinitionNode,
+  DirectiveName,
   DirectiveNode,
   GraphQLField,
   GraphQLFieldMap,
@@ -46,10 +39,15 @@ import type {
   GraphQLNamedType,
   GraphQLSchemaConfig,
   GraphQLType,
-  ObjectTypeDefinitionNode,
-  Maybe,
   IGetRelation,
+  LoaderOption,
+  LoadSchemaOptions,
+  Maybe,
+  ObjectTypeDefinitionNode,
+  PackageOptionsConfig,
   PrintTypeOptions,
+  SchemaEntity,
+  SchemaMap,
 } from "@graphql-markdown/types";
 
 import { convertArrayToObject } from "./array";
@@ -97,11 +95,15 @@ export async function loadSchema(
 }
 
 export async function getDocumentLoaders(
-  loadersList: LoaderOption,
-): Promise<LoadSchemaOptions> {
+  loadersList: Maybe<LoaderOption>,
+): Promise<Maybe<LoadSchemaOptions>> {
   const loaders: Loader[] = [];
   const loaderOptions: PackageOptionsConfig = {};
 
+  if (typeof loadersList !== "object" || loadersList === null) {
+    return undefined;
+  }
+
   for (const [className, graphqlDocumentLoader] of Object.entries(
     loadersList,
   )) {
diff --git a/packages/utils/src/logger.ts b/packages/utils/src/logger.ts
index 8b598e8b..bc0f4e46 100644
--- a/packages/utils/src/logger.ts
+++ b/packages/utils/src/logger.ts
@@ -15,15 +15,18 @@ export const Logger = {
     }
 
     if (typeof global.logger.log === "undefined") {
-      global.logger.log = global.logger.info;
+      global.logger.log = (...args: unknown[]) =>
+        global.logger!.info.apply(null, args);
     }
 
     if (typeof global.logger.success === "undefined") {
-      global.logger.success = global.logger.info;
+      global.logger.success = (...args: unknown[]) =>
+        global.logger!.info.apply(null, args);
     }
 
     if (typeof global.logger.debug === "undefined") {
-      global.logger.debug = global.logger.info;
+      global.logger.debug = (...args: unknown[]) =>
+        global.logger!.info.apply(null, args);
     }
 
     return global.logger;


Test patch:
diff --git a/packages/core/tests/integration/generator.spec.ts b/packages/core/tests/integration/generator.spec.ts
index 5564f8b5..28d41804 100644
--- a/packages/core/tests/integration/generator.spec.ts
+++ b/packages/core/tests/integration/generator.spec.ts
@@ -4,7 +4,11 @@ import { vol } from "memfs";
 jest.mock("fs");
 jest.mock("node:fs/promises");
 
-import type { ClassName, MDXString } from "@graphql-markdown/types";
+import type {
+  ClassName,
+  GeneratorOptions,
+  MDXString,
+} from "@graphql-markdown/types";
 
 jest.mock("@graphql-markdown/printer-legacy");
 import { Printer } from "@graphql-markdown/printer-legacy";
@@ -12,7 +16,7 @@ import { Printer } from "@graphql-markdown/printer-legacy";
 jest.mock("@graphql-markdown/diff");
 import * as diff from "@graphql-markdown/diff";
 
-import { GeneratorOptions, generateDocFromSchema } from "../../src/generator";
+import { generateDocFromSchema } from "../../src/generator";
 import {
   DEFAULT_OPTIONS,
   DeprecatedOption,
@@ -21,6 +25,10 @@ import {
 
 describe("renderer", () => {
   beforeEach(() => {
+    // silent console
+    jest.spyOn(global.console, "info").mockImplementation(() => {});
+    jest.spyOn(global.console, "error").mockImplementation(() => {});
+
     jest
       .spyOn(Printer, "printType")
       .mockImplementation((value) => value as MDXString);
diff --git a/packages/core/tests/unit/config.test.ts b/packages/core/tests/unit/config.test.ts
index 8ab6917a..b6d0f477 100644
--- a/packages/core/tests/unit/config.test.ts
+++ b/packages/core/tests/unit/config.test.ts
@@ -5,6 +5,7 @@ import type {
   CustomDirective,
   DirectiveName,
   GraphQLDirective,
+  Maybe,
   PackageName,
   TypeDiffMethod,
 } from "@graphql-markdown/types";
@@ -48,13 +49,33 @@ describe("config", () => {
       ).toStrictEqual(["noDoc"]);
     });
 
-    test("supports deprecated skip option", () => {
+    test.each([
+      {
+        location: "configFileOpts",
+        options: {
+          cliOpt: undefined,
+          configFileOpts: {
+            printTypeOptions: { deprecated: "skip" },
+          },
+        },
+      },
+      {
+        location: "configFileOpts",
+        options: {
+          cliOpt: { deprecated: "skip" },
+          configFileOpts: {
+            printTypeOptions: { deprecated: "group" },
+          },
+        },
+      },
+    ])("supports deprecated skip option in $location", ({ options }) => {
       expect.hasAssertions();
 
       expect(
-        getSkipDocDirectives(undefined, {
-          printTypeOptions: { deprecated: "skip" },
-        }),
+        getSkipDocDirectives(
+          options.cliOpt as CliOptions,
+          options.configFileOpts,
+        ),
       ).toStrictEqual(["deprecated"]);
     });
   });
@@ -69,9 +90,9 @@ describe("config", () => {
     test("throws an error if not a string", () => {
       expect.hasAssertions();
 
-      expect(() =>
-        getSkipDocDirective("+NotADirective@" as DirectiveName),
-      ).toThrow(Error);
+      expect(() => getSkipDocDirective({} as unknown as DirectiveName)).toThrow(
+        Error,
+      );
     });
 
     test("throws an error if format is not a directive", () => {
@@ -79,7 +100,7 @@ describe("config", () => {
 
       expect(() =>
         getSkipDocDirective("+NotADirective@" as DirectiveName),
-      ).toThrow(Error);
+      ).toThrow(`Invalid "+NotADirective@"`);
     });
   });
 
@@ -374,6 +395,12 @@ describe("config", () => {
       expect(getCustomDirectives(undefined, undefined)).toBeUndefined();
     });
 
+    test("returns undefined if empty", () => {
+      expect.hasAssertions();
+
+      expect(getCustomDirectives({}, undefined)).toBeUndefined();
+    });
+
     test("returns undefined if specified directives are skipped", () => {
       expect.hasAssertions();
 
@@ -386,15 +413,37 @@ describe("config", () => {
       ).toBeUndefined();
     });
 
-    test("throws an error if descriptor format is invalid", () => {
-      expect.assertions(1);
+    test.each([
+      {
+        case: "undefined",
+        options: {
+          test: {},
+        },
+      },
 
-      const options = {
-        test: {},
-      };
+      {
+        case: "descriptor is not a function",
+        options: {
+          test: {
+            descriptor: {},
+          },
+        },
+      },
+
+      {
+        case: "tag is is not a function",
+        options: {
+          test: {
+            descriptor: () => {},
+            tag: {},
+          },
+        },
+      },
+    ])("throws an error if format is $case", ({ options }) => {
+      expect.assertions(1);
 
       expect(() => {
-        getCustomDirectives(options);
+        getCustomDirectives(options as Maybe<CustomDirective>);
       }).toThrow(
         `Wrong format for plugin custom directive "test".\nPlease refer to https://graphql-markdown.github.io/docs/advanced/custom-directive`,
       );
diff --git a/packages/core/tests/unit/diff.test.ts b/packages/core/tests/unit/diff.test.ts
index 50a1d940..c9998e33 100644
--- a/packages/core/tests/unit/diff.test.ts
+++ b/packages/core/tests/unit/diff.test.ts
@@ -9,12 +9,17 @@ import * as diff from "@graphql-markdown/diff";
 
 describe("diff", () => {
   describe("hasChanges()", () => {
+    beforeEach(() => {
+      // silent console
+      jest.spyOn(global.console, "warn").mockImplementation(() => {});
+    });
+
     afterEach(() => {
       jest.restoreAllMocks();
     });
 
     test.each([[undefined], [null]])(
-      "returns true if diffMethod not set",
+      "returns true if diffMethod is %s",
       async (value: unknown) => {
         expect.assertions(2);
 
@@ -28,7 +33,7 @@ describe("diff", () => {
     );
 
     test.each([[undefined], [null]])(
-      "returns true if diffModule not set",
+      "returns true if diffModule is %s",
       async (value) => {
         expect.assertions(2);
 
diff --git a/packages/core/tests/unit/generator.test.ts b/packages/core/tests/unit/generator.test.ts
new file mode 100644
index 00000000..d7acc1b6
--- /dev/null
+++ b/packages/core/tests/unit/generator.test.ts
@@ -0,0 +1,255 @@
+jest.useFakeTimers();
+
+import type {
+  GeneratorOptions,
+  GraphQLSchema,
+  IPrinter,
+  LoadSchemaOptions,
+  SchemaMap,
+} from "@graphql-markdown/types";
+
+import * as Utils from "@graphql-markdown/utils";
+jest.mock("@graphql-markdown/utils", () => {
+  const utils = jest.requireActual("@graphql-markdown/utils");
+  return {
+    Logger: utils.Logger,
+    getCustomDirectives: jest.fn(),
+    getDocumentLoaders: jest.fn(),
+    getGroups: jest.fn(),
+    getSchemaMap: jest.fn(),
+    loadSchema: jest.fn(),
+  };
+});
+
+import { DiffMethod } from "../../src/config";
+import * as CoreDiff from "../../src/diff";
+jest.mock("../../src/diff");
+import * as CoreRenderer from "../../src/renderer";
+jest.mock("../../src/renderer");
+import * as CorePrinter from "../../src/printer";
+jest.mock("../../src/printer");
+
+import { generateDocFromSchema } from "../../src";
+
+describe("generator", () => {
+  describe("generateDocFromSchema()", () => {
+    const options = {
+      baseURL: "base URL",
+      schemaLocation: "schema location",
+      outputDir: "output dir",
+      linkRoot: "link root",
+      homepageLocation: "homepage location",
+      tmpDir: "temp dir",
+      diffMethod: "diff method",
+      docOptions: {
+        index: true,
+        pagination: true,
+        toc: true,
+      },
+      printTypeOptions: {
+        codeSection: true,
+        deprecated: "skip",
+        parentTypePrefix: true,
+        relatedTypeSection: true,
+        typeBadges: true,
+      },
+      prettify: true,
+      printer: "printer module",
+      skipDocDirective: "doc directive",
+    } as unknown as GeneratorOptions;
+
+    beforeAll(() => {
+      Object.assign(global, { logger: global.console });
+    });
+
+    beforeEach(() => {
+      // silent console
+      jest.spyOn(global.console, "info").mockImplementation(() => {});
+      jest.spyOn(global.console, "error").mockImplementation(() => {});
+    });
+
+    afterEach(() => {
+      jest.restoreAllMocks();
+    });
+
+    afterAll(() => {
+      delete global.logger;
+    });
+
+    test("passes options to Printer and Renderer", async () => {
+      jest.spyOn(CoreDiff, "hasChanges").mockResolvedValueOnce(true);
+      jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce({} as LoadSchemaOptions);
+      jest
+        .spyOn(Utils, "loadSchema")
+        .mockResolvedValueOnce({} as GraphQLSchema);
+      jest
+        .spyOn(Utils, "getSchemaMap")
+        .mockReturnValueOnce({ objects: {} } as SchemaMap);
+      jest.spyOn(Utils, "getGroups").mockReturnValueOnce(undefined);
+      jest.spyOn(Utils, "getCustomDirectives").mockReturnValueOnce(undefined);
+
+      const getPrinterSpy = jest
+        .spyOn(CorePrinter, "getPrinter")
+        .mockResolvedValueOnce({} as unknown as typeof IPrinter);
+      const rendererSpy = jest.spyOn(CoreRenderer, "Renderer");
+
+      await generateDocFromSchema(options);
+
+      expect(getPrinterSpy).toHaveBeenCalledWith(
+        options.printer,
+        {
+          baseURL: options.baseURL,
+          linkRoot: options.linkRoot,
+          schema: {},
+        },
+        {
+          customDirectives: undefined,
+          groups: undefined,
+          printTypeOptions: options.printTypeOptions,
+          skipDocDirective: options.skipDocDirective,
+        },
+      );
+      expect(rendererSpy).toHaveBeenCalledWith(
+        {},
+        options.outputDir,
+        options.baseURL,
+        undefined,
+        options.prettify,
+        {
+          ...options.docOptions,
+          deprecated: options.printTypeOptions.deprecated,
+        },
+      );
+    });
+
+    test("prints summary when completed", async () => {
+      expect.assertions(1);
+
+      jest.spyOn(CoreDiff, "hasChanges").mockResolvedValueOnce(true);
+      jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce({} as LoadSchemaOptions);
+      jest
+        .spyOn(Utils, "loadSchema")
+        .mockResolvedValueOnce({} as GraphQLSchema);
+      jest
+        .spyOn(Utils, "getSchemaMap")
+        .mockReturnValueOnce({ objects: {} } as SchemaMap);
+      jest.spyOn(Utils, "getGroups").mockReturnValueOnce(undefined);
+      jest.spyOn(Utils, "getCustomDirectives").mockReturnValueOnce(undefined);
+      jest
+        .spyOn(CorePrinter, "getPrinter")
+        .mockResolvedValueOnce({} as unknown as typeof IPrinter);
+
+      const loggerSpy = jest.spyOn(global.console, "info");
+
+      await generateDocFromSchema(options);
+
+      expect(loggerSpy.mock.calls).toMatchInlineSnapshot(`
+      [
+        [
+          "Documentation successfully generated in "output dir" with base URL "base URL".",
+        ],
+        [
+          "1 pages generated in 0.000s from schema "schema location".",
+        ],
+        [
+          "Remember to update your Docusaurus site's sidebars with "undefined".",
+        ],
+      ]
+      `);
+    });
+
+    test("calls getDocumentLoaders and returns an error if loaders cannot be fetched", async () => {
+      expect.assertions(3);
+
+      const getDocumentLoadersSpy = jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce(undefined);
+      const loggerSpy = jest.spyOn(console, "error");
+      const loadSchemaSpy = jest.spyOn(Utils, "loadSchema");
+
+      await generateDocFromSchema({} as unknown as GeneratorOptions);
+
+      expect(getDocumentLoadersSpy).toHaveBeenCalled();
+      expect(loggerSpy).toHaveBeenCalledWith(
+        `An error occurred while loading GraphQL loader.\nCheck your dependencies and configuration.`,
+      );
+      expect(loadSchemaSpy).not.toHaveBeenCalled();
+    });
+
+    test("calls hasChanges if DiffMethod is not NONE", async () => {
+      expect.assertions(2);
+
+      jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce({} as LoadSchemaOptions);
+      jest
+        .spyOn(Utils, "loadSchema")
+        .mockResolvedValueOnce({} as GraphQLSchema);
+      jest
+        .spyOn(Utils, "getSchemaMap")
+        .mockReturnValueOnce({ objects: {} } as SchemaMap);
+      const loggerSpy = jest.spyOn(console, "info");
+      const hasChangesSpy = jest
+        .spyOn(CoreDiff, "hasChanges")
+        .mockResolvedValueOnce(true);
+
+      await generateDocFromSchema(options);
+
+      expect(hasChangesSpy).toHaveBeenCalledWith({}, "temp dir", "diff method");
+      expect(loggerSpy).not.toHaveBeenCalledWith(
+        `No changes detected in schema "schema location".`,
+      );
+    });
+
+    test("skips hasChanges if DiffMethod is NONE", async () => {
+      expect.assertions(1);
+
+      jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce({} as LoadSchemaOptions);
+      jest
+        .spyOn(Utils, "loadSchema")
+        .mockResolvedValueOnce({} as GraphQLSchema);
+      jest
+        .spyOn(Utils, "getSchemaMap")
+        .mockReturnValueOnce({ objects: {} } as SchemaMap);
+      const hasChangesSpy = jest.spyOn(CoreDiff, "hasChanges");
+
+      await generateDocFromSchema({
+        ...options,
+        diffMethod: DiffMethod.NONE,
+      });
+
+      expect(hasChangesSpy).not.toHaveBeenCalled();
+    });
+
+    test("print info log is hasChanges is false", async () => {
+      expect.assertions(2);
+
+      jest
+        .spyOn(Utils, "getDocumentLoaders")
+        .mockResolvedValueOnce({} as LoadSchemaOptions);
+      jest
+        .spyOn(Utils, "loadSchema")
+        .mockResolvedValueOnce({} as GraphQLSchema);
+      jest
+        .spyOn(Utils, "getSchemaMap")
+        .mockReturnValueOnce({ objects: {} } as SchemaMap);
+      const loggerSpy = jest.spyOn(console, "info");
+      const hasChangesSpy = jest
+        .spyOn(CoreDiff, "hasChanges")
+        .mockResolvedValueOnce(false);
+
+      await generateDocFromSchema(options);
+
+      expect(hasChangesSpy).toHaveBeenCalledWith({}, "temp dir", "diff method");
+      expect(loggerSpy).toHaveBeenCalledWith(
+        `No changes detected in schema "schema location".`,
+      );
+    });
+  });
+});
diff --git a/packages/core/tests/unit/graphql-config.test.ts b/packages/core/tests/unit/graphql-config.test.ts
index 74fc0dc6..90c227b2 100644
--- a/packages/core/tests/unit/graphql-config.test.ts
+++ b/packages/core/tests/unit/graphql-config.test.ts
@@ -1,8 +1,9 @@
+/* eslint-disable @typescript-eslint/no-explicit-any */
 import { vol } from "memfs";
 
 import { join } from "node:path";
 
-import { loadConfiguration } from "../../src/graphql-config";
+import * as CoreGraphQLConfig from "../../src/graphql-config";
 import { buildConfig, DEFAULT_OPTIONS } from "../../src/config";
 
 jest.mock("graphql-config");
@@ -15,16 +16,29 @@ describe("graphql-config", () => {
       jest.restoreAllMocks();
     });
 
-    test("returns undefined if not graphql-config found", async () => {
+    test("returns undefined if graphql-config empty", async () => {
       expect.hasAssertions();
 
-      await expect(loadConfiguration("default")).resolves.toBeUndefined();
+      await expect(
+        CoreGraphQLConfig.loadConfiguration("default"),
+      ).resolves.toBeUndefined();
     });
 
-    test("returns undefined if graphql-config empty", async () => {
+    test("returns undefined if an error is thrown", async () => {
       expect.hasAssertions();
 
-      await expect(loadConfiguration("default")).resolves.toBeUndefined();
+      jest
+        .spyOn(CoreGraphQLConfig, "setLoaderOptions")
+        .mockImplementationOnce(() => {
+          throw new Error();
+        });
+
+      await expect(
+        CoreGraphQLConfig.loadConfiguration("default", undefined, {
+          throwOnMissing: true,
+          throwOnEmpty: true,
+        }),
+      ).resolves.toBeUndefined();
     });
 
     test.each([
@@ -39,7 +53,7 @@ describe("graphql-config", () => {
         ],
       ],
       [["http://localhost:4000/graphql", "./packages/bar/schema.graphql"]],
-    ])("returns config if graphql-config valid", async (schema) => {
+    ])("returns config if graphql-config valid - %#", async (schema) => {
       expect.hasAssertions();
 
       const graphqlConfig = {
@@ -51,20 +65,24 @@ describe("graphql-config", () => {
         },
       };
 
-      (GraphQLConfig.loadConfig as jest.Mock).mockResolvedValueOnce({
-        getProject: jest.fn(() => ({
-          extension: jest.fn(() => ({
-            documents: undefined,
-            exclude: undefined,
-            include: undefined,
-            schema: graphqlConfig.schema,
-            ...graphqlConfig.extensions["graphql-markdown"],
-          })),
-        })),
-      });
+      const spy = jest
+        .spyOn(GraphQLConfig, "loadConfig")
+        .mockResolvedValueOnce({
+          getProject: () =>
+            ({
+              extension: (): any =>
+                ({
+                  documents: undefined,
+                  exclude: undefined,
+                  include: undefined,
+                  schema: graphqlConfig.schema,
+                  ...graphqlConfig.extensions["graphql-markdown"],
+                }) as unknown as any,
+            }) as unknown as any,
+        } as unknown as any);
 
       await expect(
-        loadConfiguration("default", undefined, {
+        CoreGraphQLConfig.loadConfiguration("default", undefined, {
           throwOnMissing: true,
           throwOnEmpty: true,
         }),
@@ -75,6 +93,11 @@ describe("graphql-config", () => {
         include: undefined,
         schema: "http://localhost:4000/graphql",
       });
+      expect(spy).toHaveBeenCalledWith({
+        extensions: [CoreGraphQLConfig.GraphQLConfigExtension],
+        throwOnMissing: true,
+        throwOnEmpty: true,
+      });
     });
 
     test("returns default config", async () => {
@@ -103,20 +126,22 @@ describe("graphql-config", () => {
         },
       };
 
-      (GraphQLConfig.loadConfig as jest.Mock).mockResolvedValueOnce({
-        getProject: jest.fn(() => ({
-          extension: jest.fn(() => ({
-            documents: undefined,
-            exclude: undefined,
-            include: undefined,
-            schema: graphqlConfig.schema,
-            ...graphqlConfig.extensions["graphql-markdown"],
-          })),
-        })),
-      });
+      jest.spyOn(GraphQLConfig, "loadConfig").mockResolvedValueOnce({
+        getProject: () =>
+          ({
+            extension: () =>
+              ({
+                documents: undefined,
+                exclude: undefined,
+                include: undefined,
+                schema: graphqlConfig.schema,
+                ...graphqlConfig.extensions["graphql-markdown"],
+              }) as unknown as any,
+          }) as unknown as any,
+      } as unknown as any);
 
       await expect(
-        loadConfiguration("default", undefined, {
+        CoreGraphQLConfig.loadConfiguration("default", undefined, {
           throwOnMissing: true,
           throwOnEmpty: true,
         }),
@@ -164,20 +189,22 @@ describe("graphql-config", () => {
         },
       };
 
-      (GraphQLConfig.loadConfig as jest.Mock).mockResolvedValueOnce({
-        getProject: jest.fn(() => ({
-          extension: jest.fn(() => ({
-            documents: undefined,
-            exclude: undefined,
-            include: undefined,
-            schema: graphqlConfig.projects.foo.schema,
-            ...graphqlConfig.projects.foo.extensions["graphql-markdown"],
-          })),
-        })),
-      });
+      jest.spyOn(GraphQLConfig, "loadConfig").mockResolvedValueOnce({
+        getProject: () =>
+          ({
+            extension: () =>
+              ({
+                documents: undefined,
+                exclude: undefined,
+                include: undefined,
+                schema: graphqlConfig.projects.foo.schema,
+                ...graphqlConfig.projects.foo.extensions["graphql-markdown"],
+              }) as unknown as any,
+          }) as unknown as any,
+      } as unknown as any);
 
       await expect(
-        loadConfiguration("foo", undefined, {
+        CoreGraphQLConfig.loadConfiguration("foo", undefined, {
           throwOnMissing: true,
           throwOnEmpty: true,
         }),
@@ -207,8 +234,21 @@ describe("graphql-config", () => {
         getProject: jest.fn(() => undefined),
       });
 
-      await expect(loadConfiguration("baz")).resolves.toBeUndefined();
+      await expect(
+        CoreGraphQLConfig.loadConfiguration("baz"),
+      ).resolves.toBeUndefined();
     });
+
+    test.each([[undefined], [null]])(
+      "returns undefined if project id is %s",
+      async (value) => {
+        expect.hasAssertions();
+
+        await expect(
+          CoreGraphQLConfig.loadConfiguration(value),
+        ).resolves.toBeUndefined();
+      },
+    );
   });
 });
 
@@ -231,17 +271,19 @@ describe("config", () => {
         },
       };
 
-      (GraphQLConfig.loadConfig as jest.Mock).mockResolvedValueOnce({
-        getProject: jest.fn(() => ({
-          extension: jest.fn(() => ({
-            documents: undefined,
-            exclude: undefined,
-            include: undefined,
-            schema: graphqlConfig.schema,
-            ...graphqlConfig.extensions["graphql-markdown"],
-          })),
-        })),
-      });
+      jest.spyOn(GraphQLConfig, "loadConfig").mockResolvedValueOnce({
+        getProject: () =>
+          ({
+            extension: () =>
+              ({
+                documents: undefined,
+                exclude: undefined,
+                include: undefined,
+                schema: graphqlConfig.schema,
+                ...graphqlConfig.extensions["graphql-markdown"],
+              }) as unknown as any,
+          }) as unknown as any,
+      } as unknown as any);
 
       const config = await buildConfig(undefined, undefined);
 
diff --git a/packages/core/tests/unit/printer.test.ts b/packages/core/tests/unit/printer.test.ts
index 0427cccd..792951d5 100644
--- a/packages/core/tests/unit/printer.test.ts
+++ b/packages/core/tests/unit/printer.test.ts
@@ -4,51 +4,65 @@ import type { PackageName } from "@graphql-markdown/types";
 
 import { getPrinter } from "../../src/printer";
 
+import { Printer } from "@graphql-markdown/printer-legacy";
 jest.mock("@graphql-markdown/printer-legacy");
 
 describe("generator", () => {
   describe("getPrinter()", () => {
     test("returns Printer object for @graphql-markdown/printer-legacy", async () => {
-      expect.assertions(3);
+      expect.assertions(4);
 
+      const spy = jest.spyOn(Printer, "init");
+
+      const printerConfig = {
+        schema: new GraphQLSchema({}),
+        baseURL: "/",
+        linkRoot: "root",
+      };
+      const printerOptions = {
+        groups: {},
+        printTypeOptions: {},
+      };
       const printer = await getPrinter(
         "@graphql-markdown/printer-legacy" as PackageName,
-        {
-          schema: new GraphQLSchema({}),
-          baseURL: "/",
-          linkRoot: "root",
-        },
-        {
-          groups: {},
-          printTypeOptions: {},
-        },
+        printerConfig,
+        printerOptions,
       );
 
       expect(printer).toBeDefined();
       expect(printer).toHaveProperty("init");
       expect(printer).toHaveProperty("printType");
+      expect(spy).toHaveBeenCalledWith(
+        printerConfig.schema,
+        printerConfig.baseURL,
+        printerConfig.linkRoot,
+        printerOptions,
+      );
     });
 
-    test("throws exception if no printer module set", async () => {
-      expect.assertions(1);
+    test.each([[undefined], [null]])(
+      "throws exception if printer module is %s",
+      async (value) => {
+        expect.assertions(1);
 
-      await expect(
-        getPrinter(
-          undefined,
-          {
-            schema: new GraphQLSchema({}),
-            baseURL: "/",
-            linkRoot: "root",
-          },
-          {
-            groups: {},
-            printTypeOptions: {},
-          },
-        ),
-      ).rejects.toThrow(
-        `Invalid printer module name in "printTypeOptions" settings.`,
-      );
-    });
+        await expect(
+          getPrinter(
+            value,
+            {
+              schema: new GraphQLSchema({}),
+              baseURL: "/",
+              linkRoot: "root",
+            },
+            {
+              groups: {},
+              printTypeOptions: {},
+            },
+          ),
+        ).rejects.toThrow(
+          `Invalid printer module name in "printTypeOptions" settings.`,
+        );
+      },
+    );
 
     test("throws exception if no printer config set", async () => {
       expect.assertions(1);
diff --git a/packages/core/tests/unit/renderer.test.ts b/packages/core/tests/unit/renderer.test.ts
index 3f9e7d23..c425540b 100644
--- a/packages/core/tests/unit/renderer.test.ts
+++ b/packages/core/tests/unit/renderer.test.ts
@@ -1,6 +1,7 @@
 jest.mock("node:fs/promises");
 
-import { join } from "node:path";
+import path from "node:path";
+jest.mock("node:path", () => jest.requireActual("node:path"));
 
 import { GraphQLScalarType, Kind } from "graphql";
 
@@ -97,6 +98,54 @@ describe("renderer", () => {
 
         expect(meta).toBeUndefined();
       });
+
+      test("return undefined and logs warning if an error is thrown", async () => {
+        expect.assertions(2);
+
+        jest.spyOn(Printer, "printType").mockImplementationOnce(() => {
+          throw new Error();
+        });
+
+        const spy = jest
+          .spyOn(global.console, "warn")
+          .mockImplementationOnce(() => {});
+
+        const meta = await rendererInstance.renderTypeEntities(
+          "test",
+          "FooBar",
+          "TestType",
+        );
+
+        expect(meta).toBeUndefined();
+        expect(spy).toHaveBeenCalledWith(
+          `An error occurred while processing "TestType"`,
+        );
+      });
+
+      test("return undefined and logs warning if file path is invalid", async () => {
+        expect.assertions(2);
+
+        jest
+          .spyOn(Printer, "printType")
+          .mockReturnValue("Lorem ipsum" as MDXString);
+        jest
+          .spyOn(Utils.pathUrl, "relative")
+          .mockImplementationOnce(() => "not-valid.md");
+        const spy = jest
+          .spyOn(global.console, "warn")
+          .mockImplementationOnce(() => {});
+
+        const meta = await rendererInstance.renderTypeEntities(
+          "test",
+          "FooBar",
+          "TestType",
+        );
+
+        expect(meta).toBeUndefined();
+        expect(spy).toHaveBeenCalledWith(
+          `An error occurred while processing file test/foo-bar.mdx for type "TestType"`,
+        );
+      });
     });
 
     describe("renderSidebar()", () => {
@@ -176,7 +225,7 @@ describe("renderer", () => {
 
         const category = "foobar";
         const outputPath = "/output/docs";
-        const filePath = join(outputPath, "_category_.yml");
+        const filePath = path.join(outputPath, "_category_.yml");
 
         jest.spyOn(Utils, "fileExists").mockResolvedValue(false);
         const spy = jest.spyOn(Utils, "saveFile");
@@ -194,7 +243,7 @@ describe("renderer", () => {
 
         const category = "foobar";
         const outputPath = "/output/docs";
-        const filePath = join(outputPath, "_category_.yml");
+        const filePath = path.join(outputPath, "_category_.yml");
 
         rendererInstance.options = {
           ...DEFAULT_RENDERER_OPTIONS,
@@ -231,7 +280,7 @@ describe("renderer", () => {
 
         const category = "foobar";
         const outputPath = "/output/docs";
-        const filePath = join(outputPath, "_category_.yml");
+        const filePath = path.join(outputPath, "_category_.yml");
 
         jest.spyOn(Utils, "fileExists").mockResolvedValue(false);
         const spy = jest.spyOn(Utils, "saveFile");
@@ -247,6 +296,30 @@ describe("renderer", () => {
           `label: Foobar\nposition: 42\nlink: null\n`,
         );
       });
+
+      test("generate _category_.yml file with classname", async () => {
+        expect.assertions(1);
+
+        const category = "foobar";
+        const outputPath = "/output/docs";
+        const filePath = path.join(outputPath, "_category_.yml");
+        const styleClass = "foo-baz";
+
+        jest.spyOn(Utils, "fileExists").mockResolvedValue(false);
+        const spy = jest.spyOn(Utils, "saveFile");
+
+        await rendererInstance.generateCategoryMetafile(
+          category,
+          outputPath,
+          42,
+          styleClass,
+        );
+
+        expect(spy).toHaveBeenCalledWith(
+          filePath,
+          `label: Foobar\nposition: 42\nclassName: ${styleClass}\nlink: null\n`,
+        );
+      });
     });
 
     describe("generateCategoryMetafileType()", () => {
@@ -261,12 +334,12 @@ describe("renderer", () => {
           "objects",
         );
 
-        expect(spy).toHaveBeenCalledTimes(1);
+        expect(spy).toHaveBeenCalledWith("objects", "/output/objects");
         expect(dirPath).toBe("/output/objects");
       });
 
       test("generate group _category_.yml file", async () => {
-        expect.assertions(2);
+        expect.assertions(3);
 
         const [type, name, root, group] = [{}, "Foo", "objects", "lorem"];
 
@@ -281,12 +354,13 @@ describe("renderer", () => {
           root as SchemaEntity,
         );
 
-        expect(spy).toHaveBeenCalledTimes(2);
+        expect(spy).toHaveBeenCalledWith("lorem", "/output/lorem");
+        expect(spy).toHaveBeenCalledWith("objects", "/output/lorem/objects");
         expect(dirPath).toBe(`/output/${group}/${root.toLowerCase()}`);
       });
 
       test("generate deprecated _category_.yml file if type is deprecated", async () => {
-        expect.assertions(2);
+        expect.assertions(3);
 
         const [type, name, root] = [{}, "Foo", "Baz"];
 
@@ -302,7 +376,13 @@ describe("renderer", () => {
           root as SchemaEntity,
         );
 
-        expect(spy).toHaveBeenCalledTimes(2);
+        expect(spy).toHaveBeenCalledWith(
+          "deprecated",
+          "/output/deprecated",
+          999,
+          "deprecated",
+        );
+        expect(spy).toHaveBeenCalledWith("Baz", "/output/deprecated/baz");
         expect(dirPath).toBe(`/output/deprecated/${root.toLowerCase()}`);
       });
 
@@ -323,7 +403,28 @@ describe("renderer", () => {
           root as SchemaEntity,
         );
 
-        expect(spy).toHaveBeenCalledTimes(1);
+        expect(spy).toHaveBeenCalledWith("Baz", "/output/baz");
+        expect(dirPath).toBe(`/output/${root.toLowerCase()}`);
+      });
+
+      test("generate no deprecated _category_.yml file if deprecated is not group", async () => {
+        expect.assertions(2);
+
+        const [type, name, root] = [{}, "Foo", "Baz"];
+
+        const spy = jest.spyOn(rendererInstance, "generateCategoryMetafile");
+        jest.replaceProperty(rendererInstance, "options", {
+          deprecated: "default",
+        });
+        jest.spyOn(Utils, "isDeprecated").mockReturnValue(false);
+
+        const dirPath = await rendererInstance.generateCategoryMetafileType(
+          type,
+          name,
+          root as SchemaEntity,
+        );
+
+        expect(spy).toHaveBeenCalledWith("Baz", "/output/baz");
         expect(dirPath).toBe(`/output/${root.toLowerCase()}`);
       });
 
diff --git a/packages/diff/tests/unit/diff.test.ts b/packages/diff/tests/unit/diff.test.ts
index 13d22021..8c771999 100644
--- a/packages/diff/tests/unit/diff.test.ts
+++ b/packages/diff/tests/unit/diff.test.ts
@@ -30,6 +30,7 @@ describe("lib", () => {
 
     afterEach(() => {
       vol.reset();
+      jest.restoreAllMocks();
     });
 
     describe("checkSchemaChanges()", () => {
diff --git a/packages/utils/tests/unit/graphql.test.ts b/packages/utils/tests/unit/graphql.test.ts
index 95f3f83a..2a5f0846 100644
--- a/packages/utils/tests/unit/graphql.test.ts
+++ b/packages/utils/tests/unit/graphql.test.ts
@@ -105,20 +105,22 @@ describe("graphql", () => {
     test("returns loaders when plugin config loaders format is a string", async () => {
       expect.hasAssertions();
 
-      const loaders = {
+      const loaderList = {
         GraphQLFileLoader: "@graphql-tools/graphql-file-loader",
       } as LoaderOption;
-      const { loaders: documentLoaders, ...loaderOptions } =
-        await getDocumentLoaders(loaders);
+      const documentLoaders = await getDocumentLoaders(loaderList);
 
-      expect(documentLoaders).toMatchObject([new GraphQLFileLoader()]);
+      expect(documentLoaders).toBeDefined();
+      const { loaders, ...loaderOptions } = documentLoaders!;
+
+      expect(loaders).toMatchObject([new GraphQLFileLoader()]);
       expect(loaderOptions).toMatchObject({});
     });
 
     test("returns loaders and configuration when plugin config loaders format is an object", async () => {
       expect.hasAssertions();
 
-      const loaders = {
+      const loaderList = {
         GraphQLFileLoader: {
           module: "@graphql-tools/graphql-file-loader",
           options: {
@@ -126,10 +128,12 @@ describe("graphql", () => {
           },
         },
       } as LoaderOption;
-      const { loaders: documentLoaders, ...loaderOptions } =
-        await getDocumentLoaders(loaders);
+      const documentLoaders = await getDocumentLoaders(loaderList);
+
+      expect(documentLoaders).toBeDefined();
+      const { loaders, ...loaderOptions } = documentLoaders!;
 
-      expect(documentLoaders).toMatchObject([new GraphQLFileLoader()]);
+      expect(loaders).toMatchObject([new GraphQLFileLoader()]);
       expect(loaderOptions).toMatchObject({
         option1: true,
       });
@@ -138,8 +142,8 @@ describe("graphql", () => {
     test("throw an error when loader list is invalid", async () => {
       expect.hasAssertions();
 
-      const loaders = { GraphQLFileLoader: {} } as LoaderOption;
-      await expect(getDocumentLoaders(loaders)).rejects.toThrow(
+      const loaderList = { GraphQLFileLoader: {} } as LoaderOption;
+      await expect(getDocumentLoaders(loaderList)).rejects.toThrow(
         `Wrong format for plugin loader "GraphQLFileLoader", it should be {module: String, options?: Object}`,
       );
     });
diff --git a/packages/utils/tests/unit/group.test.ts b/packages/utils/tests/unit/group.test.ts
index 8d9ebd67..bbc099b4 100644
--- a/packages/utils/tests/unit/group.test.ts
+++ b/packages/utils/tests/unit/group.test.ts
@@ -59,7 +59,7 @@ describe("group-info", () => {
     };
 
     test.each([[undefined], [null]])(
-      "returns undefined if groupByDirective is $value",
+      "returns undefined if groupByDirective is %s",
       (value) => {
         expect.assertions(1);
 
@@ -111,7 +111,7 @@ describe("group-info", () => {
     test.each([
       { case: "null type", type: null },
       { case: "undefined type", type: undefined },
-    ])("returns undefined if type is $value", ({ type }) => {
+    ])("returns undefined if type is $case", ({ type }) => {
       expect.assertions(1);
 
       expect(getGroupName(type, groupOptions)).toBeUndefined();
@@ -120,7 +120,7 @@ describe("group-info", () => {
     test.each([
       { case: "null type", options: null },
       { case: "undefined type", options: undefined },
-    ])("returns undefined if groupByDirective is $value", ({ options }) => {
+    ])("returns undefined if groupByDirective is $case", ({ options }) => {
       expect.assertions(1);
 
       const type = schema.getType("Bird")!;
diff --git a/packages/utils/tests/unit/string.test.ts b/packages/utils/tests/unit/string.test.ts
index 59e86267..05da3010 100644
--- a/packages/utils/tests/unit/string.test.ts
+++ b/packages/utils/tests/unit/string.test.ts
@@ -95,7 +95,7 @@ describe("string", () => {
       ["42 dollars", "42 dollars"],
       ["fooBar", "Foobar"],
     ])(
-      "returns capitalized string: first letter uppercase, rest lowercase",
+      "returns capitalized string: first letter uppercase, rest lowercase - %#",
       (input, expected) => {
         expect.hasAssertions();