From caa1782ae5b114b2a2c775c3ac336a75667574fd Mon Sep 17 00:00:00 2001
From: MBueschelberger <46421269+MBueschelberger@users.noreply.github.com>
Date: Tue, 20 Aug 2024 12:06:15 +0200
Subject: [PATCH] Fix/optional title (#63)

* add more docs strings

* make ontology title optional, add pytest, remove unneeded parser argument from tbox pytest

* update github ci for pytests, make title and authors optional, update pytest

* update pytests
---
 .github/workflows/ci.yml                      |  5 ++
 data2rdf/config.py                            |  5 ++
 data2rdf/parsers/base.py                      | 33 +++++++++++--
 data2rdf/parsers/csv.py                       | 49 +++++++++++++++++--
 data2rdf/parsers/excel.py                     | 38 ++++++++++++--
 data2rdf/parsers/json.py                      | 48 ++++++++++++++++--
 data2rdf/parsers/utils.py                     | 47 ++++++++++++------
 data2rdf/pipelines/main.py                    | 30 +++++++++++-
 docs/config.md                                |  3 ++
 tests/tbox/csv_pipeline_test/test_parser.py   |  4 +-
 tests/tbox/csv_pipeline_test/test_pipeline.py |  4 +-
 .../output/output_json_parser_wo_title.ttl    | 25 ++++++++++
 tests/tbox/json_pipeline_test/test_parser.py  |  4 +-
 .../tbox/json_pipeline_test/test_pipeline.py  |  4 +-
 .../test_title_exclusion.py                   | 41 ++++++++++++++++
 tests/tbox/xls_pipeline_test/test_parser.py   |  4 +-
 tests/tbox/xls_pipeline_test/test_pipeline.py |  4 +-
 17 files changed, 305 insertions(+), 43 deletions(-)
 create mode 100644 tests/tbox/json_pipeline_test/output/output_json_parser_wo_title.ttl
 create mode 100644 tests/tbox/json_pipeline_test/test_title_exclusion.py

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e8f80dd0..0e7fcc5f 100755
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -46,6 +46,11 @@ jobs:
                   python -m pip freeze
 
             - name: Run tests
+              run: |
+                pytest -v
+
+            - name: Make coverage
+              if: ${{ matrix.python-version == '3.12' }}
               run: |
                 pytest --junitxml=pytest.xml  --cov=data2rdf | tee pytest-coverage.txt
 
diff --git a/data2rdf/config.py b/data2rdf/config.py
index 19588762..7c82507c 100755
--- a/data2rdf/config.py
+++ b/data2rdf/config.py
@@ -72,4 +72,9 @@ class Config(BaseSettings):
         This will be suppressed if enabled.""",
     )
 
+    exclude_ontology_title: bool = Field(
+        False,
+        description="In TBox mode, exclude the title of the ontology in the graph.",
+    )
+
     model_config = ConfigDict(extra="ignore")
diff --git a/data2rdf/parsers/base.py b/data2rdf/parsers/base.py
index 1a5c0c60..a97bb078 100644
--- a/data2rdf/parsers/base.py
+++ b/data2rdf/parsers/base.py
@@ -101,7 +101,19 @@ def graph(cls) -> "Graph":
     @model_validator(mode="after")
     @classmethod
     def run_parser(cls, self: "BaseParser") -> "BaseParser":
-        """Run parser"""
+        """
+        Runs the parser for the given data file and mapping.
+
+        This function is a class method that takes in a `self` parameter, which is an instance of the `BaseParser` class.
+        It loads the data file using the `_load_data_file` method and loads the mapping file using the `load_mapping_file` function.
+        It then runs the parser using the `_run_parser` method and returns the parsed `BaseParser` instance.
+
+        Args:
+            self (BaseParser): The instance of the `BaseParser` class.
+
+        Returns:
+            BaseParser: The parsed `BaseParser` instance.
+        """
 
         datafile: Any = cls._load_data_file(self)
         mapping: "Dict[str, BaseParser]" = load_mapping_file(
@@ -125,17 +137,19 @@ class TBoxBaseParser(AnyBoxBaseParser):
     )
 
     version_info: Optional[str] = Field(
-        "1.0.0", description="Version of the ontplpgy"
+        None, description="Version of the ontplpgy"
     )
 
     ontology_iri: Optional[Union[str, AnyUrl]] = Field(
         None, description="General IRI of the ontology."
     )
 
-    ontology_title: str = Field(..., description="Title of the ontology")
+    ontology_title: Optional[str] = Field(
+        None, description="Title of the ontology"
+    )
 
-    authors: List[str] = Field(
-        ..., description="Name of the authors contributing to the ontology."
+    authors: Optional[List[str]] = Field(
+        None, description="Name of the authors contributing to the ontology."
     )
 
     _classes: Any = PrivateAttr()
@@ -227,6 +241,15 @@ def tbox(self) -> "TBoxBaseParser":
     @model_validator(mode="after")
     @classmethod
     def execute_parser(cls, self: "BaseFileParser") -> "BaseFileParser":
+        """
+        Validates the parser model and executes the parser based on the specified mode.
+
+        Args:
+            self: An instance of the BaseFileParser class.
+
+        Returns:
+            An instance of the BaseFileParser class with the parser executed.
+        """
         arguments = {
             "mapping": self.mapping,
             "raw_data": self.raw_data,
diff --git a/data2rdf/parsers/csv.py b/data2rdf/parsers/csv.py
index 27b1df7a..00ab9866 100644
--- a/data2rdf/parsers/csv.py
+++ b/data2rdf/parsers/csv.py
@@ -86,7 +86,20 @@ def _run_parser(
         datafile: StringIO,
         mapping: "List[TBoxBaseMapping]",
     ) -> None:
-        """Run excel parser in tbox mode"""
+        """
+        Class method for running the CSVTBoxParser. This method reads a CSV file
+        into a pandas DataFrame and then uses the provided mapping to create TBox
+        classes.
+
+        Parameters:
+            self (CSVTBoxParser): The instance of the parser.
+            datafile (StringIO): The CSV file to be parsed.
+            mapping (List[TBoxBaseMapping]): The list of mappings to be applied.
+
+        Returns:
+            None
+        """
+
         df = pd.read_csv(datafile, sep=self.column_sep)
         _make_tbox_classes(self, df, mapping)
 
@@ -131,7 +144,23 @@ def mapping_model(cls) -> ABoxBaseMapping:
     # OVERRIDE
     @property
     def json_ld(cls) -> "Dict[str, Any]":
-        """Return dict for json-ld for the graph in abox mode"""
+        """
+        Returns a JSON-LD representation of the CSV data in ABox mode.
+
+        This method generates a JSON-LD object that describes the CSV data,
+        including its metadata, time series data, and relationships between them.
+
+        The returned JSON-LD object is in the format of a csvw:TableGroup,
+        which contains one or more csvw:Table objects. Each csvw:Table object
+        represents a table in the CSV data, and contains information about its
+        columns, rows, and relationships to other tables.
+
+        The JSON-LD object also includes context information, such as namespace
+        prefixes and base URLs, to help with serialization and deserialization.
+
+        Returns:
+        Dict[str, Any]: A JSON-LD object representing the CSV data in ABox mode.
+        """
 
         if not cls.config.suppress_file_description:
             tables = []
@@ -273,7 +302,21 @@ def _run_parser(
         mapping: "List[ABoxBaseMapping]",
     ) -> None:
         """
-        Parse metadata, time series metadata and time series
+        This function is responsible for parsing metadata, time series metadata, and time series data from a CSV file.
+
+        It takes in three parameters:
+        - `self`: The CSVParser instance.
+        - `datafile`: The StringIO object containing the CSV data.
+        - `mapping`: A list of ABoxBaseMapping instances that map the CSV data to the desired output format.
+
+        The function returns None, but it populates the following instance variables:
+        - `self._general_metadata`: A list of PropertyGraph or QuantityGraph instances representing the general metadata.
+        - `self._time_series_metadata`: A list of QuantityGraph instances representing the time series metadata.
+        - `self._time_series`: A pandas DataFrame containing the time series data.
+
+        The function also raises ValueError if the `metadata_length` is greater than 0 but `metadata_sep` is not set.
+        It raises TypeError if the unit for a key is not a string.
+        It raises MappingMissmatchWarning if no match is found in the mapping for a key.
         """
 
         mapping = {model.key: model for model in mapping}
diff --git a/data2rdf/parsers/excel.py b/data2rdf/parsers/excel.py
index cc563f35..665721a4 100644
--- a/data2rdf/parsers/excel.py
+++ b/data2rdf/parsers/excel.py
@@ -80,7 +80,23 @@ def _run_parser(
         datafile: BytesIO,
         mapping: "List[TBoxBaseMapping]",
     ) -> None:
-        """Run excel parser in tbox mode"""
+        """
+        Run excel parser in tbox mode.
+
+        Parameters
+        ----------
+        self : ExcelTBoxParser
+            The instance of the parser.
+        datafile : BytesIO
+            The excel file to be parsed.
+        mapping : List[TBoxBaseMapping]
+            The list of mappings to be applied.
+
+        Returns
+        -------
+        None
+            This function does not return any value.
+        """
         df = pd.read_excel(datafile, sheet_name=self.sheet)
         _make_tbox_classes(self, df, mapping)
 
@@ -122,7 +138,15 @@ def mapping_model(cls) -> ABoxExcelMapping:
     # OVERRIDE
     @property
     def json_ld(cls) -> Dict[str, Any]:
-        """Make the json-ld if pipeline is in abox-mode"""
+        """
+        Returns the JSON-LD representation of the data in ABox mode.
+
+        The JSON-LD is constructed based on the metadata and time series data.
+        If the file description is not suppressed, it includes the metadata and time series data tables.
+        Otherwise, it returns a list of JSON-LD representations of the individual models.
+
+        :return: A dictionary representing the JSON-LD data.
+        """
 
         if not cls.config.suppress_file_description:
             tables = []
@@ -256,7 +280,15 @@ def _run_parser(
         mapping: "List[ABoxExcelMapping]",
     ) -> None:
         """
-        Parse metadata, time series metadata and time series
+        Parses the metadata, time series metadata, and time series from an Excel file.
+
+        Args:
+            self (ExcelABoxParser): The instance of the ExcelABoxParser class.
+            datafile (BytesIO): The file object containing the Excel file.
+            mapping (List[ABoxExcelMapping]): The list of mappings to use for parsing.
+
+        Returns:
+            None: This function does not return anything.
         """
 
         mapping = {model.key: model for model in mapping}
diff --git a/data2rdf/parsers/json.py b/data2rdf/parsers/json.py
index 56636a46..ca10aa74 100644
--- a/data2rdf/parsers/json.py
+++ b/data2rdf/parsers/json.py
@@ -69,7 +69,18 @@ def _run_parser(
         datafile: "List[Dict[str, Any]]",
         mapping: "Dict[str, TBoxBaseMapping]",
     ) -> None:
-        """Run parser in TBox mode"""
+        """
+        Runs the parser in TBox mode.
+
+        Args:
+            self: An instance of JsonTBoxParser.
+            datafile: A list of dictionaries containing the data to be parsed.
+            mapping: A dictionary containing the mapping of the data.
+
+        Returns:
+            None
+        """
+
         df = pd.DataFrame(datafile)
         _make_tbox_classes(self, df, mapping)
 
@@ -98,6 +109,18 @@ def mapping_model(cls) -> ABoxJsonMapping:
     # OVERRIDE
     @property
     def json_ld(cls) -> Dict[str, Any]:
+        """
+        Returns the JSON-LD representation of the parser's data.
+
+        This method generates the JSON-LD representation of the parser's data,
+        including the context, id, type, and members. The members are generated
+        based on the general metadata and time series metadata.
+
+        The method returns a dictionary containing the JSON-LD representation.
+
+        :return: A dictionary containing the JSON-LD representation.
+        :rtype: Dict[str, Any]
+        """
         if not cls.config.suppress_file_description:
             members = []
 
@@ -202,6 +225,16 @@ def json_ld(cls) -> Dict[str, Any]:
     # OVERRIDE
     @classmethod
     def _load_data_file(cls, self: "JsonABoxParser") -> "Dict[str, Any]":
+        """
+        Class method for loading data file.
+
+        Args:
+            cls: The class of the parser.
+            self: An instance of JsonABoxParser.
+
+        Returns:
+            Dict[str, Any]: The loaded data file.
+        """
         return _load_data_file(self)
 
     # OVERRIDE
@@ -213,9 +246,18 @@ def _run_parser(
         mapping: "List[ABoxJsonMapping]",
     ) -> None:
         """
-        Parse metadata, time series metadata and time series
-        """
+        Class method for parsing metadata, time series metadata,
+        and time series from a given data file and mapping.
 
+        Args:
+            self: An instance of JsonABoxParser.
+            datafile: A dictionary containing the data to be parsed.
+            mapping: A list of ABoxJsonMapping objects defining the
+                     mapping from the data to the ABox.
+
+        Returns:
+            None
+        """
         self._general_metadata = []
         self._time_series_metadata = []
         self._time_series = {}
diff --git a/data2rdf/parsers/utils.py b/data2rdf/parsers/utils.py
index 49520eb3..7f9676a1 100644
--- a/data2rdf/parsers/utils.py
+++ b/data2rdf/parsers/utils.py
@@ -139,8 +139,37 @@ def _make_tbox_classes(
         self._classes.append(subgraph)
 
 
-def _make_tbox_json_ld(cls: "TBoxBaseParser") -> "Dict[str, Any]":
-    ontology_iri = cls.ontology_iri or cls.config.base_iri
+def _make_tbox_json_ld(model: "TBoxBaseParser") -> "Dict[str, Any]":
+    ontology_iri = model.ontology_iri or model.config.base_iri
+    classes = [model.json_ld for model in model.classes]
+    if not model.config.exclude_ontology_title:
+        if model.ontology_title:
+            title = {"dcterms:title": model.ontology_title}
+        else:
+            title = {}
+        if model.authors:
+            authors = {
+                "dcterms:creator": [
+                    {"@type": "foaf:Person", "foaf:name": author}
+                    for author in model.authors
+                ]
+            }
+        else:
+            authors = {}
+        if model.version_info:
+            version = {"owl:versionInfo": model.version_info}
+        else:
+            version = {}
+
+        classes += [
+            {
+                "@id": str(ontology_iri),
+                "@type": "owl:Ontology",
+                **title,
+                **authors,
+                **version,
+            },
+        ]
     return {
         "@context": {
             "owl": "http://www.w3.org/2002/07/owl#",
@@ -148,17 +177,5 @@ def _make_tbox_json_ld(cls: "TBoxBaseParser") -> "Dict[str, Any]":
             "dcterms": "http://purl.org/dc/terms/",
             "foaf": "http://xmlns.com/foaf/spec/",
         },
-        "@graph": [model.json_ld for model in cls.classes]
-        + [
-            {
-                "@id": str(ontology_iri),
-                "@type": "owl:Ontology",
-                "dcterms:title": cls.ontology_title,
-                "owl:versionInfo": cls.version_info,
-                "dcterms:creator": [
-                    {"@type": "foaf:Person", "foaf:name": author}
-                    for author in cls.authors
-                ],
-            },
-        ],
+        "@graph": classes,
     }
diff --git a/data2rdf/pipelines/main.py b/data2rdf/pipelines/main.py
index 1956b709..57c4c531 100644
--- a/data2rdf/pipelines/main.py
+++ b/data2rdf/pipelines/main.py
@@ -137,7 +137,23 @@ def run_pipeline(cls, self: "Data2RDF") -> "Data2RDF":
 
     @property
     def json_ld(cls) -> Dict[str, Any]:
-        """Return dict of json-ld for graph"""
+        """
+        Returns a dictionary of JSON-LD for the graph based on the pipeline mode.
+
+        If the pipeline mode is ABOX, it returns a dictionary containing the context,
+        id, type, and distribution information of the dataset. If the
+        `suppress_file_description` config is False, it also includes the file
+        description. Otherwise, it returns the JSON-LD of the ABox parser.
+
+        If the pipeline mode is TBOX, it returns the JSON-LD of the TBox parser.
+
+        Args:
+            None
+
+        Returns:
+            Dict[str, Any]: A dictionary of JSON-LD for the graph.
+        """
+
         if cls.mode == PipelineMode.ABOX:
             if not cls.config.suppress_file_description:
                 model = {
@@ -177,7 +193,17 @@ def json_ld(cls) -> Dict[str, Any]:
 
     @property
     def graph(cls) -> Graph:
-        """Return graph object"""
+        """
+        Returns a graph object based on the pipeline's JSON-LD data.
+
+        The graph object is created with the identifier specified through the pipeline.
+        It is then populated with the JSON-LD data from the pipeline, and if additional
+        triples are provided, they are validated and added to the graph.
+
+        Returns:
+            Graph: A graph object containing the pipeline's data.
+        """
+
         graph = Graph(identifier=cls.config.graph_identifier)
         graph.parse(data=json.dumps(cls.json_ld), format="json-ld")
         if cls.additional_triples:
diff --git a/docs/config.md b/docs/config.md
index 33daed06..f32c42a5 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -18,6 +18,8 @@ The configuration of the package is crucial for the correct parsing and transfor
 | mapping_csv_separator | str | When the mapping file is a csv, the separator to be used for parsing | ; | No |
 | remove_from_datafile | List[str] | In plain text parsers, e.g. the CSV-parser, there might be the need to remove certain characters when parsing | ['"', "\r", "\n"] | No |
 | suppress_file_description | bool | In ABox mode, the pipeline is producing an additional subgraph graph for describing the data file in its structure, mime type, etc. This will be suppressed if enabled. | False | No |
+| exclude_ontology_file | bool | In TBox mode, exclude the title of the ontology in the graph. | False | No |
+
 
 ```{python}
 example_config = {
@@ -34,5 +36,6 @@ example_config = {
     "mapping_csv_separator": ";",
     "remove_from_datafile": ['"', "\r", "\n"],
     "suppress_file_description": False,
+    "exclude_ontology_file": False,
 }
 ```
diff --git a/tests/tbox/csv_pipeline_test/test_parser.py b/tests/tbox/csv_pipeline_test/test_parser.py
index 36cffa76..b36ae12e 100644
--- a/tests/tbox/csv_pipeline_test/test_parser.py
+++ b/tests/tbox/csv_pipeline_test/test_parser.py
@@ -36,7 +36,7 @@ def test_parser_csv_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -72,7 +72,7 @@ def test_parser_csv_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
diff --git a/tests/tbox/csv_pipeline_test/test_pipeline.py b/tests/tbox/csv_pipeline_test/test_pipeline.py
index b3ac03e3..2759672a 100644
--- a/tests/tbox/csv_pipeline_test/test_pipeline.py
+++ b/tests/tbox/csv_pipeline_test/test_pipeline.py
@@ -38,7 +38,7 @@ def test_csv_pipeline_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -76,7 +76,7 @@ def test_csv_pipeline_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
diff --git a/tests/tbox/json_pipeline_test/output/output_json_parser_wo_title.ttl b/tests/tbox/json_pipeline_test/output/output_json_parser_wo_title.ttl
new file mode 100644
index 00000000..3504e9a0
--- /dev/null
+++ b/tests/tbox/json_pipeline_test/output/output_json_parser_wo_title.ttl
@@ -0,0 +1,25 @@
+@prefix dcterms: <http://purl.org/dc/terms/> .
+@prefix foaf1: <http://xmlns.com/foaf/spec/> .
+@prefix ns1: <https://w3id.org/steel/ProcessOntology/> .
+@prefix owl: <http://www.w3.org/2002/07/owl#> .
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
+@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
+@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
+
+<https://w3id.org/dimat/BulkModulus> a owl:Class ;
+    rdfs:label "B"^^xsd:string ;
+    dcterms:contributor "John Doe"^^xsd:string ;
+    dcterms:description "atio of the infinitesimal pressure increase to the resulting relative decrease of the volume"^^xsd:string ;
+    rdfs:comment ""^^xsd:string ;
+    skos:altlabel "BulkModulus"^^xsd:string ;
+    ns1:hasLabelSource "DIN EN ISO XXX"^^xsd:string ;
+    ns1:hasTypicalUnitLabel "MPa "^^xsd:string .
+
+<https://w3id.org/dimat/ModulusOfElasticity> a owl:Class ;
+    rdfs:label "E"^^xsd:string ;
+    dcterms:contributor "Jane Doe"^^xsd:string ;
+    dcterms:description "Quotient of change of stress and change of extension in the range of evaluation in the elastic regime."^^xsd:string ;
+    rdfs:comment "This row is an example"^^xsd:string ;
+    skos:altlabel "ModulusOfElasticity"^^xsd:string ;
+    ns1:hasLabelSource "DIN EN ISO 6892-1, 3.13"^^xsd:string ;
+    ns1:hasTypicalUnitLabel "GPa"^^xsd:string .
diff --git a/tests/tbox/json_pipeline_test/test_parser.py b/tests/tbox/json_pipeline_test/test_parser.py
index 614720b9..b383b749 100644
--- a/tests/tbox/json_pipeline_test/test_parser.py
+++ b/tests/tbox/json_pipeline_test/test_parser.py
@@ -35,7 +35,7 @@ def test_parser_json_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -70,7 +70,7 @@ def test_parser_json_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
diff --git a/tests/tbox/json_pipeline_test/test_pipeline.py b/tests/tbox/json_pipeline_test/test_pipeline.py
index aca10d1f..f811d508 100644
--- a/tests/tbox/json_pipeline_test/test_pipeline.py
+++ b/tests/tbox/json_pipeline_test/test_pipeline.py
@@ -37,7 +37,7 @@ def test_json_pipeline_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -74,7 +74,7 @@ def test_json_pipeline_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
diff --git a/tests/tbox/json_pipeline_test/test_title_exclusion.py b/tests/tbox/json_pipeline_test/test_title_exclusion.py
new file mode 100644
index 00000000..4a9e53a2
--- /dev/null
+++ b/tests/tbox/json_pipeline_test/test_title_exclusion.py
@@ -0,0 +1,41 @@
+"""JSON Pipeline tbox pytest without title"""
+
+import json
+import os
+
+test_folder = os.path.dirname(os.path.abspath(__file__))
+working_folder = os.path.join(test_folder, "input")
+output_folder = os.path.join(test_folder, "output")
+
+mapping_folder = os.path.join(working_folder, "mapping")
+raw_data = os.path.join(working_folder, "data", "classes.json")
+expected = os.path.join(output_folder, "output_json_parser_wo_title.ttl")
+
+
+def test_json_pipeline_tbox_wo_title() -> None:
+    from rdflib import Graph
+
+    from data2rdf import Data2RDF, Parser  # isort:skip
+
+    path = os.path.join(mapping_folder, "mapping.json")
+    with open(path, encoding="utf-8") as file:
+        mapping = json.load(file)
+
+    pipeline = Data2RDF(
+        mode="tbox",
+        raw_data=raw_data,
+        mapping=mapping,
+        parser=Parser.json,
+        parser_args={
+            "suffix_location": "Ontological concept ID",
+        },
+        config={
+            "base_iri": "https://w3id.org/dimat",
+            "exclude_ontology_title": True,
+        },
+    )
+
+    expected_graph = Graph()
+    expected_graph.parse(expected)
+
+    assert pipeline.graph.isomorphic(expected_graph)
diff --git a/tests/tbox/xls_pipeline_test/test_parser.py b/tests/tbox/xls_pipeline_test/test_parser.py
index 839e58c8..34131f85 100644
--- a/tests/tbox/xls_pipeline_test/test_parser.py
+++ b/tests/tbox/xls_pipeline_test/test_parser.py
@@ -36,7 +36,7 @@ def test_parser_excel_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -72,7 +72,7 @@ def test_parser_excel_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
diff --git a/tests/tbox/xls_pipeline_test/test_pipeline.py b/tests/tbox/xls_pipeline_test/test_pipeline.py
index 4bdbe319..a5fe3f48 100644
--- a/tests/tbox/xls_pipeline_test/test_pipeline.py
+++ b/tests/tbox/xls_pipeline_test/test_pipeline.py
@@ -38,7 +38,7 @@ def test_excel_pipeline_tbox(extension) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",
@@ -76,7 +76,7 @@ def test_excel_pipeline_inputs_tbox(input_kind) -> None:
             "suffix_location": "Ontological concept ID",
             "ontology_title": "Test Ontology",
             "authors": ["Jane Doe"],
-            "header_length": 2,
+            "version_info": "1.0.0",
         },
         config={
             "base_iri": "https://w3id.org/dimat",