From a53d9fd39af3e69db1da5436d64d0b3beed3c0ac Mon Sep 17 00:00:00 2001 From: "alexander.schaal" Date: Tue, 24 Sep 2024 07:31:25 +0200 Subject: [PATCH] Initial commit --- .github/workflows/dim_ut.yaml | 37 + .github/workflows/doc.yaml | 30 + .github/workflows/formatting.yaml | 23 + .github/workflows/style_ut.yaml | 34 + .github/workflows/trace_ut.yaml | 50 + .gitignore | 4 + CHANGELOG.md | 9 + LICENSE | 202 +++ NOTICE.md | 3 + README.md | 18 + dim/.gitignore | 4 + dim/.rubocop.yml | 8 + dim/Gemfile | 3 + dim/Rakefile.rb | 1 + dim/bin/dim | 9 + dim/dim.gemspec | 26 + dim/documentation/.gitignore | 4 + dim/documentation/Makefile | 14 + dim/documentation/createMapping.rb | 102 ++ dim/documentation/footer.rb | 24 + dim/documentation/requirements.txt | 9 + .../source/_static/conversion.drawio.png | Bin 0 -> 20356 bytes .../_static/swa/dynamic/export.drawio.png | Bin 0 -> 38574 bytes .../_static/swa/dynamic/format.drawio.png | Bin 0 -> 55758 bytes .../_static/swa/dynamic/loader.drawio.png | Bin 0 -> 168379 bytes .../swa/dynamic/main_workflow.drawio.png | Bin 0 -> 167081 bytes .../_static/swa/dynamic/options.drawio.png | Bin 0 -> 42441 bytes .../_static/swa/dynamic/stats.drawio.png | Bin 0 -> 13292 bytes .../_static/swa/dynamic/subcommand.drawio.png | Bin 0 -> 35854 bytes .../_static/swa/overview/classes.drawio.png | Bin 0 -> 61406 bytes .../_static/swa/overview/inout.drawio.png | Bin 0 -> 39780 bytes .../swa/scripting/load_scripting.drawio.png | Bin 0 -> 31568 bytes .../swa/scripting/main_scripting.drawio.png | Bin 0 -> 134678 bytes .../swa/scripting/write_scripting.drawio.png | Bin 0 -> 14225 bytes .../_static/swa/usecases/change.drawio.png | Bin 0 -> 46253 bytes .../_static/swa/usecases/data.drawio.png | Bin 0 -> 12888 bytes .../_static/swa/usecases/export.drawio.png | Bin 0 -> 37136 bytes .../_static/swa/usecases/import.drawio.png | Bin 0 -> 64916 bytes .../_static/swa/usecases/legend.drawio.png | Bin 0 -> 36906 bytes .../_static/swa/usecases/reading.drawio.png | Bin 0 -> 31530 bytes .../_static/swa/usecases/stats.drawio.png | Bin 0 -> 34889 bytes .../_static/swa/usecases/verifier.drawio.png | Bin 0 -> 56151 bytes .../_static/swa/usecases/writing.drawio.png | Bin 0 -> 37385 bytes dim/documentation/source/conf.py | 30 + dim/documentation/source/index.rst | 27 + dim/documentation/source/pages/.gitignore | 1 + dim/documentation/source/pages/api.rst | 218 +++ .../source/pages/architecture.rst | 15 + .../source/pages/architecture/classes.rst | 34 + .../source/pages/architecture/dynamic.rst | 174 ++ .../source/pages/architecture/fmea.rst | 107 ++ .../pages/architecture/fmea/dynamic.csv | 33 + .../pages/architecture/fmea/general.csv | 6 + .../pages/architecture/fmea/scripting.csv | 13 + .../source/pages/architecture/inout.rst | 23 + .../source/pages/architecture/legend.rst | 12 + .../source/pages/architecture/scripting.rst | 56 + .../source/pages/architecture/usecases.rst | 137 ++ dim/documentation/source/pages/changelog.rst | 9 + dim/documentation/source/pages/cli.rst | 178 ++ .../source/pages/development.rst | 58 + dim/documentation/source/pages/format.rst | 95 ++ .../source/pages/installation.rst | 25 + .../source/pages/integration.rst | 133 ++ .../source/pages/introduction.rst | 83 + dim/documentation/source/pages/reqConfig.rst | 16 + dim/documentation/source/pages/reqSources.rst | 4 + dim/documentation/source/pages/syntax.rst | 15 + .../source/pages/syntax/attributes.rst | 67 + .../source/pages/syntax/backward.rst | 13 + .../source/pages/syntax/config.rst | 147 ++ .../source/pages/syntax/html.rst | 48 + .../source/pages/syntax/issues.rst | 29 + .../source/pages/syntax/property.rst | 114 ++ .../source/pages/syntax/requirement.rst | 428 +++++ .../source/pages/version_handling.rst | 52 + .../scripting/excelImport/excel_export.csv | 22 + dim/examples/scripting/excelImport/import.rb | 65 + .../scripting/generationStatus/status.rb | 20 + .../generationStatus/test/CRS_SafeRTE.dim | 27 + .../generationStatus/test/SRS_General.dim | 8 + .../generationStatus/test/SRS_SafeRTE.dim | 70 + .../generationStatus/test/config.dim | 7 + .../generationStatus/test/images/test.jpeg | Bin 0 -> 100698 bytes dim/examples/scripting/reimport/merge.rb | 43 + .../scripting/reimport/new/config.dim | 4 + dim/examples/scripting/reimport/new/crs1.dim | 21 + dim/examples/scripting/reimport/new/crs2.dim | 4 + .../scripting/reimport/old/config.dim | 4 + dim/examples/scripting/reimport/old/crs1.dim | 21 + dim/examples/scripting/reimport/old/crs3.dim | 3 + dim/lib/dim.rb | 1 + dim/lib/dim/commands/check.rb | 13 + dim/lib/dim/commands/export.rb | 145 ++ dim/lib/dim/commands/format.rb | 198 +++ dim/lib/dim/commands/stats.rb | 64 + dim/lib/dim/consistency.rb | 187 ++ dim/lib/dim/dimmain.rb | 28 + dim/lib/dim/encoding.rb | 4 + dim/lib/dim/exit_helper.rb | 23 + dim/lib/dim/exporter/csv.rb | 25 + dim/lib/dim/exporter/exporterInterface.rb | 37 + dim/lib/dim/exporter/json.rb | 32 + dim/lib/dim/exporter/rst.rb | 142 ++ dim/lib/dim/ext/psych.rb | 63 + dim/lib/dim/ext/string.rb | 85 + dim/lib/dim/globals.rb | 12 + dim/lib/dim/helpers/attribute_helper.rb | 126 ++ dim/lib/dim/helpers/file_helper.rb | 25 + dim/lib/dim/loader.rb | 581 +++++++ dim/lib/dim/options.rb | 116 ++ dim/lib/dim/requirement.rb | 236 +++ dim/lib/dim/ver.rb | 7 + dim/license.txt | 205 +++ dim/req/config.dim | 7 + dim/req/dim.dim | 1046 ++++++++++++ dim/req/properties.yaml | 3 + dim/spec/api_spec.rb | 211 +++ dim/spec/attribute_helper_spec.rb | 287 ++++ dim/spec/consistency_spec.rb | 94 ++ dim/spec/export_spec.rb | 388 +++++ dim/spec/file_helper_spec.rb | 19 + dim/spec/format_spec.rb | 264 +++ dim/spec/framework/helper.rb | 114 ++ dim/spec/framework/output.rb | 41 + dim/spec/framework/testmain.rb | 23 + dim/spec/loader_attribute_spec.rb | 252 +++ dim/spec/loader_config_spec.rb | 485 ++++++ dim/spec/loader_general_spec.rb | 101 ++ dim/spec/loader_property_spec.rb | 44 + dim/spec/loader_requirement_spec.rb | 94 ++ dim/spec/options_spec.rb | 77 + dim/spec/output_spec.rb | 24 + dim/spec/property_spec.rb | 121 ++ dim/spec/requirement_spec.rb | 1158 +++++++++++++ dim/spec/stats_spec.rb | 35 + .../test_input/auto_asilCal_check/Config.dim | 7 + .../auto_asilCal_check/properties.yaml | 7 + .../auto_asilCal_check/test_module_asil.dim | 11 + .../test_module_asilCal.dim | 11 + .../auto_asilCal_check/test_module_none.dim | 11 + .../circular/config.dim | 7 + .../circular/module1.dim | 5 + .../circular/module2.dim | 5 + .../circular/module3.dim | 5 + .../non_circular/config.dim | 8 + .../non_circular/index.dim | 4 + .../non_circular/module1.dim | 4 + .../non_circular/module2.dim | 3 + .../config.dim | 20 + .../input/module.dim | 7 + .../smd/module.dim | 7 + .../srs/module.dim | 9 + .../swa/module.dim | 8 + .../sys/module.dim | 8 + dim/spec/test_input/convenience/module_ok.dim | 67 + .../Config.dim | 5 + .../test_module.dim | 16 + .../config.dim | 6 + .../test_module_1.dim | 5 + .../test_module_2.dim | 5 + .../test_module_1.dim | 9 + .../different_encodings/ISO8859-1_input.dim | 4 + .../ISO8859-1_input_invalid.dim | 4 + .../different_encodings/Windows1250_input.dim | 4 + .../different_encodings/utf-8_input.dim | 4 + dim/spec/test_input/document/document.dim | 4 + .../test_input/document/document.dim.expected | 4 + .../document/document_and_modulename.dim | 6 + .../test_input/document/empty_document.dim | 4 + .../test_input/document/missing_document.dim | 0 dim/spec/test_input/document/modulename.dim | 4 + .../document/modulename.dim.expected | 4 + .../document/output/csv/Requirements.csv | 3 + .../document/output/json/Requirements.json | 24 + .../document/output/rst/Requirements.rst | 22 + .../empty_custom_attributes_file/Config.dim | 6 + .../attributes.dim | 0 .../test_module.dim | 16 + .../test_input/empty_requirement/module.dim | 3 + dim/spec/test_input/enclosed_check/test.txt | 1 + .../enclosed_check/test_module_1_1.dim | 7 + .../export_calculated_infos/Input1.yml | 36 + .../export_calculated_infos/Input2.yml | 11 + .../output/Requirements1.csv | 10 + .../output/Requirements2.csv | 4 + dim/spec/test_input/export_check/Config.dim | 17 + .../export_check/export_test_12_1.dim | 17 + .../export_check/export_test_12_2.dim | 17 + .../test_input/export_check/images/test.jpeg | Bin 0 -> 100698 bytes .../export_check/images/test_new.jpeg | Bin 0 -> 100698 bytes .../export_check/no_check_enclosed.dim | 18 + .../output/X-_.test___srs_/Requirements.rst | 22 + .../output/index_001_software_companyname.rst | 7 + .../output/index_002_module_companyname.rst | 21 + .../output/index_003_module_xy_company.rst | 7 + .../output/mod01/Requirements.rst | 20 + .../output/mod02/Requirements.rst | 20 + .../output/mod03/Requirements.rst | 20 + .../output/mod04/Requirements.rst | 20 + .../output/mod05/Requirements.rst | 20 + .../output/mod06/Requirements.rst | 20 + .../output/mod07/Requirements.rst | 20 + .../output/mod08/Requirements.rst | 20 + .../output/mod09/Requirements.rst | 20 + .../output/mod10/Requirements.rst | 20 + .../output/mod11/Requirements.rst | 20 + .../output/test_module_1/Requirements.rst | 62 + .../output/test_module_2/Requirements.rst | 123 ++ .../output/test_module_2/images/test.jpeg | Bin 0 -> 100698 bytes .../output/test_module_3/Requirements.rst | 22 + .../output/test_module_4/Requirements.rst | 162 ++ .../output/test_module_5/Requirements.rst | 602 +++++++ .../export_check/test_export_01.dim | 4 + .../export_check/test_export_02.dim | 4 + .../export_check/test_export_03.dim | 4 + .../export_check/test_export_04.dim | 4 + .../export_check/test_export_05.dim | 3 + .../export_check/test_export_06.dim | 5 + .../export_check/test_export_07.dim | 5 + .../export_check/test_export_08.dim | 5 + .../export_check/test_export_09.dim | 5 + .../export_check/test_export_10.dim | 4 + .../export_check/test_export_11.dim | 10 + .../test_input/export_check/test_module_1.dim | 23 + .../test_input/export_check/test_module_2.dim | 73 + .../test_input/export_check/test_module_3.dim | 5 + .../test_input/export_check/test_module_4.dim | 36 + .../test_input/export_check/test_module_5.dim | 130 ++ .../test_input/export_check/test_srs_1.dim | 5 + .../export_check/using_config/Config.dim | 9 + .../using_config/SingleOriginConfig.dim | 5 + .../using_config/images/test.jpeg | Bin 0 -> 100698 bytes .../using_config/images/test_new.jpeg | Bin 0 -> 100698 bytes .../export_check/using_config/module1.dim | 9 + .../export_check/using_config/module2.dim | 9 + .../export_empty_requirements/module.dim | 1 + .../different_sample.txt | 1 + .../export_when_media_file_present/module.dim | 7 + .../export_when_media_file_present/sample.txt | 3 + .../export_with_custom_attributes/Config.dim | 6 + .../attributes.dim | 41 + .../output/Requirements.csv | 5 + .../output/Requirements.json | 86 + .../output/Requirements.rst | 77 + .../test_module.dim | 21 + dim/spec/test_input/filter_check/module.dim | 17 + dim/spec/test_input/format/.gitignore | 1 + .../test_input/format/collection/asil.conf | 5 + .../test_input/format/collection/asil.dim | 10 + .../format/collection/asil.dim.expected | 10 + .../test_input/format/collection/asil.prop | 2 + dim/spec/test_input/format/collection/cal.dim | 23 + .../format/collection/cal.dim.expected | 24 + .../format/collection/change_request.dim | 16 + .../collection/change_request.dim.expected | 17 + .../test_input/format/collection/comment.dim | 18 + .../format/collection/comment.dim.expected | 17 + .../format/collection/complete.conf | 5 + .../format/collection/developer.dim | 13 + .../format/collection/developer.dim.expected | 17 + .../format/collection/enclosedArray.dim | 5 + .../collection/enclosedArray.dim.expected | 5 + .../format/collection/enclosedString.dim | 4 + .../collection/enclosedString.dim.expected | 3 + .../test_input/format/collection/feature.dim | 15 + .../format/collection/feature.dim.expected | 17 + .../test_input/format/collection/language.dim | 26 + .../format/collection/language.dim.expected | 27 + .../format/collection/metadataEmpty.dim | 4 + .../collection/metadataEmpty.dim.expected | 1 + .../format/collection/metadataString.dim | 6 + .../collection/metadataString.dim.expected | 5 + .../format/collection/miscellaneous.dim | 10 + .../collection/miscellaneous.dim.expected | 11 + .../format/collection/oneLiners.dim | 27 + .../format/collection/oneLiners.dim.expected | 28 + .../format/collection/onlyModule.dim | 1 + .../format/collection/onlyModule.dim.expected | 1 + .../test_input/format/collection/order.dim | 33 + .../format/collection/order.dim.expected | 32 + .../test_input/format/collection/refs.dim | 10 + .../format/collection/refs.dim.expected | 12 + .../format/collection/review_status.dim | 8 + .../collection/review_status.dim.expected | 9 + .../test_input/format/collection/sources.dim | 10 + .../format/collection/sources.dim.expected | 12 + .../test_input/format/collection/status.dim | 39 + .../format/collection/status.dim.expected | 39 + .../test_input/format/collection/tags.dim | 10 + .../format/collection/tags.dim.expected | 10 + .../format/collection/test_setups.dim | 11 + .../collection/test_setups.dim.expected | 14 + .../test_input/format/collection/tester.dim | 13 + .../format/collection/tester.dim.expected | 17 + .../test_input/format/collection/text.dim | 119 ++ .../format/collection/text.dim.expected | 136 ++ .../test_input/format/collection/type.dim | 9 + .../format/collection/type.dim.expected | 10 + .../collection/verification_criteria.dim | 10 + .../verification_criteria.dim.expected | 11 + .../collection/verification_methods.dim | 11 + .../verification_methods.dim.expected | 14 + dim/spec/test_input/format/empty/none.dim | 1 + .../test_input/format/empty/none.dim.expected | 1 + dim/spec/test_input/format/inplace/.gitignore | 2 + .../test_input/format/inplace/complete.conf | 6 + .../format/inplace/complete_extra.conf | 6 + dim/spec/test_input/format/inplace/first.dim | 4 + .../format/inplace/first.dim.expected | 4 + dim/spec/test_input/format/inplace/second.dim | 6 + .../format/inplace/second.dim.expected | 3 + .../format/with_custom_attributes/Config.dim | 6 + .../with_custom_attributes/attributes.dim | 39 + .../with_custom_attributes/test_module.dim | 21 + .../test_module.dim.expected | 25 + .../format_lineendings/.gitattributes | 3 + .../test_input/format_lineendings/crlf.dim | 4 + dim/spec/test_input/format_lineendings/lf.dim | 4 + .../test_input/format_lineendings/mixed.dim | 4 + .../invalid_attributes/default_auto.dim | 10 + .../invalid_attributes/invalid_allowed.dim | 7 + .../invalid_attributes/invalid_default.dim | 9 + .../invalid_attributes/invalid_type.dim | 10 + .../invalid_attributes/test_module.dim | 16 + .../invalid_format_style/module.dim | 5 + .../invalid_input/absolute_file_path.dim | 4 + .../invalid_input/backward_config.dim | 5 + .../invalid_input/category_array.dim | 6 + .../invalid_input/config_string.dim | 1 + .../invalid_input/custom_attributes.dim | 7 + .../invalid_input/duplicate_files.dim | 6 + .../invalid_input/duplicate_metadata.dim | 6 + .../test_input/invalid_input/empty_yaml.dim | 0 .../files_key_invalid_string.dim | 4 + .../invalid_input/files_key_no_array.dim | 3 + .../invalid_input/hash_in_files.dim | 6 + .../invalid_config_entry_attribute.dim | 5 + .../invalid_config_toplevel_attribute.dim | 7 + .../invalid_input/invalid_enclosed.dim | 6 + .../invalid_input/invalid_originator.dim | 6 + .../invalid_input/invalid_types.dim | 9 + .../missing_config_entry_attribute.dim | 3 + .../invalid_input/modules/attribute_empty.dim | 4 + .../modules/attribute_no_string.dim | 5 + .../invalid_input/modules/duplicate_keys.dim | 6 + .../invalid_input/modules/duplicate_meta1.dim | 3 + .../invalid_input/modules/duplicate_meta2.dim | 3 + .../modules/duplicate_module.dim | 4 + .../modules/subfolder/Config.dim | 6 + .../invalid_input/modules/test_module_1.dim | 19 + .../invalid_input/modules/test_module_2.dim | 6 + .../modules/toplevel_invalid.dim | 1 + .../modules/unallowed_attribute.dim | 5 + .../invalid_input/modules/valid_test_1.dim | 4 + .../invalid_input/modules/valid_test_2.dim | 4 + .../modules/yaml_syntax_invalid.dim | 4 + .../modules/yaml_syntax_invalid_char.dim | 4 + .../invalid_input/no_match_pattern.dim | 4 + dim/spec/test_input/invalid_input/no_yaml.dim | 0 .../invalid_input/parent_dir_in_path.dim | 4 + .../invalid_input/properties_array.dim | 6 + .../same_module_different_category.dim | 8 + .../same_module_different_owner.dim | 7 + .../invalid_input/yaml_syntax_invalid.dim | 3 + .../empty_property/Config.dim | 6 + .../empty_property/properties.yaml | 0 .../empty_property/test_module_1.dim | 4 + .../invalid_asil_level/Config.dim | 12 + .../invalid_asil_level/properties.yaml | 7 + .../invalid_asil_value/Config.dim | 12 + .../invalid_asil_value/properties.yaml | 6 + .../invalid_property/invalid_file/Config.dim | 12 + .../invalid_file/properties.yaml | 2 + dim/spec/test_input/language/module_ok.dim | 20 + .../language/output/Requirements.json | 86 + .../test_input/load_multiple_files/Config.dim | 4 + .../load_multiple_files/attributes.dim | 10 + .../load_multiple_files/test_module_1.dim | 41 + .../load_multiple_files/test_module_2.dim | 11 + dim/spec/test_input/metadata/meta.dim | 6 + .../test_input/missing_refs/test_module_1.dim | 5 + .../missing_refs/test_module_1.dim.expected | 5 + dim/spec/test_input/nb_space/module.dim | 5 + dim/spec/test_input/nested_html/module.dim | 25 + .../nested_html/output/Requirements.rst | 162 ++ .../test_input/no_tester/test_module_1.dim | 6 + .../one_module_in_several_files/Config.yml | 4 + .../module1/Input1.yml | 4 + .../module2/Input2.yml | 4 + .../prefix_check/req/test_module_3.dim | 4 + .../test_input/prefix_check/test_module_1.dim | 6 + .../test_input/prefix_check/test_module_2.dim | 4 + .../property_file_insertion/Config.dim | 7 + .../property_file_insertion/properties.yaml | 36 + .../test_module_for_information.dim | 12 + .../test_module_for_insertion.dim | 21 + .../test_module_for_requirement.dim | 12 + .../test_module_no_insertions.dim | 9 + .../test_module_text_insertion.dim | 8 + .../test_setups/Config.dim | 7 + .../test_setups/module.dim | 3 + .../test_setups/properties.yaml | 2 + .../Config_circular_reference.dim | 7 + .../Config_invalid_reference.dim | 7 + .../properties_circular_ref.yaml | 2 + .../properties_invalid_ref.yaml | 2 + .../property_file_refs/ref_test_module1.dim | 7 + .../property_file_refs/ref_test_module2.dim | 8 + dim/spec/test_input/relevant/module_ok.dim | 68 + dim/spec/test_input/reqs/asil/default.dim | 3 + dim/spec/test_input/reqs/asil/empty.dim | 4 + .../test_input/reqs/asil/invalid_type.dim | 6 + dim/spec/test_input/reqs/asil/valid.dim | 16 + dim/spec/test_input/reqs/cal/default.dim | 3 + dim/spec/test_input/reqs/cal/empty.dim | 4 + dim/spec/test_input/reqs/cal/invalid_type.dim | 6 + dim/spec/test_input/reqs/cal/valid.dim | 13 + dim/spec/test_input/reqs/comment/default.dim | 4 + .../test_input/reqs/comment/invalid_type.dim | 6 + dim/spec/test_input/reqs/comment/valid.dim | 4 + .../test_input/reqs/comment_lang/default.dim | 7 + .../reqs/comment_lang/no_string.dim | 9 + .../reqs/comment_lang/not_specified.dim | 4 + .../test_input/reqs/comment_lang/valid.dim | 14 + dim/spec/test_input/reqs/cr/default.dim | 4 + dim/spec/test_input/reqs/cr/invalid_type.dim | 6 + dim/spec/test_input/reqs/cr/valid.dim | 4 + .../test_input/reqs/developer/default.dim | 3 + .../reqs/developer/default_config.dim | 4 + .../reqs/developer/invalid_type.dim | 6 + .../reqs/developer/resolve_config.dim | 7 + .../reqs/developer/resolve_input.dim | 7 + .../reqs/developer/resolve_module.dim | 7 + dim/spec/test_input/reqs/developer/valid.dim | 12 + dim/spec/test_input/reqs/enclosed/array.dim | 7 + .../test_input/reqs/enclosed/backward.dim | 3 + dim/spec/test_input/reqs/enclosed/data/a.txt | 0 dim/spec/test_input/reqs/enclosed/data/b.txt | 0 dim/spec/test_input/reqs/enclosed/data/c.txt | 0 dim/spec/test_input/reqs/enclosed/default.dim | 3 + dim/spec/test_input/reqs/enclosed/dot.dim | 3 + dim/spec/test_input/reqs/enclosed/dotdot.dim | 3 + .../test_input/reqs/enclosed/empty_string.dim | 4 + .../test_input/reqs/enclosed/notexist.dim | 4 + dim/spec/test_input/reqs/enclosed/string.dim | 5 + dim/spec/test_input/reqs/feature/default.dim | 4 + .../test_input/reqs/feature/invalid_type.dim | 6 + dim/spec/test_input/reqs/feature/valid.dim | 4 + dim/spec/test_input/reqs/id/comma.dim | 4 + dim/spec/test_input/reqs/id/empty.dim | 1 + dim/spec/test_input/reqs/id/invalid_key.dim | 4 + dim/spec/test_input/reqs/id/invalid_short.dim | 3 + dim/spec/test_input/reqs/id/invalid_value.dim | 9 + dim/spec/test_input/reqs/id/only_id.dim | 3 + dim/spec/test_input/reqs/metadata/data.dim | 7 + dim/spec/test_input/reqs/metadata/default.dim | 3 + .../test_input/reqs/metadata/invalid_type.dim | 4 + dim/spec/test_input/reqs/misc/default.dim | 4 + .../test_input/reqs/misc/invalid_type.dim | 6 + dim/spec/test_input/reqs/misc/valid.dim | 4 + dim/spec/test_input/reqs/module/config.dim | 5 + dim/spec/test_input/reqs/module/default.dim | 3 + dim/spec/test_input/reqs/module/empty.dim | 1 + .../test_input/reqs/module/invalid_type.dim | 1 + dim/spec/test_input/reqs/module/mod1.dim | 3 + dim/spec/test_input/reqs/module/mod2.dim | 3 + .../test_input/reqs/module/without_module.dim | 3 + dim/spec/test_input/reqs/refs/default.dim | 4 + dim/spec/test_input/reqs/refs/duplicate.dim | 8 + .../test_input/reqs/refs/invalid_type.dim | 6 + dim/spec/test_input/reqs/refs/unresolved.dim | 4 + dim/spec/test_input/reqs/refs/valid.dim | 9 + .../test_input/reqs/rs/default_config.dim | 7 + dim/spec/test_input/reqs/rs/default_input.dim | 3 + .../test_input/reqs/rs/default_module.dim | 3 + dim/spec/test_input/reqs/rs/empty.dim | 4 + dim/spec/test_input/reqs/rs/invalid_type.dim | 6 + .../test_input/reqs/rs/resolve_config.dim | 7 + dim/spec/test_input/reqs/rs/resolve_input.dim | 3 + .../test_input/reqs/rs/resolve_module.dim | 3 + dim/spec/test_input/reqs/rs/unknown.dim | 4 + dim/spec/test_input/reqs/rs/valid.dim | 16 + dim/spec/test_input/reqs/sources/default.dim | 4 + .../test_input/reqs/sources/duplicate.dim | 4 + .../test_input/reqs/sources/invalid_type.dim | 6 + dim/spec/test_input/reqs/sources/valid.dim | 7 + dim/spec/test_input/reqs/status/default.dim | 10 + dim/spec/test_input/reqs/status/empty.dim | 4 + .../test_input/reqs/status/invalid_type.dim | 6 + dim/spec/test_input/reqs/status/resolve.dim | 10 + dim/spec/test_input/reqs/status/unknown.dim | 4 + dim/spec/test_input/reqs/status/valid.dim | 10 + .../test_input/reqs/tags_attr/default.dim | 4 + .../test_input/reqs/tags_attr/duplicate.dim | 4 + .../reqs/tags_attr/invalid_type.dim | 6 + .../test_input/reqs/tags_attr/unknown.dim | 4 + dim/spec/test_input/reqs/tags_attr/valid.dim | 9 + dim/spec/test_input/reqs/tester/default.dim | 3 + .../test_input/reqs/tester/default_config.dim | 4 + .../test_input/reqs/tester/invalid_type.dim | 6 + .../test_input/reqs/tester/resolve_config.dim | 7 + .../test_input/reqs/tester/resolve_input.dim | 7 + .../test_input/reqs/tester/resolve_module.dim | 7 + dim/spec/test_input/reqs/tester/valid.dim | 12 + dim/spec/test_input/reqs/text/default.dim | 3 + dim/spec/test_input/reqs/text/no_string.dim | 9 + dim/spec/test_input/reqs/text/valid.dim | 12 + dim/spec/test_input/reqs/text/valid_short.dim | 8 + .../test_input/reqs/text_lang/default.dim | 7 + .../test_input/reqs/text_lang/no_string.dim | 9 + .../reqs/text_lang/not_specified.dim | 4 + dim/spec/test_input/reqs/text_lang/valid.dim | 15 + dim/spec/test_input/reqs/ts/combined_none.dim | 5 + dim/spec/test_input/reqs/ts/default.dim | 3 + .../test_input/reqs/ts/default_config.dim | 4 + dim/spec/test_input/reqs/ts/duplicate.dim | 4 + dim/spec/test_input/reqs/ts/empty.dim | 4 + dim/spec/test_input/reqs/ts/invalid_type.dim | 6 + .../test_input/reqs/ts/resolve_config.dim | 11 + dim/spec/test_input/reqs/ts/resolve_input.dim | 15 + .../test_input/reqs/ts/resolve_module.dim | 15 + .../test_input/reqs/ts/resolve_software.dim | 15 + dim/spec/test_input/reqs/ts/unknown.dim | 4 + dim/spec/test_input/reqs/ts/valid.dim | 7 + dim/spec/test_input/reqs/type/default.dim | 3 + dim/spec/test_input/reqs/type/empty.dim | 4 + dim/spec/test_input/reqs/type/heading101.dim | 4 + dim/spec/test_input/reqs/type/unknown.dim | 4 + dim/spec/test_input/reqs/type/valid.dim | 16 + dim/spec/test_input/reqs/type/valid_short.dim | 8 + dim/spec/test_input/reqs/vc/default.dim | 4 + dim/spec/test_input/reqs/vc/empty.dim | 4 + dim/spec/test_input/reqs/vc/invalid_type.dim | 6 + dim/spec/test_input/reqs/vc/valid.dim | 4 + dim/spec/test_input/reqs/vc_lang/default.dim | 7 + .../test_input/reqs/vc_lang/no_string.dim | 9 + .../test_input/reqs/vc_lang/not_specified.dim | 4 + dim/spec/test_input/reqs/vc_lang/valid.dim | 15 + .../test_input/resolved_function/config.dim | 7 + .../resolved_function/modules/Module1.dim | 23 + .../resolved_function/modules/Module2.dim | 4 + .../same_id_different_files/Config.yml | 6 + .../same_id_different_files/Input1.yml | 7 + .../same_id_different_files/Input2.yml | 4 + .../test_input/same_id_same_file/Config.yml | 5 + .../test_input/same_id_same_file/Input1.yml | 8 + .../slash_in_modname/test_module_1.dim | 9 + .../test_input/software_configs/config.dim | 6 + .../software_configs/test_input.dim | 4 + .../with_category_software/config.dim | 5 + .../invalid_name_check_config.dim | 5 + .../with_category_software/test_module.dim | 4 + .../with_name_check_no_config.dim | 5 + .../without_name_check_config.dim | 4 + .../software_requirements/config.dim | 4 + .../software_requirements/legacy/config.dim | 5 + .../legacy/test_module.dim | 13 + .../missing_aspect/config.dim | 4 + .../missing_aspect/test_module.dim | 4 + .../missing_feature/config.dim | 4 + .../missing_feature/test_module.dim | 4 + .../module_with_invalid_chars/config.dim | 4 + .../module_with_invalid_chars/test_module.dim | 4 + .../config.dim | 4 + .../test_module.dim | 4 + .../module_without_feature/config.dim | 4 + .../module_without_feature/test_module.dim | 4 + .../module_without_srs/config.dim | 5 + .../module_without_srs/test_module.dim | 4 + .../multiple_underscores/config.dim | 4 + .../multiple_underscores/test_module.dim | 4 + .../non_alphanumeric_in_aspect/config.dim | 4 + .../test_module.dim | 4 + .../non_alphanumeric_in_feature/config.dim | 4 + .../test_module.dim | 4 + .../software_requirements/only_srs/config.dim | 4 + .../only_srs/test_module.dim | 4 + .../start_without_srs/config.dim | 4 + .../start_without_srs/test_module.dim | 4 + .../software_requirements/test_module.dim | 4 + .../without_software_category/config.dim | 4 + .../without_software_category/test_module.dim | 10 + dim/spec/test_input/spaces_html/module.dim | 25 + .../spaces_html/output/Requirements.rst | 162 ++ dim/spec/test_input/stats_input/Config.dim | 4 + .../test_input/stats_input/test_module_1.dim | 49 + .../test_input/stats_input/test_module_2.dim | 13 + .../verification_methods/all_none.dim | 5 + .../all_none.dim.expected | 4 + .../verification_methods/none_test_setups.dim | 5 + .../none_verification_methods.dim | 6 + .../verification_methods/Requirement.csv | 7 + .../verification_methods/Requirements.json | 112 ++ .../verification_methods/Requirements.rst | 94 ++ .../verification_methods/single_none.dim | 7 + .../single_none.dim.expected | 7 + .../verification_methods.dim | 21 + .../verification_methods.dim.expected | 18 + .../with_custom_attributes/Config.dim | 6 + .../with_custom_attributes/attributes.dim | 10 + .../Config.dim | 6 + .../attributes.dim | 14 + .../test_module.dim | 16 + .../Config.dim | 6 + .../attributes.dim | 10 + .../test_module.dim | 16 + .../duplicate_attributes/Config.dim | 6 + .../duplicate_attributes/attributes.dim | 10 + .../custom_attributes.dim | 15 + .../duplicate_attributes/test_module.dim | 17 + .../invalid_requirements/Config.dim | 6 + .../invalid_requirements/attributes.dim | 10 + .../invalid_requirements/test_module.dim | 16 + .../multiple_attribute_files/Config.dim | 6 + .../multiple_attribute_files/attributes.dim | 10 + .../custom_attributes.dim | 8 + .../multiple_attribute_files/test_module.dim | 17 + .../output/csv/Requirements.csv | 5 + .../output/rst/Requirements.rst | 41 + .../reference_from_parent/test_module.dim | 16 + .../with_custom_attributes/test_module.dim | 16 + dim/spec/zzz_dummy_spec.rb | 9 + dim/version.txt | 1 + documentation/.gitignore | 2 + documentation/Makefile | 22 + documentation/footer.rb | 24 + documentation/requirements.txt | 9 + documentation/source/conf.py | 21 + documentation/source/index.rst | 41 + dox_style/LICENSE | 202 +++ dox_style/MANIFEST.in | 2 + dox_style/Makefile | 2 + dox_style/README.md | 4 + dox_style/documentation/.gitignore | 2 + dox_style/documentation/Makefile | 12 + dox_style/documentation/footer.rb | 24 + dox_style/documentation/requirements.txt | 9 + dox_style/documentation/source/conf.py | 25 + dox_style/documentation/source/index.rst | 19 + .../source/pages/appendix/changelog.rst | 9 + .../source/pages/appendix/extending.rst | 13 + .../source/pages/user/checks.rst | 102 ++ .../source/pages/user/config.rst | 58 + .../pages/user/config/data_classification.rst | 55 + .../pages/user/config/document_status.rst | 80 + .../document_lifecycle.drawio.png | Bin 0 -> 19375 bytes .../pages/user/config/footer_string.rst | 48 + .../source/pages/user/config/table_colors.rst | 219 +++ .../source/pages/user/config/text_colors.rst | 32 + dox_style/dox_style/__init__.py | 14 + dox_style/dox_style/__main__.py | 6 + dox_style/dox_style/checks/__init__.py | 2 + dox_style/dox_style/checks/check.py | 20 + dox_style/dox_style/checks/dummy.py | 23 + dox_style/dox_style/checks/finding.py | 40 + .../dox_style/checks/heading_levels_check.py | 47 + .../dox_style/checks/include_rst_check.py | 20 + dox_style/dox_style/checks/main.py | 112 ++ .../checks/top_level_casing_check.py | 22 + .../checks/top_level_heading_check.py | 20 + .../checks/top_level_length_check.py | 34 + .../checks/top_level_modulename_check.py | 25 + .../checks/trailing_whitespace_check.py | 20 + .../checks/underline_length_check.py | 23 + dox_style/dox_style/checks/utils.py | 34 + .../dox_style/config/_static/breadcrumbs.html | 76 + .../config/_static/colored_table.css | 26 + dox_style/dox_style/config/_static/colors.css | 19 + .../dox_style/config/_static/footer.html | 16 + dox_style/dox_style/config/_static/header.css | 27 + .../config/_static/rtd_theme_overrides.css | 57 + dox_style/dox_style/config/label_check.py | 64 + dox_style/dox_style/config/main.py | 156 ++ dox_style/dox_style/version.py | 1 + dox_style/pyproject.toml | 28 + dox_style/tests/__init__.py | 0 dox_style/tests/test_check.py | 39 + dox_style/tests/test_finding.py | 88 + dox_style/tests/test_heading_levels.py | 77 + dox_style/tests/test_include_rst.py | 25 + dox_style/tests/test_top_level.py | 152 ++ dox_style/tests/test_trailing_whitespace.py | 27 + .../tests/test_underline_length_check.py | 35 + dox_style/tests/test_utils.py | 33 + dox_trace/.gitignore | 4 + dox_trace/LICENSE | 202 +++ dox_trace/MANIFEST.in | 2 + dox_trace/README.md | 3 + dox_trace/Rakefile.rb | 1 + dox_trace/documentation/.gitignore | 3 + dox_trace/documentation/Makefile | 14 + dox_trace/documentation/createMapping.rb | 121 ++ dox_trace/documentation/footer.rb | 24 + dox_trace/documentation/properties.yaml | 7 + dox_trace/documentation/requirements.txt | 9 + dox_trace/documentation/source/conf.py | 58 + dox_trace/documentation/source/index.rst | 95 ++ .../source/pages/_static/example.png | Bin 0 -> 2410 bytes .../source/pages/_static/intro.drawio.png | Bin 0 -> 26591 bytes .../pages/_static/module1/doc/index.rst | 6 + .../pages/_static/module1/include/source1.h | 1 + .../pages/_static/module1/include/source2.h | 1 + .../pages/_static/module2/doc/index.rst | 6 + .../_static/swa/appendix/legend.drawio.png | Bin 0 -> 34868 bytes .../_static/swa/dynamic/dh_check.drawio.png | Bin 0 -> 38292 bytes .../_static/swa/dynamic/dh_create.drawio.png | Bin 0 -> 29766 bytes .../_static/swa/dynamic/dh_export.drawio.png | Bin 0 -> 49147 bytes .../_static/swa/dynamic/dh_parse.drawio.png | Bin 0 -> 124906 bytes .../_static/swa/dynamic/dh_setup.drawio.png | Bin 0 -> 52770 bytes .../_static/swa/dynamic/workflow.drawio.png | Bin 0 -> 92874 bytes .../_static/swa/overview/inout.drawio.png | Bin 0 -> 43133 bytes .../_static/swa/overview/static.drawio.png | Bin 0 -> 163558 bytes .../swa/usecases/usecase_change.drawio.png | Bin 0 -> 68853 bytes .../swa/usecases/usecase_export.drawio.png | Bin 0 -> 30689 bytes .../swa/usecases/usecase_review.drawio.png | Bin 0 -> 167960 bytes .../swa/usecases/usecase_view.drawio.png | Bin 0 -> 31182 bytes .../source/pages/_static/trace.drawio.png | Bin 0 -> 35531 bytes .../source/pages/_static/types.drawio.png | Bin 0 -> 29533 bytes .../source/pages/appendix/changelog.rst | 9 + .../source/pages/appendix/config.rst | 48 + .../source/pages/architecture/dynamic.rst | 143 ++ .../source/pages/architecture/fmea.rst | 87 + .../pages/architecture/fmea/dynamic.csv | 69 + .../pages/architecture/fmea/general.csv | 6 + .../source/pages/architecture/inout.rst | 33 + .../source/pages/architecture/legend.rst | 12 + .../source/pages/architecture/static.rst | 60 + .../source/pages/architecture/usecases.rst | 66 + .../source/pages/development/bugTracking.rst | 7 + .../source/pages/development/ci.rst | 9 + .../source/pages/development/release.rst | 11 + .../pages/examples/contents/derivation.inc | 39 + .../source/pages/examples/contents/image.inc | 11 + .../pages/examples/contents/information.inc | 3 + .../pages/examples/contents/invalid.inc | 4 + .../pages/examples/contents/modules.inc | 16 + .../pages/examples/contents/unit2source.inc | 6 + .../source/pages/examples/report.rst | 33 + .../source/pages/examples/specifications.rst | 77 + .../source/pages/examples/undefined_refs.rst | 18 + .../source/pages/requirements/reqConfig.rst | 16 + .../source/pages/started/installation.rst | 11 + .../source/pages/started/integration.rst | 146 ++ .../source/pages/started/introduction.rst | 36 + .../source/pages/user/backward.rst | 115 ++ .../source/pages/user/calcedValues.rst | 102 ++ .../source/pages/user/config.rst | 25 + .../source/pages/user/customAttributes.rst | 82 + .../pages/user/customAttributesExample.inc | 15 + .../source/pages/user/directives.rst | 183 ++ .../source/pages/user/enclosed.rst | 31 + .../source/pages/user/explicitAttributes.rst | 528 ++++++ .../source/pages/user/export.rst | 41 + .../source/pages/user/newlines.rst | 42 + .../source/pages/user/parentValues.rst | 148 ++ .../source/pages/user/properties.rst | 169 ++ .../source/pages/user/rawhtml.rst | 65 + .../source/pages/user/traceability.rst | 167 ++ .../source/pages/user/unintended.rst | 47 + dox_trace/dox_trace/__init__.py | 18 + dox_trace/dox_trace/_static/dox_trace.css | 101 ++ dox_trace/dox_trace/_static/dox_trace.js | 116 ++ dox_trace/dox_trace/backward_refs.py | 241 +++ dox_trace/dox_trace/checks.py | 78 + dox_trace/dox_trace/config.py | 171 ++ dox_trace/dox_trace/coverage.py | 22 + dox_trace/dox_trace/dim_write.py | 75 + dox_trace/dox_trace/directives.py | 820 +++++++++ dox_trace/dox_trace/enclosed.py | 43 + dox_trace/dox_trace/env.py | 110 ++ dox_trace/dox_trace/helper.py | 91 + dox_trace/dox_trace/main.py | 194 +++ dox_trace/dox_trace/properties.py | 75 + dox_trace/dox_trace/report.py | 174 ++ dox_trace/dox_trace/report_architecture.py | 6 + dox_trace/dox_trace/report_generic.py | 362 ++++ dox_trace/dox_trace/report_input.py | 105 ++ dox_trace/dox_trace/report_module.py | 9 + dox_trace/dox_trace/report_source.py | 48 + dox_trace/dox_trace/report_table.py | 174 ++ dox_trace/dox_trace/roles.py | 25 + dox_trace/dox_trace/undefined_refs.py | 65 + dox_trace/dox_trace/version.py | 1 + dox_trace/dox_trace/yaml.py | 26 + dox_trace/pyproject.toml | 29 + dox_trace/req/config.dim | 7 + dox_trace/req/dox_trace.dim | 1498 +++++++++++++++++ dox_trace/req/properties.yaml | 5 + dox_trace/spec/asil_spec.rb | 64 + dox_trace/spec/cal_spec.rb | 78 + dox_trace/spec/category_spec.rb | 98 ++ dox_trace/spec/change_request_spec.rb | 102 ++ dox_trace/spec/checks_spec.rb | 355 ++++ dox_trace/spec/comment_spec.rb | 93 + dox_trace/spec/config_spec.rb | 170 ++ dox_trace/spec/content_spec.rb | 41 + dox_trace/spec/custom_categories_spec.rb | 85 + dox_trace/spec/custom_default_spec.rb | 70 + dox_trace/spec/custom_directives_spec.rb | 98 ++ dox_trace/spec/custom_export_spec.rb | 56 + dox_trace/spec/custom_name_spec.rb | 64 + dox_trace/spec/custom_type_spec.rb | 67 + dox_trace/spec/derived_change_request_spec.rb | 32 + dox_trace/spec/derived_feature_spec.rb | 32 + dox_trace/spec/developer_spec.rb | 73 + dox_trace/spec/directives_spec.rb | 61 + dox_trace/spec/downstream_references_spec.rb | 66 + dox_trace/spec/enclosed_spec.rb | 35 + dox_trace/spec/export_spec.rb | 155 ++ dox_trace/spec/feature_spec.rb | 102 ++ dox_trace/spec/framework/helper.rb | 337 ++++ dox_trace/spec/framework/testmain.rb | 29 + dox_trace/spec/general_spec.rb | 93 + dox_trace/spec/html_spec.rb | 125 ++ dox_trace/spec/ignore_in_export_spec.rb | 25 + dox_trace/spec/location_spec.rb | 120 ++ dox_trace/spec/miscellaneous_spec.rb | 93 + dox_trace/spec/parallel_spec.rb | 47 + dox_trace/spec/parent_asil_spec.rb | 37 + dox_trace/spec/parent_cal_spec.rb | 42 + dox_trace/spec/parent_security_spec.rb | 42 + dox_trace/spec/parent_tags_spec.rb | 35 + dox_trace/spec/properties_spec.rb | 138 ++ dox_trace/spec/refs_spec.rb | 85 + dox_trace/spec/reuse_spec.rb | 104 ++ dox_trace/spec/review_status_spec.rb | 78 + dox_trace/spec/security_spec.rb | 88 + dox_trace/spec/sources_spec.rb | 96 ++ dox_trace/spec/status_spec.rb | 59 + dox_trace/spec/tags_spec.rb | 74 + dox_trace/spec/test_input/asil/Makefile | 10 + dox_trace/spec/test_input/asil/conf.py | 9 + dox_trace/spec/test_input/asil/index.rst | 67 + dox_trace/spec/test_input/cal/Makefile | 10 + dox_trace/spec/test_input/cal/conf.py | 9 + dox_trace/spec/test_input/cal/index.rst | 83 + dox_trace/spec/test_input/category/Makefile | 10 + dox_trace/spec/test_input/category/conf.py | 9 + dox_trace/spec/test_input/category/index.rst | 37 + .../test_input/category_interface/Makefile | 10 + .../test_input/category_interface/conf.py | 9 + .../test_input/category_interface/index.rst | 8 + .../spec/test_input/category_mod/Makefile | 10 + .../spec/test_input/category_mod/conf.py | 9 + .../spec/test_input/category_mod/index.rst | 8 + .../spec/test_input/category_spec/Makefile | 10 + .../spec/test_input/category_spec/conf.py | 9 + .../spec/test_input/category_spec/index.rst | 8 + .../spec/test_input/category_srs/Makefile | 10 + .../spec/test_input/category_srs/conf.py | 9 + .../spec/test_input/category_srs/index.rst | 8 + .../spec/test_input/category_unit/Makefile | 10 + .../spec/test_input/category_unit/conf.py | 9 + .../spec/test_input/category_unit/index.rst | 8 + .../spec/test_input/change_request/Makefile | 10 + .../spec/test_input/change_request/conf.py | 9 + .../spec/test_input/change_request/index.rst | 22 + .../change_request_information/Makefile | 10 + .../change_request_information/conf.py | 9 + .../change_request_information/index.rst | 9 + .../change_request_interface/Makefile | 10 + .../change_request_interface/conf.py | 9 + .../change_request_interface/index.rst | 8 + .../test_input/change_request_mod/Makefile | 10 + .../test_input/change_request_mod/conf.py | 9 + .../test_input/change_request_mod/index.rst | 8 + .../test_input/change_request_spec/Makefile | 10 + .../test_input/change_request_spec/conf.py | 9 + .../test_input/change_request_spec/index.rst | 8 + .../test_input/change_request_srs/Makefile | 10 + .../test_input/change_request_srs/conf.py | 9 + .../test_input/change_request_srs/index.rst | 8 + .../test_input/change_request_unit/Makefile | 10 + .../test_input/change_request_unit/conf.py | 9 + .../test_input/change_request_unit/index.rst | 8 + .../test_input/check_cyclic_direct/Makefile | 10 + .../test_input/check_cyclic_direct/conf.py | 9 + .../test_input/check_cyclic_direct/index.rst | 6 + .../test_input/check_cyclic_indirect/Makefile | 10 + .../test_input/check_cyclic_indirect/conf.py | 9 + .../check_cyclic_indirect/index.rst | 17 + .../check_cyclic_indirect_levels/Makefile | 10 + .../check_cyclic_indirect_levels/conf.py | 9 + .../check_cyclic_indirect_levels/index.rst | 30 + .../test_input/check_invalid_case/Makefile | 10 + .../test_input/check_invalid_case/conf.py | 9 + .../test_input/check_invalid_case/index.rst | 9 + .../check_invalid_comment_ignored/Makefile | 10 + .../check_invalid_comment_ignored/conf.py | 9 + .../check_invalid_comment_ignored/index.rst | 13 + .../check_invalid_comment_interface/Makefile | 10 + .../check_invalid_comment_interface/conf.py | 9 + .../check_invalid_comment_interface/index.rst | 4 + .../check_invalid_comment_mod/Makefile | 10 + .../check_invalid_comment_mod/conf.py | 9 + .../check_invalid_comment_mod/index.rst | 5 + .../check_invalid_comment_spec/Makefile | 10 + .../check_invalid_comment_spec/conf.py | 9 + .../check_invalid_comment_spec/index.rst | 5 + .../check_invalid_comment_srs/Makefile | 10 + .../check_invalid_comment_srs/conf.py | 9 + .../check_invalid_comment_srs/index.rst | 5 + .../check_invalid_comment_unit/Makefile | 10 + .../check_invalid_comment_unit/conf.py | 9 + .../check_invalid_comment_unit/index.rst | 4 + .../test_input/check_invalid_ref/Makefile | 10 + .../spec/test_input/check_invalid_ref/conf.py | 9 + .../test_input/check_invalid_ref/index.rst | 8 + .../check_invalid_ref_suppress/Makefile | 10 + .../check_invalid_ref_suppress/conf.py | 11 + .../check_invalid_ref_suppress/index.rst | 8 + .../check_invalid_sources_interface/Makefile | 10 + .../check_invalid_sources_interface/conf.py | 9 + .../check_invalid_sources_interface/index.rst | 5 + .../Makefile | 10 + .../check_invalid_sources_requirement/conf.py | 9 + .../index.rst | 6 + .../check_invalid_sources_spec/Makefile | 10 + .../check_invalid_sources_spec/conf.py | 9 + .../check_invalid_sources_spec/index.rst | 5 + .../check_invalid_sources_srs/Makefile | 10 + .../check_invalid_sources_srs/conf.py | 9 + .../check_invalid_sources_srs/index.rst | 5 + .../check_invalid_sources_unit/Makefile | 10 + .../check_invalid_sources_unit/conf.py | 9 + .../check_invalid_sources_unit/index.rst | 5 + .../check_naming_double_underscore/Makefile | 10 + .../check_naming_double_underscore/conf.py | 9 + .../check_naming_double_underscore/index.rst | 4 + .../check_naming_lower_case/Makefile | 10 + .../check_naming_lower_case/conf.py | 9 + .../check_naming_lower_case/index.rst | 4 + .../check_naming_three_underscores/Makefile | 10 + .../check_naming_three_underscores/conf.py | 9 + .../check_naming_three_underscores/index.rst | 4 + .../check_naming_too_short/Makefile | 10 + .../test_input/check_naming_too_short/conf.py | 9 + .../check_naming_too_short/index.rst | 4 + .../Makefile | 10 + .../check_naming_too_short_deprecated/conf.py | 10 + .../index.rst | 4 + .../test_input/check_naming_valid/Makefile | 10 + .../test_input/check_naming_valid/conf.py | 9 + .../test_input/check_naming_valid/index.rst | 26 + .../check_naming_valid_tolerant/Makefile | 10 + .../check_naming_valid_tolerant/conf.py | 10 + .../check_naming_valid_tolerant/index.rst | 26 + .../Makefile | 10 + .../conf.py | 9 + .../index.rst | 4 + .../check_naming_wrong_prefix_mod/Makefile | 10 + .../check_naming_wrong_prefix_mod/conf.py | 9 + .../check_naming_wrong_prefix_mod/index.rst | 4 + .../check_naming_wrong_prefix_srs/Makefile | 10 + .../check_naming_wrong_prefix_srs/conf.py | 9 + .../check_naming_wrong_prefix_srs/index.rst | 4 + .../Makefile | 10 + .../conf.py | 10 + .../index.rst | 4 + .../check_naming_wrong_prefix_unit/Makefile | 10 + .../check_naming_wrong_prefix_unit/conf.py | 9 + .../check_naming_wrong_prefix_unit/index.rst | 4 + .../spec/test_input/check_newline_id/Makefile | 10 + .../spec/test_input/check_newline_id/conf.py | 9 + .../test_input/check_newline_id/index.rst | 8 + .../test_input/check_outdated_python/Makefile | 10 + .../test_input/check_outdated_python/conf.py | 9 + .../check_outdated_python/index.rst | 2 + .../test_input/check_outdated_sphinx/Makefile | 10 + .../test_input/check_outdated_sphinx/conf.py | 9 + .../check_outdated_sphinx/index.rst | 2 + .../spec/test_input/check_unique_id/Makefile | 10 + .../spec/test_input/check_unique_id/conf.py | 9 + .../spec/test_input/check_unique_id/index.rst | 9 + .../test_input/check_unique_id/subpage.rst | 5 + dox_trace/spec/test_input/comment/Makefile | 10 + dox_trace/spec/test_input/comment/conf.py | 9 + dox_trace/spec/test_input/comment/index.rst | 36 + .../test_input/comment_interface/Makefile | 10 + .../spec/test_input/comment_interface/conf.py | 9 + .../test_input/comment_interface/index.rst | 8 + .../spec/test_input/comment_mod/Makefile | 10 + dox_trace/spec/test_input/comment_mod/conf.py | 9 + .../spec/test_input/comment_mod/index.rst | 8 + .../spec/test_input/comment_spec/Makefile | 10 + .../spec/test_input/comment_spec/conf.py | 9 + .../spec/test_input/comment_spec/index.rst | 8 + .../spec/test_input/comment_srs/Makefile | 10 + dox_trace/spec/test_input/comment_srs/conf.py | 9 + .../spec/test_input/comment_srs/index.rst | 8 + .../spec/test_input/comment_unit/Makefile | 10 + .../spec/test_input/comment_unit/conf.py | 9 + .../spec/test_input/comment_unit/index.rst | 8 + dox_trace/spec/test_input/config.dim | 10 + dox_trace/spec/test_input/config/Makefile | 10 + dox_trace/spec/test_input/config/conf.py | 19 + dox_trace/spec/test_input/config/filled.rst | 105 ++ dox_trace/spec/test_input/config/index.rst | 51 + dox_trace/spec/test_input/config/special.rst | 67 + dox_trace/spec/test_input/content/Makefile | 10 + dox_trace/spec/test_input/content/conf.py | 9 + dox_trace/spec/test_input/content/index.rst | 53 + .../test_input/custom_categories/Makefile | 10 + .../spec/test_input/custom_categories/conf.py | 26 + .../test_input/custom_categories/index.rst | 35 + .../custom_categories_invalid_empty/Makefile | 10 + .../custom_categories_invalid_empty/conf.py | 15 + .../custom_categories_invalid_empty/index.rst | 4 + .../Makefile | 10 + .../custom_categories_invalid_missing/conf.py | 13 + .../index.rst | 4 + .../custom_categories_invalid_type/Makefile | 10 + .../custom_categories_invalid_type/conf.py | 15 + .../custom_categories_invalid_type/index.rst | 4 + .../custom_categories_invalid_value/Makefile | 10 + .../custom_categories_invalid_value/conf.py | 19 + .../custom_categories_invalid_value/index.rst | 4 + .../spec/test_input/custom_default/Makefile | 10 + .../spec/test_input/custom_default/conf.py | 23 + .../spec/test_input/custom_default/index.rst | 22 + .../custom_default_invalid_nontext/Makefile | 10 + .../custom_default_invalid_nontext/conf.py | 15 + .../custom_default_invalid_nontext/index.rst | 4 + .../custom_default_invalid_text/Makefile | 10 + .../custom_default_invalid_text/conf.py | 15 + .../custom_default_invalid_text/index.rst | 4 + .../test_input/custom_directives/Makefile | 10 + .../spec/test_input/custom_directives/conf.py | 27 + .../test_input/custom_directives/index.rst | 34 + .../custom_directives_invalid_empty/Makefile | 10 + .../custom_directives_invalid_empty/conf.py | 13 + .../custom_directives_invalid_empty/index.rst | 4 + .../Makefile | 10 + .../custom_directives_invalid_missing/conf.py | 13 + .../index.rst | 4 + .../custom_directives_invalid_spec/Makefile | 10 + .../custom_directives_invalid_spec/conf.py | 13 + .../custom_directives_invalid_spec/index.rst | 5 + .../custom_directives_invalid_type/Makefile | 10 + .../custom_directives_invalid_type/conf.py | 13 + .../custom_directives_invalid_type/index.rst | 4 + .../custom_directives_invalid_value/Makefile | 10 + .../custom_directives_invalid_value/conf.py | 13 + .../custom_directives_invalid_value/index.rst | 4 + .../spec/test_input/custom_export/Makefile | 10 + .../spec/test_input/custom_export/conf.py | 20 + .../spec/test_input/custom_export/index.rst | 21 + .../custom_export_invalid_type/Makefile | 10 + .../custom_export_invalid_type/conf.py | 13 + .../custom_export_invalid_type/index.rst | 4 + .../custom_export_invalid_value/Makefile | 10 + .../custom_export_invalid_value/conf.py | 13 + .../custom_export_invalid_value/index.rst | 4 + .../spec/test_input/custom_name/Makefile | 10 + dox_trace/spec/test_input/custom_name/conf.py | 15 + .../spec/test_input/custom_name/index.rst | 5 + .../custom_name_invalid_exists/Makefile | 10 + .../custom_name_invalid_exists/conf.py | 13 + .../custom_name_invalid_exists/index.rst | 4 + .../custom_name_invalid_text/Makefile | 10 + .../custom_name_invalid_text/conf.py | 13 + .../custom_name_invalid_text/index.rst | 4 + .../custom_name_invalid_type/Makefile | 10 + .../custom_name_invalid_type/conf.py | 13 + .../custom_name_invalid_type/index.rst | 4 + .../custom_name_invalid_value/Makefile | 10 + .../custom_name_invalid_value/conf.py | 13 + .../custom_name_invalid_value/index.rst | 4 + .../spec/test_input/custom_type/Makefile | 10 + dox_trace/spec/test_input/custom_type/conf.py | 17 + .../spec/test_input/custom_type/index.rst | 27 + .../custom_type_invalid_missing/Makefile | 10 + .../custom_type_invalid_missing/conf.py | 13 + .../custom_type_invalid_missing/index.rst | 4 + .../custom_type_invalid_type/Makefile | 10 + .../custom_type_invalid_type/conf.py | 13 + .../custom_type_invalid_type/index.rst | 4 + .../custom_type_invalid_value/Makefile | 10 + .../custom_type_invalid_value/conf.py | 13 + .../custom_type_invalid_value/index.rst | 4 + .../derived_change_request/Makefile | 10 + .../test_input/derived_change_request/conf.py | 9 + .../derived_change_request/index.rst | 119 ++ .../spec/test_input/derived_feature/Makefile | 10 + .../spec/test_input/derived_feature/conf.py | 9 + .../spec/test_input/derived_feature/index.rst | 119 ++ dox_trace/spec/test_input/developer/Makefile | 10 + dox_trace/spec/test_input/developer/conf.py | 9 + dox_trace/spec/test_input/developer/index.rst | 61 + .../test_input/developer_information/Makefile | 10 + .../test_input/developer_information/conf.py | 9 + .../developer_information/index.rst | 9 + .../directives_no_empty_line/Makefile | 10 + .../directives_no_empty_line/conf.py | 9 + .../directives_no_empty_line/index.rst | 6 + .../spec/test_input/directives_no_id/Makefile | 10 + .../spec/test_input/directives_no_id/conf.py | 9 + .../test_input/directives_no_id/index.rst | 5 + .../spec/test_input/directives_valid/Makefile | 10 + .../spec/test_input/directives_valid/conf.py | 9 + .../test_input/directives_valid/index.rst | 34 + dox_trace/spec/test_input/enclosed/Makefile | 10 + dox_trace/spec/test_input/enclosed/a.txt | 1 + dox_trace/spec/test_input/enclosed/b/b.txt | 1 + dox_trace/spec/test_input/enclosed/c.txt | 1 + dox_trace/spec/test_input/enclosed/conf.py | 9 + dox_trace/spec/test_input/enclosed/index.rst | 15 + .../spec/test_input/enclosed_invalid/Makefile | 10 + .../spec/test_input/enclosed_invalid/conf.py | 9 + .../test_input/enclosed_invalid/index.rst | 8 + dox_trace/spec/test_input/export/Makefile | 10 + dox_trace/spec/test_input/export/conf.py | 9 + dox_trace/spec/test_input/export/index.rst | 34 + .../spec/test_input/export/subfolder/a.rst | 8 + .../spec/test_input/export/subfolder/b.rst | 7 + .../spec/test_input/export/subfolder/b/c.rst | 7 + .../spec/test_input/export/subfolder/b/d.rst | 4 + .../test_input/export_invalid_config/Makefile | 10 + .../test_input/export_invalid_config/conf.py | 9 + .../export_invalid_config/index.rst | 4 + .../spec/test_input/export_no_config/Makefile | 10 + .../spec/test_input/export_no_config/conf.py | 10 + .../test_input/export_no_config/index.rst | 4 + .../spec/test_input/export_no_srs/Makefile | 10 + .../spec/test_input/export_no_srs/conf.py | 9 + .../spec/test_input/export_no_srs/index.rst | 6 + dox_trace/spec/test_input/feature/Makefile | 10 + dox_trace/spec/test_input/feature/conf.py | 9 + dox_trace/spec/test_input/feature/index.rst | 22 + .../test_input/feature_information/Makefile | 10 + .../test_input/feature_information/conf.py | 9 + .../test_input/feature_information/index.rst | 9 + .../test_input/feature_interface/Makefile | 10 + .../spec/test_input/feature_interface/conf.py | 9 + .../test_input/feature_interface/index.rst | 8 + .../spec/test_input/feature_mod/Makefile | 10 + dox_trace/spec/test_input/feature_mod/conf.py | 9 + .../spec/test_input/feature_mod/index.rst | 8 + .../spec/test_input/feature_spec/Makefile | 10 + .../spec/test_input/feature_spec/conf.py | 9 + .../spec/test_input/feature_spec/index.rst | 8 + .../spec/test_input/feature_srs/Makefile | 10 + dox_trace/spec/test_input/feature_srs/conf.py | 9 + .../spec/test_input/feature_srs/index.rst | 8 + .../spec/test_input/feature_unit/Makefile | 10 + .../spec/test_input/feature_unit/conf.py | 9 + .../spec/test_input/feature_unit/index.rst | 8 + dox_trace/spec/test_input/general/Makefile | 10 + dox_trace/spec/test_input/general/conf.py | 13 + dox_trace/spec/test_input/general/index.rst | 175 ++ dox_trace/spec/test_input/html/Makefile | 10 + dox_trace/spec/test_input/html/conf.py | 12 + dox_trace/spec/test_input/html/index.rst | 41 + dox_trace/spec/test_input/html/subpage.rst | 9 + dox_trace/spec/test_input/html/subpage2.rst | 5 + .../spec/test_input/ignore_in_export/Makefile | 10 + .../spec/test_input/ignore_in_export/conf.py | 9 + .../test_input/ignore_in_export/index.rst | 38 + dox_trace/spec/test_input/location/Makefile | 10 + dox_trace/spec/test_input/location/conf.py | 9 + dox_trace/spec/test_input/location/index.rst | 7 + .../location/modules/driver/doc/index.rst | 4 + .../test_input/location/subfolder/index.rst | 17 + .../test_input/location_information/Makefile | 10 + .../test_input/location_information/conf.py | 9 + .../test_input/location_information/index.rst | 9 + .../test_input/location_interface/Makefile | 10 + .../test_input/location_interface/conf.py | 9 + .../test_input/location_interface/index.rst | 8 + .../test_input/location_requirement/Makefile | 10 + .../test_input/location_requirement/conf.py | 9 + .../test_input/location_requirement/index.rst | 9 + .../spec/test_input/location_spec/Makefile | 10 + .../spec/test_input/location_spec/conf.py | 9 + .../spec/test_input/location_spec/index.rst | 8 + .../spec/test_input/location_srs/Makefile | 10 + .../spec/test_input/location_srs/conf.py | 9 + .../spec/test_input/location_srs/index.rst | 8 + .../spec/test_input/location_unit/Makefile | 10 + .../spec/test_input/location_unit/conf.py | 9 + .../spec/test_input/location_unit/index.rst | 8 + .../spec/test_input/miscellaneous/Makefile | 10 + .../spec/test_input/miscellaneous/conf.py | 9 + .../spec/test_input/miscellaneous/index.rst | 36 + .../miscellaneous_interface/Makefile | 10 + .../miscellaneous_interface/conf.py | 9 + .../miscellaneous_interface/index.rst | 8 + .../test_input/miscellaneous_mod/Makefile | 10 + .../spec/test_input/miscellaneous_mod/conf.py | 9 + .../test_input/miscellaneous_mod/index.rst | 8 + .../test_input/miscellaneous_spec/Makefile | 10 + .../test_input/miscellaneous_spec/conf.py | 9 + .../test_input/miscellaneous_spec/index.rst | 8 + .../test_input/miscellaneous_srs/Makefile | 10 + .../spec/test_input/miscellaneous_srs/conf.py | 9 + .../test_input/miscellaneous_srs/index.rst | 8 + .../test_input/miscellaneous_unit/Makefile | 10 + .../test_input/miscellaneous_unit/conf.py | 9 + .../test_input/miscellaneous_unit/index.rst | 8 + dox_trace/spec/test_input/parallel/Makefile | 10 + dox_trace/spec/test_input/parallel/conf.py | 9 + dox_trace/spec/test_input/parallel/index.rst | 13 + .../spec/test_input/parallel/subpage1.rst | 5 + .../spec/test_input/parallel/subpage2.rst | 4 + .../spec/test_input/parallel/subpage3.rst | 2 + .../spec/test_input/parallel/subpage4.rst | 2 + .../spec/test_input/parallel/subpage5.rst | 2 + dox_trace/spec/test_input/properties/Makefile | 10 + dox_trace/spec/test_input/properties/conf.py | 15 + .../spec/test_input/properties/index.rst | 52 + .../test_input/properties/properties.yaml | 15 + .../test_input/properties_no_file/Makefile | 10 + .../test_input/properties_no_file/conf.py | 11 + .../test_input/properties_no_file/index.rst | 2 + .../test_input/properties_no_name/Makefile | 10 + .../test_input/properties_no_name/conf.py | 11 + .../test_input/properties_no_name/index.rst | 4 + .../properties_no_name/properties.yaml | 1 + .../test_input/properties_no_value/Makefile | 10 + .../test_input/properties_no_value/conf.py | 11 + .../test_input/properties_no_value/index.rst | 4 + .../properties_no_value/properties.yaml | 1 + .../properties_not_available/Makefile | 10 + .../properties_not_available/conf.py | 9 + .../properties_not_available/index.rst | 4 + .../test_input/properties_wrong_file/Makefile | 10 + .../test_input/properties_wrong_file/conf.py | 11 + .../properties_wrong_file/index.rst | 5 + .../properties_wrong_file/properties.yaml | 1 + .../properties_wrong_syntax/Makefile | 10 + .../properties_wrong_syntax/conf.py | 11 + .../properties_wrong_syntax/index.rst | 4 + .../properties_wrong_syntax/properties.yaml | 1 + dox_trace/spec/test_input/refs/Makefile | 10 + dox_trace/spec/test_input/refs/conf.py | 10 + dox_trace/spec/test_input/refs/index.rst | 87 + .../spec/test_input/refs/undefined_refs.rst | 4 + dox_trace/spec/test_input/refs_mod/Makefile | 10 + dox_trace/spec/test_input/refs_mod/conf.py | 9 + dox_trace/spec/test_input/refs_mod/index.rst | 8 + .../test_input/refs_undefined_nowarn/Makefile | 10 + .../test_input/refs_undefined_nowarn/conf.py | 11 + .../refs_undefined_nowarn/index.rst | 15 + .../refs_undefined_nowarn/undefined_refs.rst | 4 + .../test_input/refs_undefined_warn/Makefile | 10 + .../test_input/refs_undefined_warn/conf.py | 9 + .../test_input/refs_undefined_warn/index.rst | 5 + dox_trace/spec/test_input/reuse/Makefile | 10 + dox_trace/spec/test_input/reuse/conf.py | 9 + dox_trace/spec/test_input/reuse/index.rst | 8 + .../test_input/reuse_information/Makefile | 10 + .../spec/test_input/reuse_information/conf.py | 9 + .../test_input/reuse_information/index.rst | 9 + .../spec/test_input/reuse_interface/Makefile | 10 + .../spec/test_input/reuse_interface/conf.py | 9 + .../spec/test_input/reuse_interface/index.rst | 8 + .../test_input/reuse_requirement/Makefile | 10 + .../spec/test_input/reuse_requirement/conf.py | 9 + .../test_input/reuse_requirement/index.rst | 9 + dox_trace/spec/test_input/reuse_spec/Makefile | 10 + dox_trace/spec/test_input/reuse_spec/conf.py | 9 + .../spec/test_input/reuse_spec/index.rst | 8 + dox_trace/spec/test_input/reuse_srs/Makefile | 10 + dox_trace/spec/test_input/reuse_srs/conf.py | 9 + dox_trace/spec/test_input/reuse_srs/index.rst | 8 + dox_trace/spec/test_input/reuse_unit/Makefile | 10 + dox_trace/spec/test_input/reuse_unit/conf.py | 9 + .../spec/test_input/reuse_unit/index.rst | 8 + .../spec/test_input/review_status/Makefile | 10 + .../spec/test_input/review_status/conf.py | 9 + .../spec/test_input/review_status/index.rst | 80 + dox_trace/spec/test_input/security/Makefile | 10 + .../spec/test_input/security/attributes.dim | 7 + dox_trace/spec/test_input/security/conf.py | 10 + dox_trace/spec/test_input/security/index.rst | 92 + dox_trace/spec/test_input/sources/Makefile | 10 + dox_trace/spec/test_input/sources/conf.py | 10 + .../spec/test_input/sources/doc/subpage.rst | 5 + dox_trace/spec/test_input/sources/index.rst | 75 + .../spec/test_input/sources/src/test.abc | 1 + .../test_input/sources_information/Makefile | 10 + .../test_input/sources_information/conf.py | 9 + .../test_input/sources_information/index.rst | 9 + .../spec/test_input/sources_mod/Makefile | 10 + dox_trace/spec/test_input/sources_mod/conf.py | 9 + .../spec/test_input/sources_mod/index.rst | 8 + dox_trace/spec/test_input/status/Makefile | 10 + dox_trace/spec/test_input/status/conf.py | 9 + dox_trace/spec/test_input/status/index.rst | 67 + dox_trace/spec/test_input/tags/Makefile | 10 + dox_trace/spec/test_input/tags/conf.py | 9 + dox_trace/spec/test_input/tags/index.rst | 79 + .../tags/modules/driver/doc/index.rst | 4 + dox_trace/spec/test_input/tags_mod/Makefile | 10 + dox_trace/spec/test_input/tags_mod/conf.py | 9 + dox_trace/spec/test_input/tags_mod/index.rst | 8 + .../spec/test_input/test_setups/Makefile | 10 + dox_trace/spec/test_input/test_setups/conf.py | 11 + .../spec/test_input/test_setups/index.rst | 61 + .../test_setups_information/Makefile | 10 + .../test_setups_information/conf.py | 9 + .../test_setups_information/index.rst | 9 + .../spec/test_input/test_setups_mod/Makefile | 10 + .../spec/test_input/test_setups_mod/conf.py | 9 + .../spec/test_input/test_setups_mod/index.rst | 8 + dox_trace/spec/test_input/tester/Makefile | 10 + dox_trace/spec/test_input/tester/conf.py | 10 + dox_trace/spec/test_input/tester/index.rst | 73 + .../test_input/tester_information/Makefile | 10 + .../test_input/tester_information/conf.py | 9 + .../test_input/tester_information/index.rst | 9 + dox_trace/spec/test_input/tester_mod/Makefile | 10 + dox_trace/spec/test_input/tester_mod/conf.py | 9 + .../spec/test_input/tester_mod/index.rst | 8 + .../tr_architecture_cal_empty/Makefile | 10 + .../tr_architecture_cal_empty/conf.py | 9 + .../tr_architecture_cal_empty/index.rst | 19 + .../tr_architecture_cal_empty/report.rst | 8 + .../tr_architecture_cal_none/Makefile | 10 + .../tr_architecture_cal_none/conf.py | 9 + .../tr_architecture_cal_none/index.rst | 10 + .../tr_architecture_cal_none/report.rst | 8 + .../tr_architecture_cal_table/Makefile | 10 + .../tr_architecture_cal_table/conf.py | 10 + .../tr_architecture_cal_table/index.rst | 27 + .../tr_architecture_cal_table/properties.yaml | 1 + .../tr_architecture_cal_table/report.rst | 8 + .../tr_architecture_cal_table/second.rst | 7 + .../tr_architecture_cal_table/third.rst | 6 + .../tr_architecture_list_empty/Makefile | 10 + .../tr_architecture_list_empty/conf.py | 9 + .../tr_architecture_list_empty/index.rst | 17 + .../tr_architecture_list_empty/report.rst | 8 + .../tr_architecture_list_none/Makefile | 10 + .../tr_architecture_list_none/conf.py | 9 + .../tr_architecture_list_none/index.rst | 11 + .../tr_architecture_list_none/report.rst | 8 + .../tr_architecture_list_table/Makefile | 10 + .../abc/doc/index.rst | 2 + .../tr_architecture_list_table/conf.py | 9 + .../tr_architecture_list_table/index.rst | 49 + .../tr_architecture_list_table/report.rst | 8 + .../tr_architecture_list_table/second.rst | 6 + .../tr_architecture_list_table/third.rst | 14 + .../tr_architecture_ref_empty/Makefile | 10 + .../tr_architecture_ref_empty/conf.py | 9 + .../tr_architecture_ref_empty/index.rst | 17 + .../tr_architecture_ref_empty/report.rst | 8 + .../tr_architecture_ref_none/Makefile | 10 + .../tr_architecture_ref_none/conf.py | 9 + .../tr_architecture_ref_none/index.rst | 11 + .../tr_architecture_ref_none/report.rst | 8 + .../tr_architecture_ref_table/Makefile | 10 + .../abc/doc/index.rst | 2 + .../tr_architecture_ref_table/conf.py | 9 + .../tr_architecture_ref_table/index.rst | 99 ++ .../tr_architecture_ref_table/report.rst | 8 + .../tr_architecture_ref_table/second.rst | 6 + .../tr_architecture_ref_table/third.rst | 14 + .../tr_architecture_safety_empty/Makefile | 10 + .../tr_architecture_safety_empty/conf.py | 9 + .../tr_architecture_safety_empty/index.rst | 19 + .../tr_architecture_safety_empty/report.rst | 8 + .../tr_architecture_safety_none/Makefile | 10 + .../tr_architecture_safety_none/conf.py | 9 + .../tr_architecture_safety_none/index.rst | 10 + .../tr_architecture_safety_none/report.rst | 8 + .../tr_architecture_safety_table/Makefile | 10 + .../tr_architecture_safety_table/conf.py | 9 + .../tr_architecture_safety_table/index.rst | 27 + .../tr_architecture_safety_table/report.rst | 8 + .../tr_architecture_safety_table/second.rst | 7 + .../tr_architecture_safety_table/third.rst | 6 + .../tr_architecture_security_empty/Makefile | 10 + .../tr_architecture_security_empty/conf.py | 11 + .../tr_architecture_security_empty/index.rst | 19 + .../tr_architecture_security_empty/report.rst | 8 + .../tr_architecture_security_none/Makefile | 10 + .../tr_architecture_security_none/conf.py | 11 + .../tr_architecture_security_none/index.rst | 10 + .../tr_architecture_security_none/report.rst | 8 + .../tr_architecture_security_table/Makefile | 10 + .../tr_architecture_security_table/conf.py | 12 + .../tr_architecture_security_table/index.rst | 27 + .../properties.yaml | 1 + .../tr_architecture_security_table/report.rst | 8 + .../tr_architecture_security_table/second.rst | 7 + .../tr_architecture_security_table/third.rst | 6 + .../tr_architecture_status_empty/Makefile | 10 + .../tr_architecture_status_empty/conf.py | 9 + .../tr_architecture_status_empty/index.rst | 16 + .../tr_architecture_status_empty/report.rst | 8 + .../tr_architecture_status_none/Makefile | 10 + .../tr_architecture_status_none/conf.py | 9 + .../tr_architecture_status_none/index.rst | 10 + .../tr_architecture_status_none/report.rst | 8 + .../tr_architecture_status_table/Makefile | 10 + .../tr_architecture_status_table/conf.py | 9 + .../tr_architecture_status_table/index.rst | 27 + .../tr_architecture_status_table/report.rst | 8 + .../tr_architecture_status_table/second.rst | 6 + .../tr_architecture_status_table/third.rst | 5 + .../tr_architecture_type_empty/Makefile | 10 + .../tr_architecture_type_empty/conf.py | 9 + .../tr_architecture_type_empty/index.rst | 20 + .../tr_architecture_type_empty/report.rst | 8 + .../tr_architecture_type_none/Makefile | 10 + .../tr_architecture_type_none/conf.py | 9 + .../tr_architecture_type_none/index.rst | 10 + .../tr_architecture_type_none/report.rst | 8 + .../tr_architecture_type_table/Makefile | 10 + .../tr_architecture_type_table/conf.py | 9 + .../tr_architecture_type_table/index.rst | 28 + .../tr_architecture_type_table/report.rst | 8 + .../tr_architecture_type_table/second.rst | 6 + .../tr_architecture_type_table/third.rst | 5 + .../tr_general_developerregex/Makefile | 10 + .../tr_general_developerregex/conf.py | 9 + .../tr_general_developerregex/index.rst | 37 + .../tr_general_developerregex/report.rst | 8 + .../test_input/tr_general_ignore/Makefile | 10 + .../spec/test_input/tr_general_ignore/conf.py | 9 + .../test_input/tr_general_ignore/index.rst | 11 + .../test_input/tr_general_ignore/report.rst | 8 + .../tr_general_invalidcategory/Makefile | 10 + .../tr_general_invalidcategory/conf.py | 9 + .../tr_general_invalidcategory/index.rst | 9 + .../tr_general_invalidcategory/report.rst | 7 + .../tr_general_missingdeveloper/Makefile | 10 + .../tr_general_missingdeveloper/conf.py | 9 + .../tr_general_missingdeveloper/index.rst | 9 + .../tr_general_missingdeveloper/report.rst | 7 + .../test_input/tr_general_notitle/Makefile | 10 + .../test_input/tr_general_notitle/conf.py | 9 + .../test_input/tr_general_notitle/index.rst | 6 + .../test_input/tr_general_notitle/report.rst | 8 + .../test_input/tr_input_cal_empty/Makefile | 10 + .../test_input/tr_input_cal_empty/conf.py | 9 + .../test_input/tr_input_cal_empty/index.rst | 22 + .../test_input/tr_input_cal_empty/report.rst | 8 + .../test_input/tr_input_cal_none/Makefile | 10 + .../spec/test_input/tr_input_cal_none/conf.py | 9 + .../test_input/tr_input_cal_none/index.rst | 10 + .../test_input/tr_input_cal_none/report.rst | 8 + .../test_input/tr_input_cal_table/Makefile | 10 + .../test_input/tr_input_cal_table/conf.py | 10 + .../test_input/tr_input_cal_table/index.rst | 35 + .../tr_input_cal_table/properties.yaml | 1 + .../test_input/tr_input_cal_table/report.rst | 8 + .../test_input/tr_input_cal_table/second.rst | 9 + .../test_input/tr_input_cal_table/third.rst | 8 + .../test_input/tr_input_dev_none/Makefile | 10 + .../spec/test_input/tr_input_dev_none/conf.py | 9 + .../test_input/tr_input_dev_none/index.rst | 10 + .../test_input/tr_input_dev_none/report.rst | 8 + .../test_input/tr_input_dev_table/Makefile | 10 + .../test_input/tr_input_dev_table/conf.py | 9 + .../test_input/tr_input_dev_table/index.rst | 19 + .../test_input/tr_input_dev_table/report.rst | 8 + .../test_input/tr_input_dev_table/second.rst | 18 + .../test_input/tr_input_list_empty/Makefile | 10 + .../test_input/tr_input_list_empty/conf.py | 9 + .../test_input/tr_input_list_empty/index.rst | 21 + .../test_input/tr_input_list_empty/report.rst | 8 + .../test_input/tr_input_list_none/Makefile | 10 + .../test_input/tr_input_list_none/conf.py | 9 + .../test_input/tr_input_list_none/index.rst | 10 + .../test_input/tr_input_list_none/report.rst | 8 + .../test_input/tr_input_list_table/Makefile | 10 + .../test_input/tr_input_list_table/conf.py | 9 + .../test_input/tr_input_list_table/index.rst | 44 + .../test_input/tr_input_list_table/report.rst | 8 + .../test_input/tr_input_list_table/second.rst | 8 + .../test_input/tr_input_list_table/third.rst | 5 + .../test_input/tr_input_ref_empty/Makefile | 10 + .../test_input/tr_input_ref_empty/conf.py | 9 + .../test_input/tr_input_ref_empty/index.rst | 21 + .../test_input/tr_input_ref_empty/report.rst | 8 + .../test_input/tr_input_ref_none/Makefile | 10 + .../spec/test_input/tr_input_ref_none/conf.py | 9 + .../test_input/tr_input_ref_none/index.rst | 10 + .../test_input/tr_input_ref_none/report.rst | 8 + .../test_input/tr_input_ref_table/Makefile | 10 + .../test_input/tr_input_ref_table/conf.py | 9 + .../test_input/tr_input_ref_table/index.rst | 44 + .../test_input/tr_input_ref_table/report.rst | 8 + .../test_input/tr_input_ref_table/second.rst | 8 + .../test_input/tr_input_ref_table/third.rst | 5 + .../tr_input_reviewstatus_empty/Makefile | 10 + .../tr_input_reviewstatus_empty/conf.py | 9 + .../tr_input_reviewstatus_empty/index.rst | 20 + .../tr_input_reviewstatus_empty/report.rst | 8 + .../tr_input_reviewstatus_none/Makefile | 10 + .../tr_input_reviewstatus_none/conf.py | 9 + .../tr_input_reviewstatus_none/index.rst | 10 + .../tr_input_reviewstatus_none/report.rst | 8 + .../tr_input_reviewstatus_table/Makefile | 10 + .../tr_input_reviewstatus_table/conf.py | 9 + .../tr_input_reviewstatus_table/index.rst | 50 + .../tr_input_reviewstatus_table/report.rst | 8 + .../tr_input_reviewstatus_table/second.rst | 19 + .../tr_input_reviewstatus_table/third.rst | 11 + .../test_input/tr_input_safety_empty/Makefile | 10 + .../test_input/tr_input_safety_empty/conf.py | 9 + .../tr_input_safety_empty/index.rst | 22 + .../tr_input_safety_empty/report.rst | 8 + .../test_input/tr_input_safety_none/Makefile | 10 + .../test_input/tr_input_safety_none/conf.py | 9 + .../test_input/tr_input_safety_none/index.rst | 10 + .../tr_input_safety_none/report.rst | 8 + .../test_input/tr_input_safety_table/Makefile | 10 + .../test_input/tr_input_safety_table/conf.py | 9 + .../tr_input_safety_table/index.rst | 29 + .../tr_input_safety_table/report.rst | 8 + .../tr_input_safety_table/second.rst | 10 + .../tr_input_safety_table/third.rst | 8 + .../tr_input_security_empty/Makefile | 10 + .../tr_input_security_empty/conf.py | 11 + .../tr_input_security_empty/index.rst | 22 + .../tr_input_security_empty/report.rst | 8 + .../tr_input_security_none/Makefile | 10 + .../test_input/tr_input_security_none/conf.py | 11 + .../tr_input_security_none/index.rst | 10 + .../tr_input_security_none/report.rst | 8 + .../tr_input_security_table/Makefile | 10 + .../tr_input_security_table/conf.py | 12 + .../tr_input_security_table/index.rst | 35 + .../tr_input_security_table/properties.yaml | 1 + .../tr_input_security_table/report.rst | 8 + .../tr_input_security_table/second.rst | 9 + .../tr_input_security_table/third.rst | 8 + .../test_input/tr_input_status_empty/Makefile | 10 + .../test_input/tr_input_status_empty/conf.py | 9 + .../tr_input_status_empty/index.rst | 10 + .../tr_input_status_empty/report.rst | 8 + .../test_input/tr_input_status_none/Makefile | 10 + .../test_input/tr_input_status_none/conf.py | 9 + .../test_input/tr_input_status_none/index.rst | 10 + .../tr_input_status_none/report.rst | 8 + .../test_input/tr_input_status_table/Makefile | 10 + .../test_input/tr_input_status_table/conf.py | 9 + .../tr_input_status_table/index.rst | 32 + .../tr_input_status_table/report.rst | 8 + .../tr_input_status_table/second.rst | 12 + .../tr_input_status_table/third.rst | 5 + .../test_input/tr_module_cal_empty/Makefile | 10 + .../test_input/tr_module_cal_empty/conf.py | 9 + .../test_input/tr_module_cal_empty/index.rst | 19 + .../test_input/tr_module_cal_empty/report.rst | 8 + .../test_input/tr_module_cal_none/Makefile | 10 + .../test_input/tr_module_cal_none/conf.py | 9 + .../test_input/tr_module_cal_none/index.rst | 10 + .../test_input/tr_module_cal_none/report.rst | 8 + .../test_input/tr_module_cal_table/Makefile | 10 + .../test_input/tr_module_cal_table/conf.py | 10 + .../test_input/tr_module_cal_table/index.rst | 27 + .../tr_module_cal_table/properties.yaml | 1 + .../test_input/tr_module_cal_table/report.rst | 8 + .../test_input/tr_module_cal_table/second.rst | 7 + .../test_input/tr_module_cal_table/third.rst | 6 + .../test_input/tr_module_list_empty/Makefile | 10 + .../test_input/tr_module_list_empty/conf.py | 10 + .../test_input/tr_module_list_empty/index.rst | 17 + .../tr_module_list_empty/report.rst | 8 + .../test_input/tr_module_list_none/Makefile | 10 + .../test_input/tr_module_list_none/conf.py | 9 + .../test_input/tr_module_list_none/index.rst | 11 + .../test_input/tr_module_list_none/report.rst | 8 + ...ccccccccccccccccccccccccccxAbcccc123xA.txt | 1 + .../test_input/tr_module_list_table/Makefile | 10 + .../test_input/tr_module_list_table/conf.py | 11 + .../test_input/tr_module_list_table/index.rst | 53 + .../tr_module_list_table/report.rst | 8 + .../tr_module_list_table/second.rst | 6 + .../test_input/tr_module_list_table/third.rst | 14 + .../test_input/tr_module_ref_empty/Makefile | 10 + .../test_input/tr_module_ref_empty/conf.py | 10 + .../test_input/tr_module_ref_empty/index.rst | 17 + .../test_input/tr_module_ref_empty/report.rst | 8 + .../test_input/tr_module_ref_none/Makefile | 10 + .../test_input/tr_module_ref_none/conf.py | 9 + .../test_input/tr_module_ref_none/index.rst | 11 + .../test_input/tr_module_ref_none/report.rst | 8 + .../test_input/tr_module_ref_table/Makefile | 10 + .../test_input/tr_module_ref_table/conf.py | 11 + .../test_input/tr_module_ref_table/index.rst | 102 ++ .../test_input/tr_module_ref_table/report.rst | 8 + .../test_input/tr_module_ref_table/second.rst | 6 + .../test_input/tr_module_ref_table/third.rst | 14 + .../tr_module_safety_empty/Makefile | 10 + .../test_input/tr_module_safety_empty/conf.py | 9 + .../tr_module_safety_empty/index.rst | 19 + .../tr_module_safety_empty/report.rst | 8 + .../test_input/tr_module_safety_none/Makefile | 10 + .../test_input/tr_module_safety_none/conf.py | 9 + .../tr_module_safety_none/index.rst | 10 + .../tr_module_safety_none/report.rst | 8 + .../tr_module_safety_table/Makefile | 10 + .../test_input/tr_module_safety_table/conf.py | 9 + .../tr_module_safety_table/index.rst | 27 + .../tr_module_safety_table/report.rst | 8 + .../tr_module_safety_table/second.rst | 8 + .../tr_module_safety_table/third.rst | 6 + .../tr_module_security_empty/Makefile | 10 + .../tr_module_security_empty/conf.py | 11 + .../tr_module_security_empty/index.rst | 19 + .../tr_module_security_empty/report.rst | 8 + .../tr_module_security_none/Makefile | 10 + .../tr_module_security_none/conf.py | 11 + .../tr_module_security_none/index.rst | 10 + .../tr_module_security_none/report.rst | 8 + .../tr_module_security_table/Makefile | 10 + .../tr_module_security_table/conf.py | 12 + .../tr_module_security_table/index.rst | 27 + .../tr_module_security_table/properties.yaml | 1 + .../tr_module_security_table/report.rst | 8 + .../tr_module_security_table/second.rst | 7 + .../tr_module_security_table/third.rst | 6 + .../tr_module_status_empty/Makefile | 10 + .../test_input/tr_module_status_empty/conf.py | 10 + .../tr_module_status_empty/index.rst | 16 + .../tr_module_status_empty/report.rst | 8 + .../test_input/tr_module_status_none/Makefile | 10 + .../test_input/tr_module_status_none/conf.py | 9 + .../tr_module_status_none/index.rst | 10 + .../tr_module_status_none/report.rst | 8 + .../tr_module_status_table/Makefile | 10 + .../test_input/tr_module_status_table/conf.py | 10 + .../tr_module_status_table/index.rst | 27 + .../tr_module_status_table/report.rst | 8 + .../tr_module_status_table/second.rst | 6 + .../tr_module_status_table/third.rst | 5 + .../test_input/tr_module_type_empty/Makefile | 10 + .../test_input/tr_module_type_empty/conf.py | 10 + .../test_input/tr_module_type_empty/index.rst | 20 + .../tr_module_type_empty/report.rst | 8 + .../test_input/tr_module_type_none/Makefile | 10 + .../test_input/tr_module_type_none/conf.py | 9 + .../test_input/tr_module_type_none/index.rst | 10 + .../test_input/tr_module_type_none/report.rst | 8 + .../test_input/tr_module_type_table/Makefile | 10 + .../test_input/tr_module_type_table/conf.py | 9 + .../test_input/tr_module_type_table/index.rst | 24 + .../tr_module_type_table/report.rst | 8 + .../tr_module_type_table/second.rst | 6 + .../test_input/tr_module_type_table/third.rst | 6 + .../tr_module_type_table_deprecated/Makefile | 10 + .../tr_module_type_table_deprecated/conf.py | 10 + .../tr_module_type_table_deprecated/index.rst | 28 + .../report.rst | 8 + .../second.rst | 6 + .../tr_module_type_table_deprecated/third.rst | 6 + .../test_input/tr_software_cal_empty/Makefile | 10 + .../test_input/tr_software_cal_empty/conf.py | 9 + .../tr_software_cal_empty/index.rst | 22 + .../tr_software_cal_empty/report.rst | 8 + .../test_input/tr_software_cal_none/Makefile | 10 + .../test_input/tr_software_cal_none/conf.py | 9 + .../test_input/tr_software_cal_none/index.rst | 10 + .../tr_software_cal_none/report.rst | 8 + .../test_input/tr_software_cal_table/Makefile | 10 + .../test_input/tr_software_cal_table/conf.py | 10 + .../tr_software_cal_table/index.rst | 29 + .../tr_software_cal_table/properties.yaml | 1 + .../tr_software_cal_table/report.rst | 8 + .../tr_software_cal_table/second.rst | 8 + .../tr_software_cal_table/third.rst | 6 + .../tr_software_list_empty/Makefile | 10 + .../test_input/tr_software_list_empty/conf.py | 9 + .../tr_software_list_empty/index.rst | 19 + .../tr_software_list_empty/report.rst | 8 + .../test_input/tr_software_list_none/Makefile | 10 + .../test_input/tr_software_list_none/conf.py | 9 + .../tr_software_list_none/index.rst | 10 + .../tr_software_list_none/report.rst | 8 + .../tr_software_list_table/Makefile | 10 + .../test_input/tr_software_list_table/conf.py | 9 + .../tr_software_list_table/index.rst | 41 + .../tr_software_list_table/report.rst | 8 + .../tr_software_list_table/second.rst | 8 + .../tr_software_list_table/third.rst | 5 + .../test_input/tr_software_ref_empty/Makefile | 10 + .../test_input/tr_software_ref_empty/conf.py | 9 + .../tr_software_ref_empty/index.rst | 19 + .../tr_software_ref_empty/report.rst | 8 + .../test_input/tr_software_ref_none/Makefile | 10 + .../test_input/tr_software_ref_none/conf.py | 9 + .../test_input/tr_software_ref_none/index.rst | 10 + .../tr_software_ref_none/report.rst | 8 + .../test_input/tr_software_ref_table/Makefile | 10 + .../test_input/tr_software_ref_table/conf.py | 9 + .../tr_software_ref_table/index.rst | 41 + .../tr_software_ref_table/report.rst | 8 + .../tr_software_ref_table/second.rst | 8 + .../tr_software_ref_table/third.rst | 5 + .../tr_software_safety_empty/Makefile | 10 + .../tr_software_safety_empty/conf.py | 9 + .../tr_software_safety_empty/index.rst | 22 + .../tr_software_safety_empty/report.rst | 8 + .../tr_software_safety_none/Makefile | 10 + .../tr_software_safety_none/conf.py | 9 + .../tr_software_safety_none/index.rst | 10 + .../tr_software_safety_none/report.rst | 8 + .../tr_software_safety_table/Makefile | 10 + .../tr_software_safety_table/conf.py | 9 + .../tr_software_safety_table/index.rst | 29 + .../tr_software_safety_table/report.rst | 8 + .../tr_software_safety_table/second.rst | 8 + .../tr_software_safety_table/third.rst | 6 + .../tr_software_security_empty/Makefile | 10 + .../tr_software_security_empty/conf.py | 11 + .../tr_software_security_empty/index.rst | 22 + .../tr_software_security_empty/report.rst | 8 + .../tr_software_security_none/Makefile | 10 + .../tr_software_security_none/conf.py | 11 + .../tr_software_security_none/index.rst | 10 + .../tr_software_security_none/report.rst | 8 + .../tr_software_security_table/Makefile | 10 + .../tr_software_security_table/conf.py | 12 + .../tr_software_security_table/index.rst | 29 + .../properties.yaml | 1 + .../tr_software_security_table/report.rst | 8 + .../tr_software_security_table/second.rst | 8 + .../tr_software_security_table/third.rst | 6 + .../tr_software_status_empty/Makefile | 10 + .../tr_software_status_empty/conf.py | 9 + .../tr_software_status_empty/index.rst | 14 + .../tr_software_status_empty/report.rst | 8 + .../tr_software_status_none/Makefile | 10 + .../tr_software_status_none/conf.py | 9 + .../tr_software_status_none/index.rst | 10 + .../tr_software_status_none/report.rst | 8 + .../tr_software_status_table/Makefile | 10 + .../tr_software_status_table/conf.py | 9 + .../tr_software_status_table/index.rst | 30 + .../tr_software_status_table/report.rst | 8 + .../tr_software_status_table/second.rst | 7 + .../tr_software_status_table/third.rst | 5 + .../spec/test_input/tr_source_list/Makefile | 10 + .../spec/test_input/tr_source_list/conf.py | 10 + .../spec/test_input/tr_source_list/index.rst | 38 + .../spec/test_input/tr_source_list/report.rst | 7 + .../spec/test_input/tr_source_list/second.rst | 6 + .../spec/test_input/tr_source_list/third.rst | 14 + .../spec/test_input/tr_source_none/Makefile | 10 + .../spec/test_input/tr_source_none/conf.py | 9 + .../spec/test_input/tr_source_none/index.rst | 11 + .../spec/test_input/tr_source_none/report.rst | 7 + .../test_input/undefined_refs_empty/Makefile | 10 + .../test_input/undefined_refs_empty/conf.py | 9 + .../test_input/undefined_refs_empty/index.rst | 14 + .../undefined_refs_empty/undefined_refs.rst | 4 + .../test_input/undefined_refs_list/Makefile | 10 + .../test_input/undefined_refs_list/conf.py | 11 + .../test_input/undefined_refs_list/index.rst | 15 + .../undefined_refs_list/undefined_refs.rst | 4 + .../spec/test_input/upstream_asil/Makefile | 10 + .../spec/test_input/upstream_asil/conf.py | 9 + .../spec/test_input/upstream_asil/index.rst | 88 + .../spec/test_input/upstream_cal/Makefile | 10 + .../spec/test_input/upstream_cal/conf.py | 9 + .../spec/test_input/upstream_cal/index.rst | 110 ++ .../test_input/upstream_references/Makefile | 10 + .../test_input/upstream_references/conf.py | 10 + .../test_input/upstream_references/index.rst | 125 ++ .../test_input/upstream_security/Makefile | 10 + .../spec/test_input/upstream_security/conf.py | 10 + .../test_input/upstream_security/index.rst | 109 ++ .../spec/test_input/upstream_tags/Makefile | 10 + .../spec/test_input/upstream_tags/conf.py | 9 + .../spec/test_input/upstream_tags/index.rst | 77 + dox_trace/spec/test_input/usage/Makefile | 10 + dox_trace/spec/test_input/usage/conf.py | 9 + dox_trace/spec/test_input/usage/index.rst | 8 + .../test_input/usage_information/Makefile | 10 + .../spec/test_input/usage_information/conf.py | 9 + .../test_input/usage_information/index.rst | 9 + .../spec/test_input/usage_interface/Makefile | 10 + .../spec/test_input/usage_interface/conf.py | 9 + .../spec/test_input/usage_interface/index.rst | 8 + .../test_input/usage_requirement/Makefile | 10 + .../spec/test_input/usage_requirement/conf.py | 9 + .../test_input/usage_requirement/index.rst | 9 + dox_trace/spec/test_input/usage_spec/Makefile | 10 + dox_trace/spec/test_input/usage_spec/conf.py | 9 + .../spec/test_input/usage_spec/index.rst | 8 + dox_trace/spec/test_input/usage_srs/Makefile | 10 + dox_trace/spec/test_input/usage_srs/conf.py | 9 + dox_trace/spec/test_input/usage_srs/index.rst | 8 + dox_trace/spec/test_input/usage_unit/Makefile | 10 + dox_trace/spec/test_input/usage_unit/conf.py | 9 + .../spec/test_input/usage_unit/index.rst | 8 + .../test_input/verification_criteria/Makefile | 10 + .../test_input/verification_criteria/conf.py | 10 + .../verification_criteria/index.rst | 76 + .../Makefile | 10 + .../verification_criteria_information/conf.py | 9 + .../index.rst | 9 + .../verification_criteria_mod/Makefile | 10 + .../verification_criteria_mod/conf.py | 9 + .../verification_criteria_mod/index.rst | 8 + .../test_input/verification_methods/Makefile | 10 + .../test_input/verification_methods/conf.py | 10 + .../test_input/verification_methods/index.rst | 61 + .../verification_methods_information/Makefile | 10 + .../verification_methods_information/conf.py | 9 + .../index.rst | 9 + .../verification_methods_mod/Makefile | 10 + .../verification_methods_mod/conf.py | 9 + .../verification_methods_mod/index.rst | 8 + dox_trace/spec/test_setups_spec.rb | 97 ++ dox_trace/spec/tester_spec.rb | 88 + dox_trace/spec/tr_architecture_spec.rb | 435 +++++ dox_trace/spec/tr_general_spec.rb | 85 + dox_trace/spec/tr_input_spec.rb | 458 +++++ dox_trace/spec/tr_module_spec.rb | 467 +++++ dox_trace/spec/tr_software_spec.rb | 382 +++++ dox_trace/spec/tr_source_spec.rb | 41 + dox_trace/spec/undefined_refs_spec.rb | 36 + dox_trace/spec/upstream_references_spec.rb | 49 + dox_trace/spec/usage_spec.rb | 103 ++ dox_trace/spec/verification_criteria_spec.rb | 90 + dox_trace/spec/verification_methods_spec.rb | 110 ++ dox_trace/spec/zzz_dummy_spec.rb | 13 + dox_util/LICENSE | 202 +++ dox_util/MANIFEST.in | 1 + dox_util/README.md | 11 + dox_util/documentation/.gitignore | 2 + dox_util/documentation/Makefile | 12 + dox_util/documentation/footer.rb | 24 + dox_util/documentation/requirements.txt | 9 + dox_util/documentation/source/conf.py | 34 + dox_util/documentation/source/index.rst | 48 + .../source/pages/appendix/changelog.rst | 9 + .../source/pages/user/extlinks.rst | 63 + .../source/pages/user/linkcheck.rst | 11 + .../documentation/source/pages/user/rule.rst | 32 + .../source/pages/user/source.rst | 58 + .../pages/user/source/include/MemoryManager.h | 1 + .../source/pages/user/toctree.rst | 88 + .../source/pages/user/toctree/example1.rst | 4 + .../source/pages/user/toctree/example2.rst | 4 + .../documentation/source/pages/user/todo.rst | 30 + .../documentation/source/pages/user/weak.rst | 41 + dox_util/dox_util/__init__.py | 52 + dox_util/dox_util/_static/dox_util_colors.css | 3 + dox_util/dox_util/extlinks.py | 31 + dox_util/dox_util/linkcheck.py | 11 + dox_util/dox_util/rule.py | 32 + dox_util/dox_util/source.py | 41 + dox_util/dox_util/toctree.py | 77 + dox_util/dox_util/todo.py | 8 + dox_util/dox_util/version.py | 1 + dox_util/dox_util/weak.py | 34 + dox_util/pyproject.toml | 28 + pyproject.toml | 2 + 1857 files changed, 46675 insertions(+) create mode 100644 .github/workflows/dim_ut.yaml create mode 100644 .github/workflows/doc.yaml create mode 100644 .github/workflows/formatting.yaml create mode 100644 .github/workflows/style_ut.yaml create mode 100644 .github/workflows/trace_ut.yaml create mode 100644 .gitignore create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 NOTICE.md create mode 100644 README.md create mode 100644 dim/.gitignore create mode 100644 dim/.rubocop.yml create mode 100644 dim/Gemfile create mode 100644 dim/Rakefile.rb create mode 100644 dim/bin/dim create mode 100644 dim/dim.gemspec create mode 100644 dim/documentation/.gitignore create mode 100644 dim/documentation/Makefile create mode 100644 dim/documentation/createMapping.rb create mode 100644 dim/documentation/footer.rb create mode 100644 dim/documentation/requirements.txt create mode 100644 dim/documentation/source/_static/conversion.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/export.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/format.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/loader.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/main_workflow.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/options.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/stats.drawio.png create mode 100644 dim/documentation/source/_static/swa/dynamic/subcommand.drawio.png create mode 100644 dim/documentation/source/_static/swa/overview/classes.drawio.png create mode 100644 dim/documentation/source/_static/swa/overview/inout.drawio.png create mode 100644 dim/documentation/source/_static/swa/scripting/load_scripting.drawio.png create mode 100644 dim/documentation/source/_static/swa/scripting/main_scripting.drawio.png create mode 100644 dim/documentation/source/_static/swa/scripting/write_scripting.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/change.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/data.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/export.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/import.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/legend.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/reading.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/stats.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/verifier.drawio.png create mode 100644 dim/documentation/source/_static/swa/usecases/writing.drawio.png create mode 100644 dim/documentation/source/conf.py create mode 100644 dim/documentation/source/index.rst create mode 100644 dim/documentation/source/pages/.gitignore create mode 100644 dim/documentation/source/pages/api.rst create mode 100644 dim/documentation/source/pages/architecture.rst create mode 100644 dim/documentation/source/pages/architecture/classes.rst create mode 100644 dim/documentation/source/pages/architecture/dynamic.rst create mode 100644 dim/documentation/source/pages/architecture/fmea.rst create mode 100644 dim/documentation/source/pages/architecture/fmea/dynamic.csv create mode 100644 dim/documentation/source/pages/architecture/fmea/general.csv create mode 100644 dim/documentation/source/pages/architecture/fmea/scripting.csv create mode 100644 dim/documentation/source/pages/architecture/inout.rst create mode 100644 dim/documentation/source/pages/architecture/legend.rst create mode 100644 dim/documentation/source/pages/architecture/scripting.rst create mode 100644 dim/documentation/source/pages/architecture/usecases.rst create mode 100644 dim/documentation/source/pages/changelog.rst create mode 100644 dim/documentation/source/pages/cli.rst create mode 100644 dim/documentation/source/pages/development.rst create mode 100644 dim/documentation/source/pages/format.rst create mode 100644 dim/documentation/source/pages/installation.rst create mode 100644 dim/documentation/source/pages/integration.rst create mode 100644 dim/documentation/source/pages/introduction.rst create mode 100644 dim/documentation/source/pages/reqConfig.rst create mode 100644 dim/documentation/source/pages/reqSources.rst create mode 100644 dim/documentation/source/pages/syntax.rst create mode 100644 dim/documentation/source/pages/syntax/attributes.rst create mode 100644 dim/documentation/source/pages/syntax/backward.rst create mode 100644 dim/documentation/source/pages/syntax/config.rst create mode 100644 dim/documentation/source/pages/syntax/html.rst create mode 100644 dim/documentation/source/pages/syntax/issues.rst create mode 100644 dim/documentation/source/pages/syntax/property.rst create mode 100644 dim/documentation/source/pages/syntax/requirement.rst create mode 100644 dim/documentation/source/pages/version_handling.rst create mode 100644 dim/examples/scripting/excelImport/excel_export.csv create mode 100644 dim/examples/scripting/excelImport/import.rb create mode 100644 dim/examples/scripting/generationStatus/status.rb create mode 100644 dim/examples/scripting/generationStatus/test/CRS_SafeRTE.dim create mode 100644 dim/examples/scripting/generationStatus/test/SRS_General.dim create mode 100644 dim/examples/scripting/generationStatus/test/SRS_SafeRTE.dim create mode 100644 dim/examples/scripting/generationStatus/test/config.dim create mode 100644 dim/examples/scripting/generationStatus/test/images/test.jpeg create mode 100644 dim/examples/scripting/reimport/merge.rb create mode 100644 dim/examples/scripting/reimport/new/config.dim create mode 100644 dim/examples/scripting/reimport/new/crs1.dim create mode 100644 dim/examples/scripting/reimport/new/crs2.dim create mode 100644 dim/examples/scripting/reimport/old/config.dim create mode 100644 dim/examples/scripting/reimport/old/crs1.dim create mode 100644 dim/examples/scripting/reimport/old/crs3.dim create mode 100644 dim/lib/dim.rb create mode 100644 dim/lib/dim/commands/check.rb create mode 100644 dim/lib/dim/commands/export.rb create mode 100644 dim/lib/dim/commands/format.rb create mode 100644 dim/lib/dim/commands/stats.rb create mode 100644 dim/lib/dim/consistency.rb create mode 100644 dim/lib/dim/dimmain.rb create mode 100644 dim/lib/dim/encoding.rb create mode 100644 dim/lib/dim/exit_helper.rb create mode 100644 dim/lib/dim/exporter/csv.rb create mode 100644 dim/lib/dim/exporter/exporterInterface.rb create mode 100644 dim/lib/dim/exporter/json.rb create mode 100644 dim/lib/dim/exporter/rst.rb create mode 100644 dim/lib/dim/ext/psych.rb create mode 100644 dim/lib/dim/ext/string.rb create mode 100644 dim/lib/dim/globals.rb create mode 100644 dim/lib/dim/helpers/attribute_helper.rb create mode 100644 dim/lib/dim/helpers/file_helper.rb create mode 100644 dim/lib/dim/loader.rb create mode 100644 dim/lib/dim/options.rb create mode 100644 dim/lib/dim/requirement.rb create mode 100644 dim/lib/dim/ver.rb create mode 100644 dim/license.txt create mode 100644 dim/req/config.dim create mode 100644 dim/req/dim.dim create mode 100644 dim/req/properties.yaml create mode 100644 dim/spec/api_spec.rb create mode 100644 dim/spec/attribute_helper_spec.rb create mode 100644 dim/spec/consistency_spec.rb create mode 100644 dim/spec/export_spec.rb create mode 100644 dim/spec/file_helper_spec.rb create mode 100644 dim/spec/format_spec.rb create mode 100644 dim/spec/framework/helper.rb create mode 100644 dim/spec/framework/output.rb create mode 100644 dim/spec/framework/testmain.rb create mode 100644 dim/spec/loader_attribute_spec.rb create mode 100644 dim/spec/loader_config_spec.rb create mode 100644 dim/spec/loader_general_spec.rb create mode 100644 dim/spec/loader_property_spec.rb create mode 100644 dim/spec/loader_requirement_spec.rb create mode 100644 dim/spec/options_spec.rb create mode 100644 dim/spec/output_spec.rb create mode 100644 dim/spec/property_spec.rb create mode 100644 dim/spec/requirement_spec.rb create mode 100644 dim/spec/stats_spec.rb create mode 100644 dim/spec/test_input/auto_asilCal_check/Config.dim create mode 100644 dim/spec/test_input/auto_asilCal_check/properties.yaml create mode 100644 dim/spec/test_input/auto_asilCal_check/test_module_asil.dim create mode 100644 dim/spec/test_input/auto_asilCal_check/test_module_asilCal.dim create mode 100644 dim/spec/test_input/auto_asilCal_check/test_module_none.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/circular/config.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/circular/module1.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/circular/module2.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/circular/module3.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/non_circular/config.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/non_circular/index.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/non_circular/module1.dim create mode 100644 dim/spec/test_input/backward_reference_same_category/non_circular/module2.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/config.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/input/module.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/smd/module.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/srs/module.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/swa/module.dim create mode 100644 dim/spec/test_input/backward_reference_within_category/sys/module.dim create mode 100644 dim/spec/test_input/convenience/module_ok.dim create mode 100644 dim/spec/test_input/custom_attributes_without_attributes_file/Config.dim create mode 100644 dim/spec/test_input/custom_attributes_without_attributes_file/test_module.dim create mode 100644 dim/spec/test_input/cyclic_reference_different_modules/config.dim create mode 100644 dim/spec/test_input/cyclic_reference_different_modules/test_module_1.dim create mode 100644 dim/spec/test_input/cyclic_reference_different_modules/test_module_2.dim create mode 100644 dim/spec/test_input/cyclic_reference_same_file/test_module_1.dim create mode 100644 dim/spec/test_input/different_encodings/ISO8859-1_input.dim create mode 100644 dim/spec/test_input/different_encodings/ISO8859-1_input_invalid.dim create mode 100644 dim/spec/test_input/different_encodings/Windows1250_input.dim create mode 100644 dim/spec/test_input/different_encodings/utf-8_input.dim create mode 100644 dim/spec/test_input/document/document.dim create mode 100644 dim/spec/test_input/document/document.dim.expected create mode 100644 dim/spec/test_input/document/document_and_modulename.dim create mode 100644 dim/spec/test_input/document/empty_document.dim create mode 100644 dim/spec/test_input/document/missing_document.dim create mode 100644 dim/spec/test_input/document/modulename.dim create mode 100644 dim/spec/test_input/document/modulename.dim.expected create mode 100644 dim/spec/test_input/document/output/csv/Requirements.csv create mode 100644 dim/spec/test_input/document/output/json/Requirements.json create mode 100644 dim/spec/test_input/document/output/rst/Requirements.rst create mode 100644 dim/spec/test_input/empty_custom_attributes_file/Config.dim create mode 100644 dim/spec/test_input/empty_custom_attributes_file/attributes.dim create mode 100644 dim/spec/test_input/empty_custom_attributes_file/test_module.dim create mode 100644 dim/spec/test_input/empty_requirement/module.dim create mode 100644 dim/spec/test_input/enclosed_check/test.txt create mode 100644 dim/spec/test_input/enclosed_check/test_module_1_1.dim create mode 100644 dim/spec/test_input/export_calculated_infos/Input1.yml create mode 100644 dim/spec/test_input/export_calculated_infos/Input2.yml create mode 100644 dim/spec/test_input/export_calculated_infos/output/Requirements1.csv create mode 100644 dim/spec/test_input/export_calculated_infos/output/Requirements2.csv create mode 100644 dim/spec/test_input/export_check/Config.dim create mode 100644 dim/spec/test_input/export_check/export_test_12_1.dim create mode 100644 dim/spec/test_input/export_check/export_test_12_2.dim create mode 100644 dim/spec/test_input/export_check/images/test.jpeg create mode 100644 dim/spec/test_input/export_check/images/test_new.jpeg create mode 100644 dim/spec/test_input/export_check/no_check_enclosed.dim create mode 100644 dim/spec/test_input/export_check/output/X-_.test___srs_/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/index_001_software_companyname.rst create mode 100644 dim/spec/test_input/export_check/output/index_002_module_companyname.rst create mode 100644 dim/spec/test_input/export_check/output/index_003_module_xy_company.rst create mode 100644 dim/spec/test_input/export_check/output/mod01/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod02/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod03/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod04/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod05/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod06/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod07/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod08/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod09/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod10/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/mod11/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/test_module_1/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/test_module_2/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/test_module_2/images/test.jpeg create mode 100644 dim/spec/test_input/export_check/output/test_module_3/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/test_module_4/Requirements.rst create mode 100644 dim/spec/test_input/export_check/output/test_module_5/Requirements.rst create mode 100644 dim/spec/test_input/export_check/test_export_01.dim create mode 100644 dim/spec/test_input/export_check/test_export_02.dim create mode 100644 dim/spec/test_input/export_check/test_export_03.dim create mode 100644 dim/spec/test_input/export_check/test_export_04.dim create mode 100644 dim/spec/test_input/export_check/test_export_05.dim create mode 100644 dim/spec/test_input/export_check/test_export_06.dim create mode 100644 dim/spec/test_input/export_check/test_export_07.dim create mode 100644 dim/spec/test_input/export_check/test_export_08.dim create mode 100644 dim/spec/test_input/export_check/test_export_09.dim create mode 100644 dim/spec/test_input/export_check/test_export_10.dim create mode 100644 dim/spec/test_input/export_check/test_export_11.dim create mode 100644 dim/spec/test_input/export_check/test_module_1.dim create mode 100644 dim/spec/test_input/export_check/test_module_2.dim create mode 100644 dim/spec/test_input/export_check/test_module_3.dim create mode 100644 dim/spec/test_input/export_check/test_module_4.dim create mode 100644 dim/spec/test_input/export_check/test_module_5.dim create mode 100644 dim/spec/test_input/export_check/test_srs_1.dim create mode 100644 dim/spec/test_input/export_check/using_config/Config.dim create mode 100644 dim/spec/test_input/export_check/using_config/SingleOriginConfig.dim create mode 100644 dim/spec/test_input/export_check/using_config/images/test.jpeg create mode 100644 dim/spec/test_input/export_check/using_config/images/test_new.jpeg create mode 100644 dim/spec/test_input/export_check/using_config/module1.dim create mode 100644 dim/spec/test_input/export_check/using_config/module2.dim create mode 100644 dim/spec/test_input/export_empty_requirements/module.dim create mode 100644 dim/spec/test_input/export_when_media_file_present/different_sample.txt create mode 100644 dim/spec/test_input/export_when_media_file_present/module.dim create mode 100644 dim/spec/test_input/export_when_media_file_present/sample.txt create mode 100644 dim/spec/test_input/export_with_custom_attributes/Config.dim create mode 100644 dim/spec/test_input/export_with_custom_attributes/attributes.dim create mode 100644 dim/spec/test_input/export_with_custom_attributes/output/Requirements.csv create mode 100644 dim/spec/test_input/export_with_custom_attributes/output/Requirements.json create mode 100644 dim/spec/test_input/export_with_custom_attributes/output/Requirements.rst create mode 100644 dim/spec/test_input/export_with_custom_attributes/test_module.dim create mode 100644 dim/spec/test_input/filter_check/module.dim create mode 100644 dim/spec/test_input/format/.gitignore create mode 100644 dim/spec/test_input/format/collection/asil.conf create mode 100644 dim/spec/test_input/format/collection/asil.dim create mode 100644 dim/spec/test_input/format/collection/asil.dim.expected create mode 100644 dim/spec/test_input/format/collection/asil.prop create mode 100644 dim/spec/test_input/format/collection/cal.dim create mode 100644 dim/spec/test_input/format/collection/cal.dim.expected create mode 100644 dim/spec/test_input/format/collection/change_request.dim create mode 100644 dim/spec/test_input/format/collection/change_request.dim.expected create mode 100644 dim/spec/test_input/format/collection/comment.dim create mode 100644 dim/spec/test_input/format/collection/comment.dim.expected create mode 100644 dim/spec/test_input/format/collection/complete.conf create mode 100644 dim/spec/test_input/format/collection/developer.dim create mode 100644 dim/spec/test_input/format/collection/developer.dim.expected create mode 100644 dim/spec/test_input/format/collection/enclosedArray.dim create mode 100644 dim/spec/test_input/format/collection/enclosedArray.dim.expected create mode 100644 dim/spec/test_input/format/collection/enclosedString.dim create mode 100644 dim/spec/test_input/format/collection/enclosedString.dim.expected create mode 100644 dim/spec/test_input/format/collection/feature.dim create mode 100644 dim/spec/test_input/format/collection/feature.dim.expected create mode 100644 dim/spec/test_input/format/collection/language.dim create mode 100644 dim/spec/test_input/format/collection/language.dim.expected create mode 100644 dim/spec/test_input/format/collection/metadataEmpty.dim create mode 100644 dim/spec/test_input/format/collection/metadataEmpty.dim.expected create mode 100644 dim/spec/test_input/format/collection/metadataString.dim create mode 100644 dim/spec/test_input/format/collection/metadataString.dim.expected create mode 100644 dim/spec/test_input/format/collection/miscellaneous.dim create mode 100644 dim/spec/test_input/format/collection/miscellaneous.dim.expected create mode 100644 dim/spec/test_input/format/collection/oneLiners.dim create mode 100644 dim/spec/test_input/format/collection/oneLiners.dim.expected create mode 100644 dim/spec/test_input/format/collection/onlyModule.dim create mode 100644 dim/spec/test_input/format/collection/onlyModule.dim.expected create mode 100644 dim/spec/test_input/format/collection/order.dim create mode 100644 dim/spec/test_input/format/collection/order.dim.expected create mode 100644 dim/spec/test_input/format/collection/refs.dim create mode 100644 dim/spec/test_input/format/collection/refs.dim.expected create mode 100644 dim/spec/test_input/format/collection/review_status.dim create mode 100644 dim/spec/test_input/format/collection/review_status.dim.expected create mode 100644 dim/spec/test_input/format/collection/sources.dim create mode 100644 dim/spec/test_input/format/collection/sources.dim.expected create mode 100644 dim/spec/test_input/format/collection/status.dim create mode 100644 dim/spec/test_input/format/collection/status.dim.expected create mode 100644 dim/spec/test_input/format/collection/tags.dim create mode 100644 dim/spec/test_input/format/collection/tags.dim.expected create mode 100644 dim/spec/test_input/format/collection/test_setups.dim create mode 100644 dim/spec/test_input/format/collection/test_setups.dim.expected create mode 100644 dim/spec/test_input/format/collection/tester.dim create mode 100644 dim/spec/test_input/format/collection/tester.dim.expected create mode 100644 dim/spec/test_input/format/collection/text.dim create mode 100644 dim/spec/test_input/format/collection/text.dim.expected create mode 100644 dim/spec/test_input/format/collection/type.dim create mode 100644 dim/spec/test_input/format/collection/type.dim.expected create mode 100644 dim/spec/test_input/format/collection/verification_criteria.dim create mode 100644 dim/spec/test_input/format/collection/verification_criteria.dim.expected create mode 100644 dim/spec/test_input/format/collection/verification_methods.dim create mode 100644 dim/spec/test_input/format/collection/verification_methods.dim.expected create mode 100644 dim/spec/test_input/format/empty/none.dim create mode 100644 dim/spec/test_input/format/empty/none.dim.expected create mode 100644 dim/spec/test_input/format/inplace/.gitignore create mode 100644 dim/spec/test_input/format/inplace/complete.conf create mode 100644 dim/spec/test_input/format/inplace/complete_extra.conf create mode 100644 dim/spec/test_input/format/inplace/first.dim create mode 100644 dim/spec/test_input/format/inplace/first.dim.expected create mode 100644 dim/spec/test_input/format/inplace/second.dim create mode 100644 dim/spec/test_input/format/inplace/second.dim.expected create mode 100644 dim/spec/test_input/format/with_custom_attributes/Config.dim create mode 100644 dim/spec/test_input/format/with_custom_attributes/attributes.dim create mode 100644 dim/spec/test_input/format/with_custom_attributes/test_module.dim create mode 100644 dim/spec/test_input/format/with_custom_attributes/test_module.dim.expected create mode 100644 dim/spec/test_input/format_lineendings/.gitattributes create mode 100644 dim/spec/test_input/format_lineendings/crlf.dim create mode 100644 dim/spec/test_input/format_lineendings/lf.dim create mode 100644 dim/spec/test_input/format_lineendings/mixed.dim create mode 100644 dim/spec/test_input/invalid_attributes/default_auto.dim create mode 100644 dim/spec/test_input/invalid_attributes/invalid_allowed.dim create mode 100644 dim/spec/test_input/invalid_attributes/invalid_default.dim create mode 100644 dim/spec/test_input/invalid_attributes/invalid_type.dim create mode 100644 dim/spec/test_input/invalid_attributes/test_module.dim create mode 100644 dim/spec/test_input/invalid_format_style/module.dim create mode 100644 dim/spec/test_input/invalid_input/absolute_file_path.dim create mode 100644 dim/spec/test_input/invalid_input/backward_config.dim create mode 100644 dim/spec/test_input/invalid_input/category_array.dim create mode 100644 dim/spec/test_input/invalid_input/config_string.dim create mode 100644 dim/spec/test_input/invalid_input/custom_attributes.dim create mode 100644 dim/spec/test_input/invalid_input/duplicate_files.dim create mode 100644 dim/spec/test_input/invalid_input/duplicate_metadata.dim create mode 100644 dim/spec/test_input/invalid_input/empty_yaml.dim create mode 100644 dim/spec/test_input/invalid_input/files_key_invalid_string.dim create mode 100644 dim/spec/test_input/invalid_input/files_key_no_array.dim create mode 100644 dim/spec/test_input/invalid_input/hash_in_files.dim create mode 100644 dim/spec/test_input/invalid_input/invalid_config_entry_attribute.dim create mode 100644 dim/spec/test_input/invalid_input/invalid_config_toplevel_attribute.dim create mode 100644 dim/spec/test_input/invalid_input/invalid_enclosed.dim create mode 100644 dim/spec/test_input/invalid_input/invalid_originator.dim create mode 100644 dim/spec/test_input/invalid_input/invalid_types.dim create mode 100644 dim/spec/test_input/invalid_input/missing_config_entry_attribute.dim create mode 100644 dim/spec/test_input/invalid_input/modules/attribute_empty.dim create mode 100644 dim/spec/test_input/invalid_input/modules/attribute_no_string.dim create mode 100644 dim/spec/test_input/invalid_input/modules/duplicate_keys.dim create mode 100644 dim/spec/test_input/invalid_input/modules/duplicate_meta1.dim create mode 100644 dim/spec/test_input/invalid_input/modules/duplicate_meta2.dim create mode 100644 dim/spec/test_input/invalid_input/modules/duplicate_module.dim create mode 100644 dim/spec/test_input/invalid_input/modules/subfolder/Config.dim create mode 100644 dim/spec/test_input/invalid_input/modules/test_module_1.dim create mode 100644 dim/spec/test_input/invalid_input/modules/test_module_2.dim create mode 100644 dim/spec/test_input/invalid_input/modules/toplevel_invalid.dim create mode 100644 dim/spec/test_input/invalid_input/modules/unallowed_attribute.dim create mode 100644 dim/spec/test_input/invalid_input/modules/valid_test_1.dim create mode 100644 dim/spec/test_input/invalid_input/modules/valid_test_2.dim create mode 100644 dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid.dim create mode 100644 dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid_char.dim create mode 100644 dim/spec/test_input/invalid_input/no_match_pattern.dim create mode 100644 dim/spec/test_input/invalid_input/no_yaml.dim create mode 100644 dim/spec/test_input/invalid_input/parent_dir_in_path.dim create mode 100644 dim/spec/test_input/invalid_input/properties_array.dim create mode 100644 dim/spec/test_input/invalid_input/same_module_different_category.dim create mode 100644 dim/spec/test_input/invalid_input/same_module_different_owner.dim create mode 100644 dim/spec/test_input/invalid_input/yaml_syntax_invalid.dim create mode 100644 dim/spec/test_input/invalid_property/empty_property/Config.dim create mode 100644 dim/spec/test_input/invalid_property/empty_property/properties.yaml create mode 100644 dim/spec/test_input/invalid_property/empty_property/test_module_1.dim create mode 100644 dim/spec/test_input/invalid_property/invalid_asil_level/Config.dim create mode 100644 dim/spec/test_input/invalid_property/invalid_asil_level/properties.yaml create mode 100644 dim/spec/test_input/invalid_property/invalid_asil_value/Config.dim create mode 100644 dim/spec/test_input/invalid_property/invalid_asil_value/properties.yaml create mode 100644 dim/spec/test_input/invalid_property/invalid_file/Config.dim create mode 100644 dim/spec/test_input/invalid_property/invalid_file/properties.yaml create mode 100644 dim/spec/test_input/language/module_ok.dim create mode 100644 dim/spec/test_input/language/output/Requirements.json create mode 100644 dim/spec/test_input/load_multiple_files/Config.dim create mode 100644 dim/spec/test_input/load_multiple_files/attributes.dim create mode 100644 dim/spec/test_input/load_multiple_files/test_module_1.dim create mode 100644 dim/spec/test_input/load_multiple_files/test_module_2.dim create mode 100644 dim/spec/test_input/metadata/meta.dim create mode 100644 dim/spec/test_input/missing_refs/test_module_1.dim create mode 100644 dim/spec/test_input/missing_refs/test_module_1.dim.expected create mode 100644 dim/spec/test_input/nb_space/module.dim create mode 100644 dim/spec/test_input/nested_html/module.dim create mode 100644 dim/spec/test_input/nested_html/output/Requirements.rst create mode 100644 dim/spec/test_input/no_tester/test_module_1.dim create mode 100644 dim/spec/test_input/one_module_in_several_files/Config.yml create mode 100644 dim/spec/test_input/one_module_in_several_files/module1/Input1.yml create mode 100644 dim/spec/test_input/one_module_in_several_files/module2/Input2.yml create mode 100644 dim/spec/test_input/prefix_check/req/test_module_3.dim create mode 100644 dim/spec/test_input/prefix_check/test_module_1.dim create mode 100644 dim/spec/test_input/prefix_check/test_module_2.dim create mode 100644 dim/spec/test_input/property_file_insertion/Config.dim create mode 100644 dim/spec/test_input/property_file_insertion/properties.yaml create mode 100644 dim/spec/test_input/property_file_insertion/test_module_for_information.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_module_for_insertion.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_module_for_requirement.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_module_no_insertions.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_module_text_insertion.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_setups/Config.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_setups/module.dim create mode 100644 dim/spec/test_input/property_file_insertion/test_setups/properties.yaml create mode 100644 dim/spec/test_input/property_file_refs/Config_circular_reference.dim create mode 100644 dim/spec/test_input/property_file_refs/Config_invalid_reference.dim create mode 100644 dim/spec/test_input/property_file_refs/properties_circular_ref.yaml create mode 100644 dim/spec/test_input/property_file_refs/properties_invalid_ref.yaml create mode 100644 dim/spec/test_input/property_file_refs/ref_test_module1.dim create mode 100644 dim/spec/test_input/property_file_refs/ref_test_module2.dim create mode 100644 dim/spec/test_input/relevant/module_ok.dim create mode 100644 dim/spec/test_input/reqs/asil/default.dim create mode 100644 dim/spec/test_input/reqs/asil/empty.dim create mode 100644 dim/spec/test_input/reqs/asil/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/asil/valid.dim create mode 100644 dim/spec/test_input/reqs/cal/default.dim create mode 100644 dim/spec/test_input/reqs/cal/empty.dim create mode 100644 dim/spec/test_input/reqs/cal/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/cal/valid.dim create mode 100644 dim/spec/test_input/reqs/comment/default.dim create mode 100644 dim/spec/test_input/reqs/comment/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/comment/valid.dim create mode 100644 dim/spec/test_input/reqs/comment_lang/default.dim create mode 100644 dim/spec/test_input/reqs/comment_lang/no_string.dim create mode 100644 dim/spec/test_input/reqs/comment_lang/not_specified.dim create mode 100644 dim/spec/test_input/reqs/comment_lang/valid.dim create mode 100644 dim/spec/test_input/reqs/cr/default.dim create mode 100644 dim/spec/test_input/reqs/cr/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/cr/valid.dim create mode 100644 dim/spec/test_input/reqs/developer/default.dim create mode 100644 dim/spec/test_input/reqs/developer/default_config.dim create mode 100644 dim/spec/test_input/reqs/developer/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/developer/resolve_config.dim create mode 100644 dim/spec/test_input/reqs/developer/resolve_input.dim create mode 100644 dim/spec/test_input/reqs/developer/resolve_module.dim create mode 100644 dim/spec/test_input/reqs/developer/valid.dim create mode 100644 dim/spec/test_input/reqs/enclosed/array.dim create mode 100644 dim/spec/test_input/reqs/enclosed/backward.dim create mode 100644 dim/spec/test_input/reqs/enclosed/data/a.txt create mode 100644 dim/spec/test_input/reqs/enclosed/data/b.txt create mode 100644 dim/spec/test_input/reqs/enclosed/data/c.txt create mode 100644 dim/spec/test_input/reqs/enclosed/default.dim create mode 100644 dim/spec/test_input/reqs/enclosed/dot.dim create mode 100644 dim/spec/test_input/reqs/enclosed/dotdot.dim create mode 100644 dim/spec/test_input/reqs/enclosed/empty_string.dim create mode 100644 dim/spec/test_input/reqs/enclosed/notexist.dim create mode 100644 dim/spec/test_input/reqs/enclosed/string.dim create mode 100644 dim/spec/test_input/reqs/feature/default.dim create mode 100644 dim/spec/test_input/reqs/feature/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/feature/valid.dim create mode 100644 dim/spec/test_input/reqs/id/comma.dim create mode 100644 dim/spec/test_input/reqs/id/empty.dim create mode 100644 dim/spec/test_input/reqs/id/invalid_key.dim create mode 100644 dim/spec/test_input/reqs/id/invalid_short.dim create mode 100644 dim/spec/test_input/reqs/id/invalid_value.dim create mode 100644 dim/spec/test_input/reqs/id/only_id.dim create mode 100644 dim/spec/test_input/reqs/metadata/data.dim create mode 100644 dim/spec/test_input/reqs/metadata/default.dim create mode 100644 dim/spec/test_input/reqs/metadata/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/misc/default.dim create mode 100644 dim/spec/test_input/reqs/misc/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/misc/valid.dim create mode 100644 dim/spec/test_input/reqs/module/config.dim create mode 100644 dim/spec/test_input/reqs/module/default.dim create mode 100644 dim/spec/test_input/reqs/module/empty.dim create mode 100644 dim/spec/test_input/reqs/module/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/module/mod1.dim create mode 100644 dim/spec/test_input/reqs/module/mod2.dim create mode 100644 dim/spec/test_input/reqs/module/without_module.dim create mode 100644 dim/spec/test_input/reqs/refs/default.dim create mode 100644 dim/spec/test_input/reqs/refs/duplicate.dim create mode 100644 dim/spec/test_input/reqs/refs/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/refs/unresolved.dim create mode 100644 dim/spec/test_input/reqs/refs/valid.dim create mode 100644 dim/spec/test_input/reqs/rs/default_config.dim create mode 100644 dim/spec/test_input/reqs/rs/default_input.dim create mode 100644 dim/spec/test_input/reqs/rs/default_module.dim create mode 100644 dim/spec/test_input/reqs/rs/empty.dim create mode 100644 dim/spec/test_input/reqs/rs/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/rs/resolve_config.dim create mode 100644 dim/spec/test_input/reqs/rs/resolve_input.dim create mode 100644 dim/spec/test_input/reqs/rs/resolve_module.dim create mode 100644 dim/spec/test_input/reqs/rs/unknown.dim create mode 100644 dim/spec/test_input/reqs/rs/valid.dim create mode 100644 dim/spec/test_input/reqs/sources/default.dim create mode 100644 dim/spec/test_input/reqs/sources/duplicate.dim create mode 100644 dim/spec/test_input/reqs/sources/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/sources/valid.dim create mode 100644 dim/spec/test_input/reqs/status/default.dim create mode 100644 dim/spec/test_input/reqs/status/empty.dim create mode 100644 dim/spec/test_input/reqs/status/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/status/resolve.dim create mode 100644 dim/spec/test_input/reqs/status/unknown.dim create mode 100644 dim/spec/test_input/reqs/status/valid.dim create mode 100644 dim/spec/test_input/reqs/tags_attr/default.dim create mode 100644 dim/spec/test_input/reqs/tags_attr/duplicate.dim create mode 100644 dim/spec/test_input/reqs/tags_attr/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/tags_attr/unknown.dim create mode 100644 dim/spec/test_input/reqs/tags_attr/valid.dim create mode 100644 dim/spec/test_input/reqs/tester/default.dim create mode 100644 dim/spec/test_input/reqs/tester/default_config.dim create mode 100644 dim/spec/test_input/reqs/tester/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/tester/resolve_config.dim create mode 100644 dim/spec/test_input/reqs/tester/resolve_input.dim create mode 100644 dim/spec/test_input/reqs/tester/resolve_module.dim create mode 100644 dim/spec/test_input/reqs/tester/valid.dim create mode 100644 dim/spec/test_input/reqs/text/default.dim create mode 100644 dim/spec/test_input/reqs/text/no_string.dim create mode 100644 dim/spec/test_input/reqs/text/valid.dim create mode 100644 dim/spec/test_input/reqs/text/valid_short.dim create mode 100644 dim/spec/test_input/reqs/text_lang/default.dim create mode 100644 dim/spec/test_input/reqs/text_lang/no_string.dim create mode 100644 dim/spec/test_input/reqs/text_lang/not_specified.dim create mode 100644 dim/spec/test_input/reqs/text_lang/valid.dim create mode 100644 dim/spec/test_input/reqs/ts/combined_none.dim create mode 100644 dim/spec/test_input/reqs/ts/default.dim create mode 100644 dim/spec/test_input/reqs/ts/default_config.dim create mode 100644 dim/spec/test_input/reqs/ts/duplicate.dim create mode 100644 dim/spec/test_input/reqs/ts/empty.dim create mode 100644 dim/spec/test_input/reqs/ts/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/ts/resolve_config.dim create mode 100644 dim/spec/test_input/reqs/ts/resolve_input.dim create mode 100644 dim/spec/test_input/reqs/ts/resolve_module.dim create mode 100644 dim/spec/test_input/reqs/ts/resolve_software.dim create mode 100644 dim/spec/test_input/reqs/ts/unknown.dim create mode 100644 dim/spec/test_input/reqs/ts/valid.dim create mode 100644 dim/spec/test_input/reqs/type/default.dim create mode 100644 dim/spec/test_input/reqs/type/empty.dim create mode 100644 dim/spec/test_input/reqs/type/heading101.dim create mode 100644 dim/spec/test_input/reqs/type/unknown.dim create mode 100644 dim/spec/test_input/reqs/type/valid.dim create mode 100644 dim/spec/test_input/reqs/type/valid_short.dim create mode 100644 dim/spec/test_input/reqs/vc/default.dim create mode 100644 dim/spec/test_input/reqs/vc/empty.dim create mode 100644 dim/spec/test_input/reqs/vc/invalid_type.dim create mode 100644 dim/spec/test_input/reqs/vc/valid.dim create mode 100644 dim/spec/test_input/reqs/vc_lang/default.dim create mode 100644 dim/spec/test_input/reqs/vc_lang/no_string.dim create mode 100644 dim/spec/test_input/reqs/vc_lang/not_specified.dim create mode 100644 dim/spec/test_input/reqs/vc_lang/valid.dim create mode 100644 dim/spec/test_input/resolved_function/config.dim create mode 100644 dim/spec/test_input/resolved_function/modules/Module1.dim create mode 100644 dim/spec/test_input/resolved_function/modules/Module2.dim create mode 100644 dim/spec/test_input/same_id_different_files/Config.yml create mode 100644 dim/spec/test_input/same_id_different_files/Input1.yml create mode 100644 dim/spec/test_input/same_id_different_files/Input2.yml create mode 100644 dim/spec/test_input/same_id_same_file/Config.yml create mode 100644 dim/spec/test_input/same_id_same_file/Input1.yml create mode 100644 dim/spec/test_input/slash_in_modname/test_module_1.dim create mode 100644 dim/spec/test_input/software_configs/config.dim create mode 100644 dim/spec/test_input/software_configs/test_input.dim create mode 100644 dim/spec/test_input/software_configs/with_category_software/config.dim create mode 100644 dim/spec/test_input/software_configs/with_category_software/invalid_name_check_config.dim create mode 100644 dim/spec/test_input/software_configs/with_category_software/test_module.dim create mode 100644 dim/spec/test_input/software_configs/with_category_software/with_name_check_no_config.dim create mode 100644 dim/spec/test_input/software_configs/with_category_software/without_name_check_config.dim create mode 100644 dim/spec/test_input/software_requirements/config.dim create mode 100644 dim/spec/test_input/software_requirements/legacy/config.dim create mode 100644 dim/spec/test_input/software_requirements/legacy/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/missing_aspect/config.dim create mode 100644 dim/spec/test_input/software_requirements/missing_aspect/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/missing_feature/config.dim create mode 100644 dim/spec/test_input/software_requirements/missing_feature/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/module_with_invalid_chars/config.dim create mode 100644 dim/spec/test_input/software_requirements/module_with_invalid_chars/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/module_with_multiple_underscores/config.dim create mode 100644 dim/spec/test_input/software_requirements/module_with_multiple_underscores/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/module_without_feature/config.dim create mode 100644 dim/spec/test_input/software_requirements/module_without_feature/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/module_without_srs/config.dim create mode 100644 dim/spec/test_input/software_requirements/module_without_srs/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/multiple_underscores/config.dim create mode 100644 dim/spec/test_input/software_requirements/multiple_underscores/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/config.dim create mode 100644 dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/config.dim create mode 100644 dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/only_srs/config.dim create mode 100644 dim/spec/test_input/software_requirements/only_srs/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/start_without_srs/config.dim create mode 100644 dim/spec/test_input/software_requirements/start_without_srs/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/test_module.dim create mode 100644 dim/spec/test_input/software_requirements/without_software_category/config.dim create mode 100644 dim/spec/test_input/software_requirements/without_software_category/test_module.dim create mode 100644 dim/spec/test_input/spaces_html/module.dim create mode 100644 dim/spec/test_input/spaces_html/output/Requirements.rst create mode 100644 dim/spec/test_input/stats_input/Config.dim create mode 100644 dim/spec/test_input/stats_input/test_module_1.dim create mode 100644 dim/spec/test_input/stats_input/test_module_2.dim create mode 100644 dim/spec/test_input/verification_methods/all_none.dim create mode 100644 dim/spec/test_input/verification_methods/all_none.dim.expected create mode 100644 dim/spec/test_input/verification_methods/none_test_setups.dim create mode 100644 dim/spec/test_input/verification_methods/none_verification_methods.dim create mode 100644 dim/spec/test_input/verification_methods/output/verification_methods/Requirement.csv create mode 100644 dim/spec/test_input/verification_methods/output/verification_methods/Requirements.json create mode 100644 dim/spec/test_input/verification_methods/output/verification_methods/Requirements.rst create mode 100644 dim/spec/test_input/verification_methods/single_none.dim create mode 100644 dim/spec/test_input/verification_methods/single_none.dim.expected create mode 100644 dim/spec/test_input/verification_methods/verification_methods.dim create mode 100644 dim/spec/test_input/verification_methods/verification_methods.dim.expected create mode 100644 dim/spec/test_input/with_custom_attributes/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/duplicate_attributes/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/duplicate_attributes/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/duplicate_attributes/custom_attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/duplicate_attributes/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/invalid_requirements/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/invalid_requirements/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/invalid_requirements/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/multiple_attribute_files/Config.dim create mode 100644 dim/spec/test_input/with_custom_attributes/multiple_attribute_files/attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/multiple_attribute_files/custom_attributes.dim create mode 100644 dim/spec/test_input/with_custom_attributes/multiple_attribute_files/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/output/csv/Requirements.csv create mode 100644 dim/spec/test_input/with_custom_attributes/output/rst/Requirements.rst create mode 100644 dim/spec/test_input/with_custom_attributes/reference_from_parent/test_module.dim create mode 100644 dim/spec/test_input/with_custom_attributes/test_module.dim create mode 100644 dim/spec/zzz_dummy_spec.rb create mode 100644 dim/version.txt create mode 100644 documentation/.gitignore create mode 100644 documentation/Makefile create mode 100644 documentation/footer.rb create mode 100644 documentation/requirements.txt create mode 100644 documentation/source/conf.py create mode 100644 documentation/source/index.rst create mode 100644 dox_style/LICENSE create mode 100644 dox_style/MANIFEST.in create mode 100644 dox_style/Makefile create mode 100644 dox_style/README.md create mode 100644 dox_style/documentation/.gitignore create mode 100644 dox_style/documentation/Makefile create mode 100644 dox_style/documentation/footer.rb create mode 100644 dox_style/documentation/requirements.txt create mode 100644 dox_style/documentation/source/conf.py create mode 100644 dox_style/documentation/source/index.rst create mode 100644 dox_style/documentation/source/pages/appendix/changelog.rst create mode 100644 dox_style/documentation/source/pages/appendix/extending.rst create mode 100644 dox_style/documentation/source/pages/user/checks.rst create mode 100644 dox_style/documentation/source/pages/user/config.rst create mode 100644 dox_style/documentation/source/pages/user/config/data_classification.rst create mode 100644 dox_style/documentation/source/pages/user/config/document_status.rst create mode 100644 dox_style/documentation/source/pages/user/config/document_status/document_lifecycle.drawio.png create mode 100644 dox_style/documentation/source/pages/user/config/footer_string.rst create mode 100644 dox_style/documentation/source/pages/user/config/table_colors.rst create mode 100644 dox_style/documentation/source/pages/user/config/text_colors.rst create mode 100644 dox_style/dox_style/__init__.py create mode 100644 dox_style/dox_style/__main__.py create mode 100644 dox_style/dox_style/checks/__init__.py create mode 100644 dox_style/dox_style/checks/check.py create mode 100644 dox_style/dox_style/checks/dummy.py create mode 100644 dox_style/dox_style/checks/finding.py create mode 100644 dox_style/dox_style/checks/heading_levels_check.py create mode 100644 dox_style/dox_style/checks/include_rst_check.py create mode 100644 dox_style/dox_style/checks/main.py create mode 100644 dox_style/dox_style/checks/top_level_casing_check.py create mode 100644 dox_style/dox_style/checks/top_level_heading_check.py create mode 100644 dox_style/dox_style/checks/top_level_length_check.py create mode 100644 dox_style/dox_style/checks/top_level_modulename_check.py create mode 100644 dox_style/dox_style/checks/trailing_whitespace_check.py create mode 100644 dox_style/dox_style/checks/underline_length_check.py create mode 100644 dox_style/dox_style/checks/utils.py create mode 100644 dox_style/dox_style/config/_static/breadcrumbs.html create mode 100644 dox_style/dox_style/config/_static/colored_table.css create mode 100644 dox_style/dox_style/config/_static/colors.css create mode 100644 dox_style/dox_style/config/_static/footer.html create mode 100644 dox_style/dox_style/config/_static/header.css create mode 100644 dox_style/dox_style/config/_static/rtd_theme_overrides.css create mode 100644 dox_style/dox_style/config/label_check.py create mode 100644 dox_style/dox_style/config/main.py create mode 100644 dox_style/dox_style/version.py create mode 100644 dox_style/pyproject.toml create mode 100644 dox_style/tests/__init__.py create mode 100644 dox_style/tests/test_check.py create mode 100644 dox_style/tests/test_finding.py create mode 100644 dox_style/tests/test_heading_levels.py create mode 100644 dox_style/tests/test_include_rst.py create mode 100644 dox_style/tests/test_top_level.py create mode 100644 dox_style/tests/test_trailing_whitespace.py create mode 100644 dox_style/tests/test_underline_length_check.py create mode 100644 dox_style/tests/test_utils.py create mode 100644 dox_trace/.gitignore create mode 100644 dox_trace/LICENSE create mode 100644 dox_trace/MANIFEST.in create mode 100644 dox_trace/README.md create mode 100644 dox_trace/Rakefile.rb create mode 100644 dox_trace/documentation/.gitignore create mode 100644 dox_trace/documentation/Makefile create mode 100644 dox_trace/documentation/createMapping.rb create mode 100644 dox_trace/documentation/footer.rb create mode 100644 dox_trace/documentation/properties.yaml create mode 100644 dox_trace/documentation/requirements.txt create mode 100644 dox_trace/documentation/source/conf.py create mode 100644 dox_trace/documentation/source/index.rst create mode 100644 dox_trace/documentation/source/pages/_static/example.png create mode 100644 dox_trace/documentation/source/pages/_static/intro.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/module1/doc/index.rst create mode 100644 dox_trace/documentation/source/pages/_static/module1/include/source1.h create mode 100644 dox_trace/documentation/source/pages/_static/module1/include/source2.h create mode 100644 dox_trace/documentation/source/pages/_static/module2/doc/index.rst create mode 100644 dox_trace/documentation/source/pages/_static/swa/appendix/legend.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/dh_check.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/dh_create.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/dh_export.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/dh_parse.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/dh_setup.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/dynamic/workflow.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/overview/inout.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/overview/static.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/usecases/usecase_change.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/usecases/usecase_export.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/usecases/usecase_review.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/swa/usecases/usecase_view.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/trace.drawio.png create mode 100644 dox_trace/documentation/source/pages/_static/types.drawio.png create mode 100644 dox_trace/documentation/source/pages/appendix/changelog.rst create mode 100644 dox_trace/documentation/source/pages/appendix/config.rst create mode 100644 dox_trace/documentation/source/pages/architecture/dynamic.rst create mode 100644 dox_trace/documentation/source/pages/architecture/fmea.rst create mode 100644 dox_trace/documentation/source/pages/architecture/fmea/dynamic.csv create mode 100644 dox_trace/documentation/source/pages/architecture/fmea/general.csv create mode 100644 dox_trace/documentation/source/pages/architecture/inout.rst create mode 100644 dox_trace/documentation/source/pages/architecture/legend.rst create mode 100644 dox_trace/documentation/source/pages/architecture/static.rst create mode 100644 dox_trace/documentation/source/pages/architecture/usecases.rst create mode 100644 dox_trace/documentation/source/pages/development/bugTracking.rst create mode 100644 dox_trace/documentation/source/pages/development/ci.rst create mode 100644 dox_trace/documentation/source/pages/development/release.rst create mode 100644 dox_trace/documentation/source/pages/examples/contents/derivation.inc create mode 100644 dox_trace/documentation/source/pages/examples/contents/image.inc create mode 100644 dox_trace/documentation/source/pages/examples/contents/information.inc create mode 100644 dox_trace/documentation/source/pages/examples/contents/invalid.inc create mode 100644 dox_trace/documentation/source/pages/examples/contents/modules.inc create mode 100644 dox_trace/documentation/source/pages/examples/contents/unit2source.inc create mode 100644 dox_trace/documentation/source/pages/examples/report.rst create mode 100644 dox_trace/documentation/source/pages/examples/specifications.rst create mode 100644 dox_trace/documentation/source/pages/examples/undefined_refs.rst create mode 100644 dox_trace/documentation/source/pages/requirements/reqConfig.rst create mode 100644 dox_trace/documentation/source/pages/started/installation.rst create mode 100644 dox_trace/documentation/source/pages/started/integration.rst create mode 100644 dox_trace/documentation/source/pages/started/introduction.rst create mode 100644 dox_trace/documentation/source/pages/user/backward.rst create mode 100644 dox_trace/documentation/source/pages/user/calcedValues.rst create mode 100644 dox_trace/documentation/source/pages/user/config.rst create mode 100644 dox_trace/documentation/source/pages/user/customAttributes.rst create mode 100644 dox_trace/documentation/source/pages/user/customAttributesExample.inc create mode 100644 dox_trace/documentation/source/pages/user/directives.rst create mode 100644 dox_trace/documentation/source/pages/user/enclosed.rst create mode 100644 dox_trace/documentation/source/pages/user/explicitAttributes.rst create mode 100644 dox_trace/documentation/source/pages/user/export.rst create mode 100644 dox_trace/documentation/source/pages/user/newlines.rst create mode 100644 dox_trace/documentation/source/pages/user/parentValues.rst create mode 100644 dox_trace/documentation/source/pages/user/properties.rst create mode 100644 dox_trace/documentation/source/pages/user/rawhtml.rst create mode 100644 dox_trace/documentation/source/pages/user/traceability.rst create mode 100644 dox_trace/documentation/source/pages/user/unintended.rst create mode 100644 dox_trace/dox_trace/__init__.py create mode 100644 dox_trace/dox_trace/_static/dox_trace.css create mode 100644 dox_trace/dox_trace/_static/dox_trace.js create mode 100644 dox_trace/dox_trace/backward_refs.py create mode 100644 dox_trace/dox_trace/checks.py create mode 100644 dox_trace/dox_trace/config.py create mode 100644 dox_trace/dox_trace/coverage.py create mode 100644 dox_trace/dox_trace/dim_write.py create mode 100644 dox_trace/dox_trace/directives.py create mode 100644 dox_trace/dox_trace/enclosed.py create mode 100644 dox_trace/dox_trace/env.py create mode 100644 dox_trace/dox_trace/helper.py create mode 100644 dox_trace/dox_trace/main.py create mode 100644 dox_trace/dox_trace/properties.py create mode 100644 dox_trace/dox_trace/report.py create mode 100644 dox_trace/dox_trace/report_architecture.py create mode 100644 dox_trace/dox_trace/report_generic.py create mode 100644 dox_trace/dox_trace/report_input.py create mode 100644 dox_trace/dox_trace/report_module.py create mode 100644 dox_trace/dox_trace/report_source.py create mode 100644 dox_trace/dox_trace/report_table.py create mode 100644 dox_trace/dox_trace/roles.py create mode 100644 dox_trace/dox_trace/undefined_refs.py create mode 100644 dox_trace/dox_trace/version.py create mode 100644 dox_trace/dox_trace/yaml.py create mode 100644 dox_trace/pyproject.toml create mode 100644 dox_trace/req/config.dim create mode 100644 dox_trace/req/dox_trace.dim create mode 100644 dox_trace/req/properties.yaml create mode 100644 dox_trace/spec/asil_spec.rb create mode 100644 dox_trace/spec/cal_spec.rb create mode 100644 dox_trace/spec/category_spec.rb create mode 100644 dox_trace/spec/change_request_spec.rb create mode 100644 dox_trace/spec/checks_spec.rb create mode 100644 dox_trace/spec/comment_spec.rb create mode 100644 dox_trace/spec/config_spec.rb create mode 100644 dox_trace/spec/content_spec.rb create mode 100644 dox_trace/spec/custom_categories_spec.rb create mode 100644 dox_trace/spec/custom_default_spec.rb create mode 100644 dox_trace/spec/custom_directives_spec.rb create mode 100644 dox_trace/spec/custom_export_spec.rb create mode 100644 dox_trace/spec/custom_name_spec.rb create mode 100644 dox_trace/spec/custom_type_spec.rb create mode 100644 dox_trace/spec/derived_change_request_spec.rb create mode 100644 dox_trace/spec/derived_feature_spec.rb create mode 100644 dox_trace/spec/developer_spec.rb create mode 100644 dox_trace/spec/directives_spec.rb create mode 100644 dox_trace/spec/downstream_references_spec.rb create mode 100644 dox_trace/spec/enclosed_spec.rb create mode 100644 dox_trace/spec/export_spec.rb create mode 100644 dox_trace/spec/feature_spec.rb create mode 100644 dox_trace/spec/framework/helper.rb create mode 100644 dox_trace/spec/framework/testmain.rb create mode 100644 dox_trace/spec/general_spec.rb create mode 100644 dox_trace/spec/html_spec.rb create mode 100644 dox_trace/spec/ignore_in_export_spec.rb create mode 100644 dox_trace/spec/location_spec.rb create mode 100644 dox_trace/spec/miscellaneous_spec.rb create mode 100644 dox_trace/spec/parallel_spec.rb create mode 100644 dox_trace/spec/parent_asil_spec.rb create mode 100644 dox_trace/spec/parent_cal_spec.rb create mode 100644 dox_trace/spec/parent_security_spec.rb create mode 100644 dox_trace/spec/parent_tags_spec.rb create mode 100644 dox_trace/spec/properties_spec.rb create mode 100644 dox_trace/spec/refs_spec.rb create mode 100644 dox_trace/spec/reuse_spec.rb create mode 100644 dox_trace/spec/review_status_spec.rb create mode 100644 dox_trace/spec/security_spec.rb create mode 100644 dox_trace/spec/sources_spec.rb create mode 100644 dox_trace/spec/status_spec.rb create mode 100644 dox_trace/spec/tags_spec.rb create mode 100644 dox_trace/spec/test_input/asil/Makefile create mode 100644 dox_trace/spec/test_input/asil/conf.py create mode 100644 dox_trace/spec/test_input/asil/index.rst create mode 100644 dox_trace/spec/test_input/cal/Makefile create mode 100644 dox_trace/spec/test_input/cal/conf.py create mode 100644 dox_trace/spec/test_input/cal/index.rst create mode 100644 dox_trace/spec/test_input/category/Makefile create mode 100644 dox_trace/spec/test_input/category/conf.py create mode 100644 dox_trace/spec/test_input/category/index.rst create mode 100644 dox_trace/spec/test_input/category_interface/Makefile create mode 100644 dox_trace/spec/test_input/category_interface/conf.py create mode 100644 dox_trace/spec/test_input/category_interface/index.rst create mode 100644 dox_trace/spec/test_input/category_mod/Makefile create mode 100644 dox_trace/spec/test_input/category_mod/conf.py create mode 100644 dox_trace/spec/test_input/category_mod/index.rst create mode 100644 dox_trace/spec/test_input/category_spec/Makefile create mode 100644 dox_trace/spec/test_input/category_spec/conf.py create mode 100644 dox_trace/spec/test_input/category_spec/index.rst create mode 100644 dox_trace/spec/test_input/category_srs/Makefile create mode 100644 dox_trace/spec/test_input/category_srs/conf.py create mode 100644 dox_trace/spec/test_input/category_srs/index.rst create mode 100644 dox_trace/spec/test_input/category_unit/Makefile create mode 100644 dox_trace/spec/test_input/category_unit/conf.py create mode 100644 dox_trace/spec/test_input/category_unit/index.rst create mode 100644 dox_trace/spec/test_input/change_request/Makefile create mode 100644 dox_trace/spec/test_input/change_request/conf.py create mode 100644 dox_trace/spec/test_input/change_request/index.rst create mode 100644 dox_trace/spec/test_input/change_request_information/Makefile create mode 100644 dox_trace/spec/test_input/change_request_information/conf.py create mode 100644 dox_trace/spec/test_input/change_request_information/index.rst create mode 100644 dox_trace/spec/test_input/change_request_interface/Makefile create mode 100644 dox_trace/spec/test_input/change_request_interface/conf.py create mode 100644 dox_trace/spec/test_input/change_request_interface/index.rst create mode 100644 dox_trace/spec/test_input/change_request_mod/Makefile create mode 100644 dox_trace/spec/test_input/change_request_mod/conf.py create mode 100644 dox_trace/spec/test_input/change_request_mod/index.rst create mode 100644 dox_trace/spec/test_input/change_request_spec/Makefile create mode 100644 dox_trace/spec/test_input/change_request_spec/conf.py create mode 100644 dox_trace/spec/test_input/change_request_spec/index.rst create mode 100644 dox_trace/spec/test_input/change_request_srs/Makefile create mode 100644 dox_trace/spec/test_input/change_request_srs/conf.py create mode 100644 dox_trace/spec/test_input/change_request_srs/index.rst create mode 100644 dox_trace/spec/test_input/change_request_unit/Makefile create mode 100644 dox_trace/spec/test_input/change_request_unit/conf.py create mode 100644 dox_trace/spec/test_input/change_request_unit/index.rst create mode 100644 dox_trace/spec/test_input/check_cyclic_direct/Makefile create mode 100644 dox_trace/spec/test_input/check_cyclic_direct/conf.py create mode 100644 dox_trace/spec/test_input/check_cyclic_direct/index.rst create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect/Makefile create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect/conf.py create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect/index.rst create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect_levels/Makefile create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect_levels/conf.py create mode 100644 dox_trace/spec/test_input/check_cyclic_indirect_levels/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_case/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_case/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_case/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_ignored/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_ignored/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_ignored/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_interface/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_interface/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_interface/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_mod/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_mod/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_mod/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_spec/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_spec/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_spec/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_srs/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_srs/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_srs/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_comment_unit/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_comment_unit/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_comment_unit/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_ref/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_ref/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_ref/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_ref_suppress/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_ref_suppress/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_ref_suppress/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_sources_interface/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_sources_interface/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_sources_interface/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_sources_requirement/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_sources_requirement/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_sources_requirement/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_sources_spec/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_sources_spec/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_sources_spec/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_sources_srs/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_sources_srs/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_sources_srs/index.rst create mode 100644 dox_trace/spec/test_input/check_invalid_sources_unit/Makefile create mode 100644 dox_trace/spec/test_input/check_invalid_sources_unit/conf.py create mode 100644 dox_trace/spec/test_input/check_invalid_sources_unit/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_double_underscore/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_double_underscore/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_double_underscore/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_lower_case/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_lower_case/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_lower_case/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_three_underscores/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_three_underscores/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_three_underscores/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_too_short/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_too_short/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_too_short/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_too_short_deprecated/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_too_short_deprecated/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_too_short_deprecated/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_valid/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_valid/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_valid/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_valid_tolerant/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_valid_tolerant/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_valid_tolerant/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_interface/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_interface/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_interface/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_mod/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_mod/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_mod/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_srs/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_srs/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_srs/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/index.rst create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_unit/Makefile create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_unit/conf.py create mode 100644 dox_trace/spec/test_input/check_naming_wrong_prefix_unit/index.rst create mode 100644 dox_trace/spec/test_input/check_newline_id/Makefile create mode 100644 dox_trace/spec/test_input/check_newline_id/conf.py create mode 100644 dox_trace/spec/test_input/check_newline_id/index.rst create mode 100644 dox_trace/spec/test_input/check_outdated_python/Makefile create mode 100644 dox_trace/spec/test_input/check_outdated_python/conf.py create mode 100644 dox_trace/spec/test_input/check_outdated_python/index.rst create mode 100644 dox_trace/spec/test_input/check_outdated_sphinx/Makefile create mode 100644 dox_trace/spec/test_input/check_outdated_sphinx/conf.py create mode 100644 dox_trace/spec/test_input/check_outdated_sphinx/index.rst create mode 100644 dox_trace/spec/test_input/check_unique_id/Makefile create mode 100644 dox_trace/spec/test_input/check_unique_id/conf.py create mode 100644 dox_trace/spec/test_input/check_unique_id/index.rst create mode 100644 dox_trace/spec/test_input/check_unique_id/subpage.rst create mode 100644 dox_trace/spec/test_input/comment/Makefile create mode 100644 dox_trace/spec/test_input/comment/conf.py create mode 100644 dox_trace/spec/test_input/comment/index.rst create mode 100644 dox_trace/spec/test_input/comment_interface/Makefile create mode 100644 dox_trace/spec/test_input/comment_interface/conf.py create mode 100644 dox_trace/spec/test_input/comment_interface/index.rst create mode 100644 dox_trace/spec/test_input/comment_mod/Makefile create mode 100644 dox_trace/spec/test_input/comment_mod/conf.py create mode 100644 dox_trace/spec/test_input/comment_mod/index.rst create mode 100644 dox_trace/spec/test_input/comment_spec/Makefile create mode 100644 dox_trace/spec/test_input/comment_spec/conf.py create mode 100644 dox_trace/spec/test_input/comment_spec/index.rst create mode 100644 dox_trace/spec/test_input/comment_srs/Makefile create mode 100644 dox_trace/spec/test_input/comment_srs/conf.py create mode 100644 dox_trace/spec/test_input/comment_srs/index.rst create mode 100644 dox_trace/spec/test_input/comment_unit/Makefile create mode 100644 dox_trace/spec/test_input/comment_unit/conf.py create mode 100644 dox_trace/spec/test_input/comment_unit/index.rst create mode 100644 dox_trace/spec/test_input/config.dim create mode 100644 dox_trace/spec/test_input/config/Makefile create mode 100644 dox_trace/spec/test_input/config/conf.py create mode 100644 dox_trace/spec/test_input/config/filled.rst create mode 100644 dox_trace/spec/test_input/config/index.rst create mode 100644 dox_trace/spec/test_input/config/special.rst create mode 100644 dox_trace/spec/test_input/content/Makefile create mode 100644 dox_trace/spec/test_input/content/conf.py create mode 100644 dox_trace/spec/test_input/content/index.rst create mode 100644 dox_trace/spec/test_input/custom_categories/Makefile create mode 100644 dox_trace/spec/test_input/custom_categories/conf.py create mode 100644 dox_trace/spec/test_input/custom_categories/index.rst create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_empty/Makefile create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_empty/conf.py create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_empty/index.rst create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_missing/Makefile create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_missing/conf.py create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_missing/index.rst create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_value/Makefile create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_value/conf.py create mode 100644 dox_trace/spec/test_input/custom_categories_invalid_value/index.rst create mode 100644 dox_trace/spec/test_input/custom_default/Makefile create mode 100644 dox_trace/spec/test_input/custom_default/conf.py create mode 100644 dox_trace/spec/test_input/custom_default/index.rst create mode 100644 dox_trace/spec/test_input/custom_default_invalid_nontext/Makefile create mode 100644 dox_trace/spec/test_input/custom_default_invalid_nontext/conf.py create mode 100644 dox_trace/spec/test_input/custom_default_invalid_nontext/index.rst create mode 100644 dox_trace/spec/test_input/custom_default_invalid_text/Makefile create mode 100644 dox_trace/spec/test_input/custom_default_invalid_text/conf.py create mode 100644 dox_trace/spec/test_input/custom_default_invalid_text/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_empty/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_empty/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_empty/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_missing/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_missing/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_missing/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_spec/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_spec/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_spec/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_value/Makefile create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_value/conf.py create mode 100644 dox_trace/spec/test_input/custom_directives_invalid_value/index.rst create mode 100644 dox_trace/spec/test_input/custom_export/Makefile create mode 100644 dox_trace/spec/test_input/custom_export/conf.py create mode 100644 dox_trace/spec/test_input/custom_export/index.rst create mode 100644 dox_trace/spec/test_input/custom_export_invalid_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_export_invalid_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_export_invalid_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_export_invalid_value/Makefile create mode 100644 dox_trace/spec/test_input/custom_export_invalid_value/conf.py create mode 100644 dox_trace/spec/test_input/custom_export_invalid_value/index.rst create mode 100644 dox_trace/spec/test_input/custom_name/Makefile create mode 100644 dox_trace/spec/test_input/custom_name/conf.py create mode 100644 dox_trace/spec/test_input/custom_name/index.rst create mode 100644 dox_trace/spec/test_input/custom_name_invalid_exists/Makefile create mode 100644 dox_trace/spec/test_input/custom_name_invalid_exists/conf.py create mode 100644 dox_trace/spec/test_input/custom_name_invalid_exists/index.rst create mode 100644 dox_trace/spec/test_input/custom_name_invalid_text/Makefile create mode 100644 dox_trace/spec/test_input/custom_name_invalid_text/conf.py create mode 100644 dox_trace/spec/test_input/custom_name_invalid_text/index.rst create mode 100644 dox_trace/spec/test_input/custom_name_invalid_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_name_invalid_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_name_invalid_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_name_invalid_value/Makefile create mode 100644 dox_trace/spec/test_input/custom_name_invalid_value/conf.py create mode 100644 dox_trace/spec/test_input/custom_name_invalid_value/index.rst create mode 100644 dox_trace/spec/test_input/custom_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_type_invalid_missing/Makefile create mode 100644 dox_trace/spec/test_input/custom_type_invalid_missing/conf.py create mode 100644 dox_trace/spec/test_input/custom_type_invalid_missing/index.rst create mode 100644 dox_trace/spec/test_input/custom_type_invalid_type/Makefile create mode 100644 dox_trace/spec/test_input/custom_type_invalid_type/conf.py create mode 100644 dox_trace/spec/test_input/custom_type_invalid_type/index.rst create mode 100644 dox_trace/spec/test_input/custom_type_invalid_value/Makefile create mode 100644 dox_trace/spec/test_input/custom_type_invalid_value/conf.py create mode 100644 dox_trace/spec/test_input/custom_type_invalid_value/index.rst create mode 100644 dox_trace/spec/test_input/derived_change_request/Makefile create mode 100644 dox_trace/spec/test_input/derived_change_request/conf.py create mode 100644 dox_trace/spec/test_input/derived_change_request/index.rst create mode 100644 dox_trace/spec/test_input/derived_feature/Makefile create mode 100644 dox_trace/spec/test_input/derived_feature/conf.py create mode 100644 dox_trace/spec/test_input/derived_feature/index.rst create mode 100644 dox_trace/spec/test_input/developer/Makefile create mode 100644 dox_trace/spec/test_input/developer/conf.py create mode 100644 dox_trace/spec/test_input/developer/index.rst create mode 100644 dox_trace/spec/test_input/developer_information/Makefile create mode 100644 dox_trace/spec/test_input/developer_information/conf.py create mode 100644 dox_trace/spec/test_input/developer_information/index.rst create mode 100644 dox_trace/spec/test_input/directives_no_empty_line/Makefile create mode 100644 dox_trace/spec/test_input/directives_no_empty_line/conf.py create mode 100644 dox_trace/spec/test_input/directives_no_empty_line/index.rst create mode 100644 dox_trace/spec/test_input/directives_no_id/Makefile create mode 100644 dox_trace/spec/test_input/directives_no_id/conf.py create mode 100644 dox_trace/spec/test_input/directives_no_id/index.rst create mode 100644 dox_trace/spec/test_input/directives_valid/Makefile create mode 100644 dox_trace/spec/test_input/directives_valid/conf.py create mode 100644 dox_trace/spec/test_input/directives_valid/index.rst create mode 100644 dox_trace/spec/test_input/enclosed/Makefile create mode 100644 dox_trace/spec/test_input/enclosed/a.txt create mode 100644 dox_trace/spec/test_input/enclosed/b/b.txt create mode 100644 dox_trace/spec/test_input/enclosed/c.txt create mode 100644 dox_trace/spec/test_input/enclosed/conf.py create mode 100644 dox_trace/spec/test_input/enclosed/index.rst create mode 100644 dox_trace/spec/test_input/enclosed_invalid/Makefile create mode 100644 dox_trace/spec/test_input/enclosed_invalid/conf.py create mode 100644 dox_trace/spec/test_input/enclosed_invalid/index.rst create mode 100644 dox_trace/spec/test_input/export/Makefile create mode 100644 dox_trace/spec/test_input/export/conf.py create mode 100644 dox_trace/spec/test_input/export/index.rst create mode 100644 dox_trace/spec/test_input/export/subfolder/a.rst create mode 100644 dox_trace/spec/test_input/export/subfolder/b.rst create mode 100644 dox_trace/spec/test_input/export/subfolder/b/c.rst create mode 100644 dox_trace/spec/test_input/export/subfolder/b/d.rst create mode 100644 dox_trace/spec/test_input/export_invalid_config/Makefile create mode 100644 dox_trace/spec/test_input/export_invalid_config/conf.py create mode 100644 dox_trace/spec/test_input/export_invalid_config/index.rst create mode 100644 dox_trace/spec/test_input/export_no_config/Makefile create mode 100644 dox_trace/spec/test_input/export_no_config/conf.py create mode 100644 dox_trace/spec/test_input/export_no_config/index.rst create mode 100644 dox_trace/spec/test_input/export_no_srs/Makefile create mode 100644 dox_trace/spec/test_input/export_no_srs/conf.py create mode 100644 dox_trace/spec/test_input/export_no_srs/index.rst create mode 100644 dox_trace/spec/test_input/feature/Makefile create mode 100644 dox_trace/spec/test_input/feature/conf.py create mode 100644 dox_trace/spec/test_input/feature/index.rst create mode 100644 dox_trace/spec/test_input/feature_information/Makefile create mode 100644 dox_trace/spec/test_input/feature_information/conf.py create mode 100644 dox_trace/spec/test_input/feature_information/index.rst create mode 100644 dox_trace/spec/test_input/feature_interface/Makefile create mode 100644 dox_trace/spec/test_input/feature_interface/conf.py create mode 100644 dox_trace/spec/test_input/feature_interface/index.rst create mode 100644 dox_trace/spec/test_input/feature_mod/Makefile create mode 100644 dox_trace/spec/test_input/feature_mod/conf.py create mode 100644 dox_trace/spec/test_input/feature_mod/index.rst create mode 100644 dox_trace/spec/test_input/feature_spec/Makefile create mode 100644 dox_trace/spec/test_input/feature_spec/conf.py create mode 100644 dox_trace/spec/test_input/feature_spec/index.rst create mode 100644 dox_trace/spec/test_input/feature_srs/Makefile create mode 100644 dox_trace/spec/test_input/feature_srs/conf.py create mode 100644 dox_trace/spec/test_input/feature_srs/index.rst create mode 100644 dox_trace/spec/test_input/feature_unit/Makefile create mode 100644 dox_trace/spec/test_input/feature_unit/conf.py create mode 100644 dox_trace/spec/test_input/feature_unit/index.rst create mode 100644 dox_trace/spec/test_input/general/Makefile create mode 100644 dox_trace/spec/test_input/general/conf.py create mode 100644 dox_trace/spec/test_input/general/index.rst create mode 100644 dox_trace/spec/test_input/html/Makefile create mode 100644 dox_trace/spec/test_input/html/conf.py create mode 100644 dox_trace/spec/test_input/html/index.rst create mode 100644 dox_trace/spec/test_input/html/subpage.rst create mode 100644 dox_trace/spec/test_input/html/subpage2.rst create mode 100644 dox_trace/spec/test_input/ignore_in_export/Makefile create mode 100644 dox_trace/spec/test_input/ignore_in_export/conf.py create mode 100644 dox_trace/spec/test_input/ignore_in_export/index.rst create mode 100644 dox_trace/spec/test_input/location/Makefile create mode 100644 dox_trace/spec/test_input/location/conf.py create mode 100644 dox_trace/spec/test_input/location/index.rst create mode 100644 dox_trace/spec/test_input/location/modules/driver/doc/index.rst create mode 100644 dox_trace/spec/test_input/location/subfolder/index.rst create mode 100644 dox_trace/spec/test_input/location_information/Makefile create mode 100644 dox_trace/spec/test_input/location_information/conf.py create mode 100644 dox_trace/spec/test_input/location_information/index.rst create mode 100644 dox_trace/spec/test_input/location_interface/Makefile create mode 100644 dox_trace/spec/test_input/location_interface/conf.py create mode 100644 dox_trace/spec/test_input/location_interface/index.rst create mode 100644 dox_trace/spec/test_input/location_requirement/Makefile create mode 100644 dox_trace/spec/test_input/location_requirement/conf.py create mode 100644 dox_trace/spec/test_input/location_requirement/index.rst create mode 100644 dox_trace/spec/test_input/location_spec/Makefile create mode 100644 dox_trace/spec/test_input/location_spec/conf.py create mode 100644 dox_trace/spec/test_input/location_spec/index.rst create mode 100644 dox_trace/spec/test_input/location_srs/Makefile create mode 100644 dox_trace/spec/test_input/location_srs/conf.py create mode 100644 dox_trace/spec/test_input/location_srs/index.rst create mode 100644 dox_trace/spec/test_input/location_unit/Makefile create mode 100644 dox_trace/spec/test_input/location_unit/conf.py create mode 100644 dox_trace/spec/test_input/location_unit/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous_interface/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous_interface/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous_interface/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous_mod/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous_mod/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous_mod/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous_spec/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous_spec/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous_spec/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous_srs/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous_srs/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous_srs/index.rst create mode 100644 dox_trace/spec/test_input/miscellaneous_unit/Makefile create mode 100644 dox_trace/spec/test_input/miscellaneous_unit/conf.py create mode 100644 dox_trace/spec/test_input/miscellaneous_unit/index.rst create mode 100644 dox_trace/spec/test_input/parallel/Makefile create mode 100644 dox_trace/spec/test_input/parallel/conf.py create mode 100644 dox_trace/spec/test_input/parallel/index.rst create mode 100644 dox_trace/spec/test_input/parallel/subpage1.rst create mode 100644 dox_trace/spec/test_input/parallel/subpage2.rst create mode 100644 dox_trace/spec/test_input/parallel/subpage3.rst create mode 100644 dox_trace/spec/test_input/parallel/subpage4.rst create mode 100644 dox_trace/spec/test_input/parallel/subpage5.rst create mode 100644 dox_trace/spec/test_input/properties/Makefile create mode 100644 dox_trace/spec/test_input/properties/conf.py create mode 100644 dox_trace/spec/test_input/properties/index.rst create mode 100644 dox_trace/spec/test_input/properties/properties.yaml create mode 100644 dox_trace/spec/test_input/properties_no_file/Makefile create mode 100644 dox_trace/spec/test_input/properties_no_file/conf.py create mode 100644 dox_trace/spec/test_input/properties_no_file/index.rst create mode 100644 dox_trace/spec/test_input/properties_no_name/Makefile create mode 100644 dox_trace/spec/test_input/properties_no_name/conf.py create mode 100644 dox_trace/spec/test_input/properties_no_name/index.rst create mode 100644 dox_trace/spec/test_input/properties_no_name/properties.yaml create mode 100644 dox_trace/spec/test_input/properties_no_value/Makefile create mode 100644 dox_trace/spec/test_input/properties_no_value/conf.py create mode 100644 dox_trace/spec/test_input/properties_no_value/index.rst create mode 100644 dox_trace/spec/test_input/properties_no_value/properties.yaml create mode 100644 dox_trace/spec/test_input/properties_not_available/Makefile create mode 100644 dox_trace/spec/test_input/properties_not_available/conf.py create mode 100644 dox_trace/spec/test_input/properties_not_available/index.rst create mode 100644 dox_trace/spec/test_input/properties_wrong_file/Makefile create mode 100644 dox_trace/spec/test_input/properties_wrong_file/conf.py create mode 100644 dox_trace/spec/test_input/properties_wrong_file/index.rst create mode 100644 dox_trace/spec/test_input/properties_wrong_file/properties.yaml create mode 100644 dox_trace/spec/test_input/properties_wrong_syntax/Makefile create mode 100644 dox_trace/spec/test_input/properties_wrong_syntax/conf.py create mode 100644 dox_trace/spec/test_input/properties_wrong_syntax/index.rst create mode 100644 dox_trace/spec/test_input/properties_wrong_syntax/properties.yaml create mode 100644 dox_trace/spec/test_input/refs/Makefile create mode 100644 dox_trace/spec/test_input/refs/conf.py create mode 100644 dox_trace/spec/test_input/refs/index.rst create mode 100644 dox_trace/spec/test_input/refs/undefined_refs.rst create mode 100644 dox_trace/spec/test_input/refs_mod/Makefile create mode 100644 dox_trace/spec/test_input/refs_mod/conf.py create mode 100644 dox_trace/spec/test_input/refs_mod/index.rst create mode 100644 dox_trace/spec/test_input/refs_undefined_nowarn/Makefile create mode 100644 dox_trace/spec/test_input/refs_undefined_nowarn/conf.py create mode 100644 dox_trace/spec/test_input/refs_undefined_nowarn/index.rst create mode 100644 dox_trace/spec/test_input/refs_undefined_nowarn/undefined_refs.rst create mode 100644 dox_trace/spec/test_input/refs_undefined_warn/Makefile create mode 100644 dox_trace/spec/test_input/refs_undefined_warn/conf.py create mode 100644 dox_trace/spec/test_input/refs_undefined_warn/index.rst create mode 100644 dox_trace/spec/test_input/reuse/Makefile create mode 100644 dox_trace/spec/test_input/reuse/conf.py create mode 100644 dox_trace/spec/test_input/reuse/index.rst create mode 100644 dox_trace/spec/test_input/reuse_information/Makefile create mode 100644 dox_trace/spec/test_input/reuse_information/conf.py create mode 100644 dox_trace/spec/test_input/reuse_information/index.rst create mode 100644 dox_trace/spec/test_input/reuse_interface/Makefile create mode 100644 dox_trace/spec/test_input/reuse_interface/conf.py create mode 100644 dox_trace/spec/test_input/reuse_interface/index.rst create mode 100644 dox_trace/spec/test_input/reuse_requirement/Makefile create mode 100644 dox_trace/spec/test_input/reuse_requirement/conf.py create mode 100644 dox_trace/spec/test_input/reuse_requirement/index.rst create mode 100644 dox_trace/spec/test_input/reuse_spec/Makefile create mode 100644 dox_trace/spec/test_input/reuse_spec/conf.py create mode 100644 dox_trace/spec/test_input/reuse_spec/index.rst create mode 100644 dox_trace/spec/test_input/reuse_srs/Makefile create mode 100644 dox_trace/spec/test_input/reuse_srs/conf.py create mode 100644 dox_trace/spec/test_input/reuse_srs/index.rst create mode 100644 dox_trace/spec/test_input/reuse_unit/Makefile create mode 100644 dox_trace/spec/test_input/reuse_unit/conf.py create mode 100644 dox_trace/spec/test_input/reuse_unit/index.rst create mode 100644 dox_trace/spec/test_input/review_status/Makefile create mode 100644 dox_trace/spec/test_input/review_status/conf.py create mode 100644 dox_trace/spec/test_input/review_status/index.rst create mode 100644 dox_trace/spec/test_input/security/Makefile create mode 100644 dox_trace/spec/test_input/security/attributes.dim create mode 100644 dox_trace/spec/test_input/security/conf.py create mode 100644 dox_trace/spec/test_input/security/index.rst create mode 100644 dox_trace/spec/test_input/sources/Makefile create mode 100644 dox_trace/spec/test_input/sources/conf.py create mode 100644 dox_trace/spec/test_input/sources/doc/subpage.rst create mode 100644 dox_trace/spec/test_input/sources/index.rst create mode 100644 dox_trace/spec/test_input/sources/src/test.abc create mode 100644 dox_trace/spec/test_input/sources_information/Makefile create mode 100644 dox_trace/spec/test_input/sources_information/conf.py create mode 100644 dox_trace/spec/test_input/sources_information/index.rst create mode 100644 dox_trace/spec/test_input/sources_mod/Makefile create mode 100644 dox_trace/spec/test_input/sources_mod/conf.py create mode 100644 dox_trace/spec/test_input/sources_mod/index.rst create mode 100644 dox_trace/spec/test_input/status/Makefile create mode 100644 dox_trace/spec/test_input/status/conf.py create mode 100644 dox_trace/spec/test_input/status/index.rst create mode 100644 dox_trace/spec/test_input/tags/Makefile create mode 100644 dox_trace/spec/test_input/tags/conf.py create mode 100644 dox_trace/spec/test_input/tags/index.rst create mode 100644 dox_trace/spec/test_input/tags/modules/driver/doc/index.rst create mode 100644 dox_trace/spec/test_input/tags_mod/Makefile create mode 100644 dox_trace/spec/test_input/tags_mod/conf.py create mode 100644 dox_trace/spec/test_input/tags_mod/index.rst create mode 100644 dox_trace/spec/test_input/test_setups/Makefile create mode 100644 dox_trace/spec/test_input/test_setups/conf.py create mode 100644 dox_trace/spec/test_input/test_setups/index.rst create mode 100644 dox_trace/spec/test_input/test_setups_information/Makefile create mode 100644 dox_trace/spec/test_input/test_setups_information/conf.py create mode 100644 dox_trace/spec/test_input/test_setups_information/index.rst create mode 100644 dox_trace/spec/test_input/test_setups_mod/Makefile create mode 100644 dox_trace/spec/test_input/test_setups_mod/conf.py create mode 100644 dox_trace/spec/test_input/test_setups_mod/index.rst create mode 100644 dox_trace/spec/test_input/tester/Makefile create mode 100644 dox_trace/spec/test_input/tester/conf.py create mode 100644 dox_trace/spec/test_input/tester/index.rst create mode 100644 dox_trace/spec/test_input/tester_information/Makefile create mode 100644 dox_trace/spec/test_input/tester_information/conf.py create mode 100644 dox_trace/spec/test_input/tester_information/index.rst create mode 100644 dox_trace/spec/test_input/tester_mod/Makefile create mode 100644 dox_trace/spec/test_input/tester_mod/conf.py create mode 100644 dox_trace/spec/test_input/tester_mod/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_cal_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_list_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_list_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_list_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_list_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/abc/doc/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_list_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/abc/doc/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_ref_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_safety_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_security_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_security_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_security_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_security_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_security_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_status_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_status_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_status_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_status_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_status_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_type_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_type_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_type_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_type_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_architecture_type_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_general_developerregex/Makefile create mode 100644 dox_trace/spec/test_input/tr_general_developerregex/conf.py create mode 100644 dox_trace/spec/test_input/tr_general_developerregex/index.rst create mode 100644 dox_trace/spec/test_input/tr_general_developerregex/report.rst create mode 100644 dox_trace/spec/test_input/tr_general_ignore/Makefile create mode 100644 dox_trace/spec/test_input/tr_general_ignore/conf.py create mode 100644 dox_trace/spec/test_input/tr_general_ignore/index.rst create mode 100644 dox_trace/spec/test_input/tr_general_ignore/report.rst create mode 100644 dox_trace/spec/test_input/tr_general_invalidcategory/Makefile create mode 100644 dox_trace/spec/test_input/tr_general_invalidcategory/conf.py create mode 100644 dox_trace/spec/test_input/tr_general_invalidcategory/index.rst create mode 100644 dox_trace/spec/test_input/tr_general_invalidcategory/report.rst create mode 100644 dox_trace/spec/test_input/tr_general_missingdeveloper/Makefile create mode 100644 dox_trace/spec/test_input/tr_general_missingdeveloper/conf.py create mode 100644 dox_trace/spec/test_input/tr_general_missingdeveloper/index.rst create mode 100644 dox_trace/spec/test_input/tr_general_missingdeveloper/report.rst create mode 100644 dox_trace/spec/test_input/tr_general_notitle/Makefile create mode 100644 dox_trace/spec/test_input/tr_general_notitle/conf.py create mode 100644 dox_trace/spec/test_input/tr_general_notitle/index.rst create mode 100644 dox_trace/spec/test_input/tr_general_notitle/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_cal_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_cal_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_cal_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_cal_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_cal_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_dev_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_dev_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_dev_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_dev_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_dev_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_dev_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_dev_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_dev_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_dev_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_list_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_list_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_list_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_list_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_list_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_list_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_list_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_ref_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_ref_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_ref_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_ref_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_ref_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_reviewstatus_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_safety_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_safety_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_safety_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_safety_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_safety_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_security_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_security_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_security_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_security_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_security_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_security_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_input_security_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_security_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_status_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_status_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_status_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_status_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_input_status_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_input_status_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_input_status_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_cal_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_cal_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_cal_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_cal_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_cal_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_list_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_list_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_list_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_list_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_table/AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt create mode 100644 dox_trace/spec/test_input/tr_module_list_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_list_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_list_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_list_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_ref_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_ref_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_ref_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_ref_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_ref_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_safety_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_safety_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_safety_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_safety_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_safety_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_security_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_security_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_security_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_security_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_security_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_security_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_module_security_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_security_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_status_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_status_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_status_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_status_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_status_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_status_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_status_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_type_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_type_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_type_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_type_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_type_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_type_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/Makefile create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/conf.py create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/index.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/report.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/second.rst create mode 100644 dox_trace/spec/test_input/tr_module_type_table_deprecated/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_cal_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_cal_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_cal_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_cal_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_cal_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_list_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_list_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_list_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_list_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_list_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_list_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_list_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_ref_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_ref_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_ref_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_ref_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_ref_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_safety_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_safety_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_safety_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_safety_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_safety_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_security_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_security_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_security_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_security_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_security_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_security_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_table/properties.yaml create mode 100644 dox_trace/spec/test_input/tr_software_security_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_security_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_empty/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_status_empty/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_status_empty/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_empty/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_status_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_status_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_none/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_table/Makefile create mode 100644 dox_trace/spec/test_input/tr_software_status_table/conf.py create mode 100644 dox_trace/spec/test_input/tr_software_status_table/index.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_table/report.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_table/second.rst create mode 100644 dox_trace/spec/test_input/tr_software_status_table/third.rst create mode 100644 dox_trace/spec/test_input/tr_source_list/Makefile create mode 100644 dox_trace/spec/test_input/tr_source_list/conf.py create mode 100644 dox_trace/spec/test_input/tr_source_list/index.rst create mode 100644 dox_trace/spec/test_input/tr_source_list/report.rst create mode 100644 dox_trace/spec/test_input/tr_source_list/second.rst create mode 100644 dox_trace/spec/test_input/tr_source_list/third.rst create mode 100644 dox_trace/spec/test_input/tr_source_none/Makefile create mode 100644 dox_trace/spec/test_input/tr_source_none/conf.py create mode 100644 dox_trace/spec/test_input/tr_source_none/index.rst create mode 100644 dox_trace/spec/test_input/tr_source_none/report.rst create mode 100644 dox_trace/spec/test_input/undefined_refs_empty/Makefile create mode 100644 dox_trace/spec/test_input/undefined_refs_empty/conf.py create mode 100644 dox_trace/spec/test_input/undefined_refs_empty/index.rst create mode 100644 dox_trace/spec/test_input/undefined_refs_empty/undefined_refs.rst create mode 100644 dox_trace/spec/test_input/undefined_refs_list/Makefile create mode 100644 dox_trace/spec/test_input/undefined_refs_list/conf.py create mode 100644 dox_trace/spec/test_input/undefined_refs_list/index.rst create mode 100644 dox_trace/spec/test_input/undefined_refs_list/undefined_refs.rst create mode 100644 dox_trace/spec/test_input/upstream_asil/Makefile create mode 100644 dox_trace/spec/test_input/upstream_asil/conf.py create mode 100644 dox_trace/spec/test_input/upstream_asil/index.rst create mode 100644 dox_trace/spec/test_input/upstream_cal/Makefile create mode 100644 dox_trace/spec/test_input/upstream_cal/conf.py create mode 100644 dox_trace/spec/test_input/upstream_cal/index.rst create mode 100644 dox_trace/spec/test_input/upstream_references/Makefile create mode 100644 dox_trace/spec/test_input/upstream_references/conf.py create mode 100644 dox_trace/spec/test_input/upstream_references/index.rst create mode 100644 dox_trace/spec/test_input/upstream_security/Makefile create mode 100644 dox_trace/spec/test_input/upstream_security/conf.py create mode 100644 dox_trace/spec/test_input/upstream_security/index.rst create mode 100644 dox_trace/spec/test_input/upstream_tags/Makefile create mode 100644 dox_trace/spec/test_input/upstream_tags/conf.py create mode 100644 dox_trace/spec/test_input/upstream_tags/index.rst create mode 100644 dox_trace/spec/test_input/usage/Makefile create mode 100644 dox_trace/spec/test_input/usage/conf.py create mode 100644 dox_trace/spec/test_input/usage/index.rst create mode 100644 dox_trace/spec/test_input/usage_information/Makefile create mode 100644 dox_trace/spec/test_input/usage_information/conf.py create mode 100644 dox_trace/spec/test_input/usage_information/index.rst create mode 100644 dox_trace/spec/test_input/usage_interface/Makefile create mode 100644 dox_trace/spec/test_input/usage_interface/conf.py create mode 100644 dox_trace/spec/test_input/usage_interface/index.rst create mode 100644 dox_trace/spec/test_input/usage_requirement/Makefile create mode 100644 dox_trace/spec/test_input/usage_requirement/conf.py create mode 100644 dox_trace/spec/test_input/usage_requirement/index.rst create mode 100644 dox_trace/spec/test_input/usage_spec/Makefile create mode 100644 dox_trace/spec/test_input/usage_spec/conf.py create mode 100644 dox_trace/spec/test_input/usage_spec/index.rst create mode 100644 dox_trace/spec/test_input/usage_srs/Makefile create mode 100644 dox_trace/spec/test_input/usage_srs/conf.py create mode 100644 dox_trace/spec/test_input/usage_srs/index.rst create mode 100644 dox_trace/spec/test_input/usage_unit/Makefile create mode 100644 dox_trace/spec/test_input/usage_unit/conf.py create mode 100644 dox_trace/spec/test_input/usage_unit/index.rst create mode 100644 dox_trace/spec/test_input/verification_criteria/Makefile create mode 100644 dox_trace/spec/test_input/verification_criteria/conf.py create mode 100644 dox_trace/spec/test_input/verification_criteria/index.rst create mode 100644 dox_trace/spec/test_input/verification_criteria_information/Makefile create mode 100644 dox_trace/spec/test_input/verification_criteria_information/conf.py create mode 100644 dox_trace/spec/test_input/verification_criteria_information/index.rst create mode 100644 dox_trace/spec/test_input/verification_criteria_mod/Makefile create mode 100644 dox_trace/spec/test_input/verification_criteria_mod/conf.py create mode 100644 dox_trace/spec/test_input/verification_criteria_mod/index.rst create mode 100644 dox_trace/spec/test_input/verification_methods/Makefile create mode 100644 dox_trace/spec/test_input/verification_methods/conf.py create mode 100644 dox_trace/spec/test_input/verification_methods/index.rst create mode 100644 dox_trace/spec/test_input/verification_methods_information/Makefile create mode 100644 dox_trace/spec/test_input/verification_methods_information/conf.py create mode 100644 dox_trace/spec/test_input/verification_methods_information/index.rst create mode 100644 dox_trace/spec/test_input/verification_methods_mod/Makefile create mode 100644 dox_trace/spec/test_input/verification_methods_mod/conf.py create mode 100644 dox_trace/spec/test_input/verification_methods_mod/index.rst create mode 100644 dox_trace/spec/test_setups_spec.rb create mode 100644 dox_trace/spec/tester_spec.rb create mode 100644 dox_trace/spec/tr_architecture_spec.rb create mode 100644 dox_trace/spec/tr_general_spec.rb create mode 100644 dox_trace/spec/tr_input_spec.rb create mode 100644 dox_trace/spec/tr_module_spec.rb create mode 100644 dox_trace/spec/tr_software_spec.rb create mode 100644 dox_trace/spec/tr_source_spec.rb create mode 100644 dox_trace/spec/undefined_refs_spec.rb create mode 100644 dox_trace/spec/upstream_references_spec.rb create mode 100644 dox_trace/spec/usage_spec.rb create mode 100644 dox_trace/spec/verification_criteria_spec.rb create mode 100644 dox_trace/spec/verification_methods_spec.rb create mode 100644 dox_trace/spec/zzz_dummy_spec.rb create mode 100644 dox_util/LICENSE create mode 100644 dox_util/MANIFEST.in create mode 100644 dox_util/README.md create mode 100644 dox_util/documentation/.gitignore create mode 100644 dox_util/documentation/Makefile create mode 100644 dox_util/documentation/footer.rb create mode 100644 dox_util/documentation/requirements.txt create mode 100644 dox_util/documentation/source/conf.py create mode 100644 dox_util/documentation/source/index.rst create mode 100644 dox_util/documentation/source/pages/appendix/changelog.rst create mode 100644 dox_util/documentation/source/pages/user/extlinks.rst create mode 100644 dox_util/documentation/source/pages/user/linkcheck.rst create mode 100644 dox_util/documentation/source/pages/user/rule.rst create mode 100644 dox_util/documentation/source/pages/user/source.rst create mode 100644 dox_util/documentation/source/pages/user/source/include/MemoryManager.h create mode 100644 dox_util/documentation/source/pages/user/toctree.rst create mode 100644 dox_util/documentation/source/pages/user/toctree/example1.rst create mode 100644 dox_util/documentation/source/pages/user/toctree/example2.rst create mode 100644 dox_util/documentation/source/pages/user/todo.rst create mode 100644 dox_util/documentation/source/pages/user/weak.rst create mode 100644 dox_util/dox_util/__init__.py create mode 100644 dox_util/dox_util/_static/dox_util_colors.css create mode 100644 dox_util/dox_util/extlinks.py create mode 100644 dox_util/dox_util/linkcheck.py create mode 100644 dox_util/dox_util/rule.py create mode 100644 dox_util/dox_util/source.py create mode 100644 dox_util/dox_util/toctree.py create mode 100644 dox_util/dox_util/todo.py create mode 100644 dox_util/dox_util/version.py create mode 100644 dox_util/dox_util/weak.py create mode 100644 dox_util/pyproject.toml create mode 100644 pyproject.toml diff --git a/.github/workflows/dim_ut.yaml b/.github/workflows/dim_ut.yaml new file mode 100644 index 0000000..6293aa9 --- /dev/null +++ b/.github/workflows/dim_ut.yaml @@ -0,0 +1,37 @@ +name: Dim Unit Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu] + ruby: [2.7, 3.0, 3.3] + include: + - os: macos + ruby: 3.3 + - os: windows + ruby: 3.3 + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ matrix.ruby }} + - name: Install gems + run: | + gem install rspec -v 3.10.0 --no-document + - name: Install coverage + if: ${{matrix.os == 'ubuntu' && matrix.ruby == '3.3'}} + run: | + gem install simplecov -v 0.22.0 --no-document + - name: Run unit tests + working-directory: dim + run: | + rake test:spec diff --git a/.github/workflows/doc.yaml b/.github/workflows/doc.yaml new file mode 100644 index 0000000..2c26e53 --- /dev/null +++ b/.github/workflows/doc.yaml @@ -0,0 +1,30 @@ +name: Documentation + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Install gems + run: | + gem install rspec -v 3.10.0 --no-document + - name: Install packages + working-directory: documentation + run: | + pip install -r requirements.txt + - name: Create documentations + working-directory: documentation + run: | + make dist diff --git a/.github/workflows/formatting.yaml b/.github/workflows/formatting.yaml new file mode 100644 index 0000000..f896fbe --- /dev/null +++ b/.github/workflows/formatting.yaml @@ -0,0 +1,23 @@ +name: Formatting + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Install packages + working-directory: documentation + run: | + pip install black==24.8.0 + - name: Check formatting + run: | + black --check . diff --git a/.github/workflows/style_ut.yaml b/.github/workflows/style_ut.yaml new file mode 100644 index 0000000..76cfac9 --- /dev/null +++ b/.github/workflows/style_ut.yaml @@ -0,0 +1,34 @@ +name: dox_style Unit Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu] + python: [3.9, 3.11, 3.12] + include: + - os: macos + python: "3.10" + - os: windows + python: 3.12 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - name: Install packages + working-directory: documentation + run: | + pip install -r requirements.txt + - name: Run unit tests + working-directory: dox_style + run: | + python -m unittest diff --git a/.github/workflows/trace_ut.yaml b/.github/workflows/trace_ut.yaml new file mode 100644 index 0000000..0f1492c --- /dev/null +++ b/.github/workflows/trace_ut.yaml @@ -0,0 +1,50 @@ +name: dox_trace Unit Tests + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +jobs: + test: + runs-on: ${{ matrix.os }}-latest + strategy: + fail-fast: false + matrix: + os: [ubuntu] + python: [3.9, 3.11, 3.12] + include: + - os: macos + python: "3.10" + - os: windows + python: 3.12 + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python }} + - uses: ruby/setup-ruby@v1 + with: + ruby-version: 3.3 + - name: Install gems + run: | + gem install rspec -v 3.10.0 --no-document + - name: Install packages + working-directory: documentation + run: | + pip install -r requirements.txt + - name: Install coverage + if: ${{matrix.os == 'ubuntu' && matrix.python == '3.12'}} + run: | + pip install coverage==7.6.1 + - name: Run unit tests + if: ${{matrix.os != 'ubuntu' || matrix.python != '3.12'}} + working-directory: dox_trace + run: | + rake test:spec + - name: Run unit tests with coverage + if: ${{matrix.os == 'ubuntu' && matrix.python == '3.12'}} + working-directory: dox_trace + run: | + rake test:coverage diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98323fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +__pycache__/ +.idea +dist/ +*.egg-info/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cd18008 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +## [1.0.0] - October 23, 2024 + +### Added + +- First public release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/NOTICE.md b/NOTICE.md new file mode 100644 index 0000000..db34927 --- /dev/null +++ b/NOTICE.md @@ -0,0 +1,3 @@ +# Notice + +Code and documentation Copyright (C) 2024 Accenture. Code released under the Apache v2 License, provided in LICENSE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ecc7621 --- /dev/null +++ b/README.md @@ -0,0 +1,18 @@ +# Overview + +This project provides four tools for creating documentation and writing requirements. +They can be used individually, but are designed to be used together. + +## Sphinx Documentation + +- **dox_style**: Standard configuration, theme enhancements and style checks. +- **dox_util**: Convenience features for Sphinx documentations. +- **dox_trace**: Specification directives to achieve traceability. + +These tools are written in Python. + +## Writing Requirements + +- **Dim**: A light-weight requirements tool based on YAML files. + +This tool is written in Ruby. diff --git a/dim/.gitignore b/dim/.gitignore new file mode 100644 index 0000000..08c8a46 --- /dev/null +++ b/dim/.gitignore @@ -0,0 +1,4 @@ +*.gem +*.formatted +coverage +spec/test_input/resolved_function_temp/ diff --git a/dim/.rubocop.yml b/dim/.rubocop.yml new file mode 100644 index 0000000..be3b213 --- /dev/null +++ b/dim/.rubocop.yml @@ -0,0 +1,8 @@ +Style/FrozenStringLiteralComment: + Enabled: false + +Layout/LineLength: + Max: 120 + +Style/Documentation: + Enabled: false diff --git a/dim/Gemfile b/dim/Gemfile new file mode 100644 index 0000000..fa75df1 --- /dev/null +++ b/dim/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gemspec diff --git a/dim/Rakefile.rb b/dim/Rakefile.rb new file mode 100644 index 0000000..13112c0 --- /dev/null +++ b/dim/Rakefile.rb @@ -0,0 +1 @@ +require_relative 'spec/framework/testmain' diff --git a/dim/bin/dim b/dim/bin/dim new file mode 100644 index 0000000..3839148 --- /dev/null +++ b/dim/bin/dim @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib") + +require 'dim/encoding' +require 'dim/ver' +require 'dim' + +Dim.main diff --git a/dim/dim.gemspec b/dim/dim.gemspec new file mode 100644 index 0000000..72d42b8 --- /dev/null +++ b/dim/dim.gemspec @@ -0,0 +1,26 @@ +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/") + +require 'lib/dim/ver' + +PKG_FILES = Dir[ + 'lib/**/*.rb', + 'license.txt', + 'version.txt' +] + +Gem::Specification.new do |s| + s.name = 'dim-toolkit' + s.version = Dim::Ver.sion + s.summary = 'Requirements tooling' + s.description = 'Creating, maintaining and exporting of requirements.' + s.homepage = 'https://github.com/esrlabs/dox' + s.files = PKG_FILES + s.require_path = 'lib' + s.author = 'Accenture' + s.rdoc_options = %w[-x doc] + s.executables = ['dim'] + s.licenses = ['Apache-2.0'] + s.required_ruby_version = '>= 2.7' + s.add_development_dependency 'rspec', '3.10.0' + s.add_development_dependency 'simplecov', '0.22.0' +end diff --git a/dim/documentation/.gitignore b/dim/documentation/.gitignore new file mode 100644 index 0000000..d2adfe2 --- /dev/null +++ b/dim/documentation/.gitignore @@ -0,0 +1,4 @@ +env +build +source/pages/requirements-generated +footer.yaml diff --git a/dim/documentation/Makefile b/dim/documentation/Makefile new file mode 100644 index 0000000..2e592c2 --- /dev/null +++ b/dim/documentation/Makefile @@ -0,0 +1,14 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + ruby createMapping.rb + ruby ../bin/dim export -i ../req/config.dim -o source/pages/requirements -f rst + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dim/documentation/createMapping.rb b/dim/documentation/createMapping.rb new file mode 100644 index 0000000..80ed438 --- /dev/null +++ b/dim/documentation/createMapping.rb @@ -0,0 +1,102 @@ +$stdout.sync = true + +# get annotations from test cases +require_relative '../Rakefile' +require 'json' +Dir.chdir('..') do + $dry_run = true + Rake.application['test:spec'].invoke +end +ref_reqs = JSON.parse File.read("#{File.dirname(__FILE__)}/source/pages/requirements-generated/mapping.json") +test_cases = {} +ref_reqs.each do |id, tcs| + tcs.each do |tc| + test_cases[tc['location']] ||= [] + test_cases[tc['location']] << id if id != '' + end +end + +# get requirement IDs +require_relative '../lib/dim/loader' +loader = Dim::Loader.new +loader.load(file: "#{File.dirname(__FILE__)}/../req/config.dim") +reqs = loader.requirements.values.select { |r| r.type == 'requirement' } +req_ids = reqs.map(&:id) + +# write mapping page +File.open("#{File.dirname(__FILE__)}/source/pages/requirements-generated/mapping.rst", 'w') do |f| + f.puts 'Test Case Mapping' + f.puts '=================' + f.puts '' + f.puts '.. list-table::' + f.puts ' :width: 100%' + f.puts ' :widths: 25 25 50' + f.puts ' :header-rows: 1' + f.puts '' + f.puts ' * - Requirements ID' + f.puts ' - Test Case Location' + f.puts ' - Test Case Description' + + req_ids.each do |r| + f.puts " * - :ref:`#{r} <#{r}>`" + if ref_reqs.include?(r) + ref_reqs[r].each_with_index do |data, i| + f.puts ' * -' if i.positive? + f.puts " - #{data['location']}" + f.puts " - #{data['description']}" + end + else + f.puts ' - :red:`[missing]`' + f.puts ' - :red:`[missing]`' + end + end +end + +# write stats page +File.open("#{File.dirname(__FILE__)}/source/pages/requirements-generated/stats.rst", 'w') do |f| + f.puts 'Statistics' + f.puts '==========' + f.puts '' + f.puts 'Requirements' + f.puts '------------' + f.puts '' + f.puts '.. list-table::' + f.puts ' :width: 100%' + f.puts ' :widths: 50 50' + f.puts '' + f.puts ' * - Total number of requirements' + f.puts " - #{reqs.length}" + f.puts ' * - Valid requirements' + f.puts " - #{reqs.count { |r| r.status == 'valid' }}" + f.puts ' * - Covered requirements' + f.puts " - #{reqs.count { |r| r.tags.uniq.include?('covered') }}" + f.puts ' * - Tested requirements' + f.puts " - #{reqs.count { |r| r.tags.uniq.include?('tested') }}" + f.puts ' * - Requirements mapped to test cases' + f.puts " - #{req_ids.count { |r| ref_reqs.key?(r) }}" + f.puts '' + f.puts 'Test Cases' + f.puts '----------' + f.puts '' + f.puts '.. list-table::' + f.puts ' :width: 100%' + f.puts ' :widths: 50 50' + f.puts '' + f.puts ' * - Total number of test cases' + f.puts " - #{test_cases.length}" + f.puts ' * - Test cases with valid requirement IDs' + not_valid = test_cases.select { |_loc, ids| ids.any? { |id| !req_ids.include?(id) } } + f.puts " - #{test_cases.length - not_valid.length}" + not_valid.each do |loc, _ids| + f.puts " |br|:red:`#{loc}`" + end + invalid = test_cases.select { |_loc, ids| ids.any? { |id| !req_ids.include?(id) } } + f.puts ' * - Test cases without invalid requirement IDs' + f.puts " - #{test_cases.length - invalid.length}" + invalid.each do |loc, ids| + f.puts " |br|:red:`#{loc}`" + ids.each do |id| + f.puts " |br|- :red:`#{id}`" unless req_ids.include?(id) + end + end +end diff --git a/dim/documentation/footer.rb b/dim/documentation/footer.rb new file mode 100644 index 0000000..8317ef1 --- /dev/null +++ b/dim/documentation/footer.rb @@ -0,0 +1,24 @@ +require 'time' +require 'yaml' + +$stdout.sync = true + +def parseTime(time) + # input e.g.: 2022-12-24 11:59:59 +0100 + DateTime.parse(time).new_offset(0).strftime("%Y-%m-%d %H:%M:%S") +end + +data = {} +file_dir = File.dirname(__FILE__) +Dir.chdir(file_dir + "/..") do + branch = `git branch --show-current`.strip + remote = `git remote get-url origin`.strip.gsub(/\/\/.*@/, '//') # assuming origin + folder = `git rev-parse --show-prefix`.strip.gsub(/\/$/, '') + time_sha1 = `git log -n 1 --pretty="format:%cd|%h" --date=iso -- . 2>&1`.split("|") + time = parseTime(time_sha1[0]) + sha1 = time_sha1[1] + + data["."] = "Based on #{remote}, folder #{folder}, from #{time}, commit #{sha1}." +end + +File.write(file_dir + "/footer.yaml", data.to_yaml) diff --git a/dim/documentation/requirements.txt b/dim/documentation/requirements.txt new file mode 100644 index 0000000..d02595c --- /dev/null +++ b/dim/documentation/requirements.txt @@ -0,0 +1,9 @@ +Sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinx-copybutton==0.5.2 +sphinxcontrib-jquery==4.1 +Pygments==2.17.2 +docutils==0.20.1 +PyYAML==6.0.1 +packaging==21.3 ; python_version < "3.11" +packaging==23.2 ; python_version >= "3.11" diff --git a/dim/documentation/source/_static/conversion.drawio.png b/dim/documentation/source/_static/conversion.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..31a0f36c8596cbc77b4e0677bb7d61d0538525e6 GIT binary patch literal 20356 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 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/export.drawio.png b/dim/documentation/source/_static/swa/dynamic/export.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..b3f93cd55c6de71f73a3f0c012f4a7863a004403 GIT binary patch literal 38574 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 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/format.drawio.png b/dim/documentation/source/_static/swa/dynamic/format.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..545353a691d6f4f92d8b10ccc466409d190e59d4 GIT binary patch literal 55758 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 I#T&u@2igo=&j0`b literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/loader.drawio.png b/dim/documentation/source/_static/swa/dynamic/loader.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..f5dfa122f337d60fdcd09cbc499c52ae63cc900e GIT binary patch literal 168379 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≫#m&a0dVTpSC?}|@DkYAS&*gBXRA?9y zd~adukSTK(-_oMTlH?62N`2YWwQ=a!GqUJvZjP1dWu(X^tQdhu)QCzj=42F^koFstWWB;nLFaN)m_6&5uqQ=Mulj&{UD#O3Uh!uyK|;lyOUjd?*w7H zq406~mlq!EW@mq=48KNj8d<42=b76m^-+iYS4L2Wl&3sTPIAm%Vm!bnIDoo-SB{fZ z#%0+DEmi2%^6o?H$4)6HeEw7^UuN1#_H%eH1TJguXq~cUp5%C~&M=)p5Q*I|cV~Zo zhUw>DdzetvJqtOVuMily<(^fYg0b7_qZ}z-FFgB09x~8uNx(HzArmVu`5B!a1TW{9 zd?Y;joS~6JM_0$)>nM7RXy!%RCh?~@ZTUC&?&s~uzjd8=ApSIDB1xe5F6wDvdQCU5r^7V1XZ1j^Hs*|z(6!4_nTBVd=iJEqiAY2mP z0oO$+@G?_A6y6ojMgA`_oq}>Go1pZ2xSL#O-!=X*KMq|62tkeWkphGl9O{g!D8)`> z0+{#t(7f*yT=O;m*(8p8rir2l*K7bMR{ww#5^&nhmGVAACj7dN(&*#a#5vt~2g#R5 zQb^mtyjr8Sm1F@_+&`%W1z1xX>F?{^C$(X<&6P&eOWfO%KfJO{O=mZK`(cw3LYK&` z=oX?p>etP{gTug=-bIYC2pe>nM+}Fap)wn-sWiCn$1MJInGz63umSrMAADx?{dbI? zKpjWUp*3DJ@arkw@pXLJo1aPFx|?n#LrjoYZ#%$%X^JWl5j%Q8AcIM0L7Rb$IAQie zJx`Y)v10DtYryM$*^EqKdynQ>H;cWDmLoQ0{u+2J0YWY^ahNY@{a5^%u2f+P@AIx* znQU*b(uuzWZ)Ps+Uy#JJ>o6+M3W`oQNpEqu@X4uvf_5`$-e7WgkDRUJx-dhYJf_q# zf)}*Trq~I4Rjk1ROCpS6Etg2gKoEjFvpG33ZPWS(WfOQqae zAHg8SwwH!0RbQT?;es}{7$iu$`Eo05CedB7%3+Qki4)y8PIiI?N1Aug>lKO3 zN4`2GOs`b)^Etv$*#$dBDH<0w#V2EfVc}Yg%zd2>;l)~yByo?9{4LJGR20M-B`{sL zi*C(}B`Zc6xDdI7C^mI6CK}(9B;nA!v%@88t#1k2H>U7l;pPPYWP2cgc;g`hX*Tvn zz#HODcI9l%94CIvR9j3$%;#EqjDyg zaXdS+XJ4csjT=@K~lOQ5Cz!$*$2=eDz21|(A9ZsiI>42Sr&B3Bm@9OHR zG3Ym{)OlL-Buucq1bs~mh36Nfmff!#U@VWZP3 zG__X+0wH=i*5L4YX~;=*cbz!F<#RrOy~}+0n;@as&(YO3vYPQ}p-1>8iQnt+b4>T= zQx6uG8hSI-KUN|H0vlt6md{l+j;k{PRj(#F^zPT#SNCVz)+T2x+nOj6MGgH@-5PbA z&|j_J&$B1^%vGAkyW?}^^mJ3xjJDp6M(xxHC9Gug%NE|Dwhq90o9a=>Sk%L+@amW>kV zzJ)7?P60jZ%Wk@S<6JP z9ka@%vLRz2A>ss)!kMZfy7By55Q6(k`EjK08?ZO=69iT&WJ`u)*rR1t-l{n_`T>+3Dt~+Gz5ET9i|_}CV7wfp7iQ%E)QIt=W@k!{cKxp zGr#s7s0{mx76Um?joqpr8KBp269yN!FryYVc4?~ycebkU$8^*lZqk*vsWK#o_vbjm0Quj(n`^=QBwiQ6C?Ee2MN#5tpm2`7rA=`|>RH zyk)h6;ddHMZ|8}Yj*bv*9Q_wWJm%F8nOE3Mtjnf+e*OtB2_RfaMBAdoXs@9IQthV& zNg4H^rXjH+XN8xep00uS&R#fwQr@wGt8R}zogs~1>-#C+iXl4vIs28Mbz9BENUST< z^*wZ@v@T<9zolONSHFds!#$2=Cke;jG8Nd$A*zu#J><==KA(yBrKCvcNK|WAW~A#S zeinDThi5{HIo*4_r;8^;fLj9U=ltUfj6r z^u(F{8hXv?8+{|lJgSbMO7&Okc9-R3tSH5mV4M>j>9PojKCxlGCZYpM_B)^hn;m2Q z>bi%Vafz>R4UJ}pL*)=jtr_zmnq3}O^K7Om=M!reYvd?r)OR~_xtc-;oZ4O4vlxYh zspsS!(UOxKe|cXVCU=34Hel+}$MtM}L==j$H4Z(`@(*a1U~rKsNQPqv`L2L2*$Cz@ z&|G`b5_?tmVb{f6`{_$*kI_xtkl(UP4))D1VI};fT4KxDXFiun&g{-4ON2*6OjyoM znm|pYeRxnORy)UTT2?Hj`%3Sc+H$dR7(eEF2ewkba93)S1*+WF3#Pt~kbSFGdb0f) z#mz4@m#ulTa!sgh+OyAMkVW;qkUhBq&VYJLcJ^nGbk|&vjN`9IuG8`@8M}J%)wy3i z>u~HC_27J}FkiBf{oPG;lB#}_%UBxJd!i0=a+N@V#)1flxw6;Pw&sAFu0&b!IGs<@ zJ-ThTUHc~59SW`YKKHV~A1)riIipuq!^)=hILa0!3))XRZGK2Xt9E?MbXPmW#?`TxidzxIswpBMhb4S+fFD)ar&uz}xcTi%X2+d}-_! z=GkxE@gMy*3;G&77vjWbq@2!IwURVV-5*8kyqoHtZ2a5aY&lwDrA#s^d&dO^Y6M%< z8p&$&+YgGhpCo>aTTjWaXLvzCba>j2rx$`#wF?T?cSok=P14WeX2H{^1iWo4jRl=w z)px{hIW+!^p!kSzVsd|h6m&2tr+!sWY~ya7*{{Stt#6sHUnI=WT4$@J3ntn&Q5Jz7 zOX%aw3s*gb{HL6Oo>pmGcPc136D(Z%cwFP^H@`u zootP~6zx+2n4y^_8NTdGks7<`cD>>F%RV-K0T@t1xu&CMaT+O&~+GiJ$M3}Jq)w^NqIQMn$8dZ?jB%5%%aFhk`0FnIl_E*8~ zY_d5&$x}#5kf^i3OKg`W$Ml+k2?^C7^f-}D$`5sszCk3~Xu!0{;r=9KRQQd(>*Q6Y zapXb9tKVb1ZU>=yzGKAWn+{*dm?(yKLyO1z zf}0tR5(e^rPZ%U241;6Of+g(nY#fsq=eI4W>*djWeFbSxy8*C8fq?oabd`qBvPz0{Fgmk#{a5)Qf6XJR;&m*GD6kdwt4G@g#b!Y{Pg|8#*wzu4t*tUafl zsUl~KxHu98;{96`2+`;=M1j49JY9UmrXwon`Rt-k`v<-QY(S(;g()`)O>c>(BbyY4l{B8BsiYA3it206K= z@-sG!L&v&~)C-Aw{Tz2nR~b|$+s|bM#`3^QXzENifo^5aH?iV~9gM*VqAV<{KhlRH z42}Ybvuf>IGKJU2^ikx;?V7IqU9$|4IeApCq(DOC{#M8LzCU`kb(n z&xnT>Sh;_yj2GZ)tT6>}g*hZaIF6$k8ES<9#=p$qoe<&*hC)#vPn)~*!`ono;YD5v zKT@p~je&@8Cy%$6Z{h3vS4elw7_DEsGd$?Z>sZ=9ezS^)dd=E9u_&WyqE3W;UUQy6 z9|v={G;tW-_?&i(yf{Fc&-m?kfDyb#l1qM^0izS?L)(Q|X`p`6r=b9{fXma=U@om^ z%cRkZ;dmtyT|I&Nzx_--UNj74B`Zp62GCmSd8ad~v9vInkFGmh;eKZkE%^=a&1p2T zNEjiH6O86!&NCM#JMvFi=k1GNo*NUTZF;F96TrM*g7^Jb$Z!)~x9Bm`y*=}RFj3k< z{yo=v15s_qx|Sw9MTW1UGBVM9wZb7UWD2^!fES9&ZM$b91hduyKYqM`xdre90t(U7 zPhfe8y?J@&1(s4py6ZRKe(j4JqU-1+P3HqmuVkVA>Oh&ls{x&LpnxU z)-e41h>0F22APuzA?n1vSY}L?`z>f?L+r3sMPAYUpcCnbePL5C06U;+!OkmzYv)4! zYkEI510F&LztduKJWaYSUKgJn!{Sqg7uXXy51#AZL7wFjq+P%nyN8sP5s(8jXXxti z4iKki9FBcx{yo-VA0 zbv0jI-6M8C%3!o2*!{#r&LapG{|$AR4yl*~cw6UYXgi)^PgJ^nvKBllR0F;?_56Zj zLE?#Hv=7*jow7BK1K!%6p@ow0ehJ{k2_H50q^Q49h88zO2RG2sKEoECrhOoUTzVz` z=u&+PK)$9dT4$SMS)&-wu>(k?5uK32iIj5GZMvsmxAI;H%8T{3RJcNkMrFoLJ_7L~ zgn&@+0ttNmt*hXTu3>63^AJU{NuUG%!r)8tf!KhlJgdwngeV^bru0KcoAK~TWIT5G zU_3VD6{ydnQKdzbCMVzn{dpr&rjQRLe@cQZ$5M-6Kq*|~gs#|`y1i)WfTqLPuTxBD z!aGM7J>x_!a$JCm=CuZIklC5ui)#6*1s6ew1P>w7*W$)`Quk=G_fhK?_t=z}UHn6C zw1p3tkd+l9y@LoM^d}d{;MBGjAu)*tjWPXvdV=e5FNi5*!L7j6u=rRnNB28=Ol;n< zwR^Ngu%^g%1qCdKoc2D(8PWbjYL<=*ha z5#W%4&m%&679W9c1Fzmz>^VnhfUZUi-a&@T--wY5pz>!(XKuFat!7BBx+fv~ih!%T zw++^ym8uPRV;gJ)(B1^S2eI#7Fma-YYQVS7Zp?EFlJjW9wT{>F+l@+)ikd>?1VPBG z6;AF{@52LAW+e^Mf=KwGn%@Sk+abLD z1C%NFhDSDlmIB~a?N5<+xmYzvpo@Fc!uaV;p@r+BW}jhaj`EqzS1v(l7Qn6o~}BD z_-7vx>*Tm=84bO*Q`Z9O69k<3hpzO_M5g?L?z258>uz_vp`;D910$Gr>Nk1du!N!| zD1ldErh1x%RCTId&K1<&x=JlH(<7V!U1|oSjdeDB7{3QFet$JG@!1o(R0G=5o{NeV z6@fi$UFQ^Y+ko#mq3h=a*F%rjfaoPig`2tplMc}z=*lL9rX^n(oRbtWJ?+e3@`701 z#G>uf23o?Y2{;h6Ox*(>zb8X^^cOGc~ICARu>Qvhl02Se)z9;9@ zj{%+dJIv#c#PV*Y7b-G3Dpz+<7g7N(H)WA^A}v4~IyHYOM4~jC6os~pYad)7A>e=` zLtD#1<*bm;N2zlyf$A%*xZ^`9Dsx#~rQa{9Bx|*dvq+vKecFJ?(AJW_kg?l@S=|N# z(m50l;QNr(*+y|}?o>#_=)G!Vw`Bp9)DJRUHHs|TwpPKDD?92{CR@=(OzZ^Qbo9{m zdin_G7m*J`ZFmfj+#VjcG+FF?=W7t^cM_i*U|kL_q0CbuA_sMxy!IQ_Dr>(b?aaS8 zy(5UWdc%FSEI%}l#9eMG$NVq3z}HZT$T)haS44K3P)R^{a45y!QosrATGk#zei}>) z?Yd*q!gmO6t!U3!n%u3Fv}h43Y~=Bou{PjnyX`e&X?wR&Z)u!SvP^%O@Ew&S6#R@#0^YpDZY? zdX8G6)4xxtq^nFk#VGs+=e;A;%kcrohe<>}hQ$PDU*N_uye~vKt%mf)n%>vFEgcej zGKSwaKfb-J#d&D3UFl$LlX)|zE2nv(63EA$fb^wldO~~z3p)Ynxb2~%MV6%}%)Fhx zm(8@aZDkyxC$5^xylN6m(b?AFxiC=WUh7f)$iF0WKtfUQokIJTEghKa(I7i~9Dy<} znp2kb3Yqad1%U!Xgmb+-z1P{__jELvE zxl-`y-k-Dt>MXBG>&3Z|YG-BEU#_6E$pDL8vXS;8VY`l?^4SBghV#X0^^tF*xT2X7 z7Pe$JIs?JJ@HdnK*Unqx-#aCWJA3W!b+|nSN>6Q2ZMe`Jt_xK*#DWM3!05*5Y<|zu z%?P&3Mz@CdZB+kmGW|XuYxlboZ>F|W_9FY-(A_iO=$-=3=F$AonU`4!?VLtkXJn9u zSlH-gC0YaV;QvPYhb6zspYV|;*t|B#)NMZ&#&$_DeA;nOxMJdSDLTANwG;FPA!L)a*Uzr9=5+}^t)`(@&4 zOD5k?DoH~T$(qT>%}ZUS51(XW)j6%!c+V5ik_y8xdzpHTo+m)Bp}d=5o$kRp-ENEd zN=F*iFfF)%%?)Jff6O_+QYI~sIs7HSWV>kv%NfiPot?0`9ZL$Vbf|8TUrl$=PtC@T zK$SB2EFK~d(DmY(E6i0IIC+IcOr!}fN<3J?UE;Oxb??gZqR7-Ol~In_-Q2Fp6>iyb zEuO-@jFC%_4f2eCZwJ<2Cp|;vklt$=cQT$kpcK;%2;|*DD z>Xz3e*S$HHA8Tc0$`6>QW6nJA{@d49Tb`vLriAZ=fSpps!Vnl zzQFjG%AhLRVe&0(BNADWdCUp(25&uU2ng}I;WfLd-KlYp&diH-J69aQU8gnbGC_ig zXF__pIbg+VZ!li{@^4G_ZS8a(mMt|PDjc`LO{_EfiTEgqbBjdPxc8+i(SQY@CNG(u zmsg!yrV0~-J&Kipb{t7N4C?}|S&@?tz4B0_NG-Y~Z;YwnB6(gS>#K9rHlxJ3;)UTp zUwj+rNR8oZg?jC)F|o68wTB10b_d%t0sQE23V2a}K&Wu-mxPOgC30yqbqwlk8ZpzQ zzTO2*Ar|(G-u?MqoYm!#oS7?Yc9d+lyTuy*SJl~Vq1*VE` zCZ@o*oz?}$db~IAH6L?<(V<3c;%-?_)}WSR?ttQi^aQchz{~BThr6fKeKpVv&wpD_ zo5L-v_*HEKIY~mYY{J%DSP^glkjLIp=Bk_|Gy7KXP}0T`Jry3<-j+gI0L#VHsJCT+ z0zZB$$G(g=QSW`JaniRBF=$@&Y^z~?%%ym8^fRYNm4mToUR2UOxP&({wfMcmI^48W zKu7&Te7Js*b?~tF0YSV9vnHW2M32$Rd-B$&eM$v1o7>e_WU_bkQ>=TL(^4Geues`a zhp()ewxLP5WB8-4T#aY(6BS{>2kO3o)stQ#%EFY;hEr=vP=IKTct?95Ox1F(i+Nnb zmmt-Osu!=*+7EMh+@or)X8qu9KC+a{*;(2KNVvjYs>e|#aTAHrcEeD~Yc?!zhoPz$ zls4z!tWQlsqppZQ7>GVm^x&iXTxUhP8oOcJ+xF8+CT)2eIQMs@nFHEz9Om-5MqDT0 z1$J;7f#b9T%)Xoxgeky8jy4!=Hzobo;pcQNQ>`pcG`2Ci6<4ckV!eD3U8-|+`=iWX z!cn|sIhCjJ|M}VjI9daHkNK5%Yc*U z;@lsT@!+JZoyOj<=femO1Z)qf8C+G{dI=Nu(2CHRi>Bsd?j|U`= z?^oQCT6NxM8!2*^8wlSN3emjCA_S!!xTi4u2fr|Ux7U3Wc|vjcF@^lJ_X&NdcgrEh z%{DhemzoM_HA+7~CcoE^om3|qCV_N9U+*Mnwjk!1T)ZI1-NxuSUH10`M>GHD1gB4P zub4d~%-M4+%=xySP~7098~$VzymI?wvW@k?KlvGS35rPyoDQVdD0;ai2pFLIo{WX=ci=XRv zORsNI4>OJBz2R_VyA@qlTD8MRG9mUi*Z+(jZ?pEetYiZoyvq|cPoF2<^}+HbwFdj@ zrdoZxrjjL|IeE(Xxfl`EU61?IQ;K11so65=RTLt`_@vi?4AMl_!Uzu^u^v10H%c%= z>Z6^_()!ofIcYdZ-iDhZlQ~S~b5t}J374GPG}7`k-?zC6MN&~Gh++}QNz3r0x~v2-bgdlJ#dl-QD&LXe;p(J3Bm02DfOnnf2dj_ z<}fWYzc*jUWBAV)kATC?{)2vnTN;&+LxU@K30b2oGxi(U+%U1QNG(@PoRzA9+9}e- z8GVYz<37TF0-u813=7160BO2HqWI;yU2Bjb(eSY#JNxu1-8kTm?NSwI^cj8RTL$*G z#<)S?l#5r0>$UuYrNL6%RuwcLJiGn?-qO=cfi@8=|5{}>;WzWUS-0^h=~(fF^S*@b z>DSAaFOI5|89(aSotl|xL+l$7IZv=%R0qx!W6%}8(~e(;kBux3q{u`Vug`vU_!6E) zbvqq)qiC+K_6vR@X_Jd!hlN-lt3(nI$wOK--5$$;Xd$fy$T4z?hEi6Lpxcf)q_tE1 zvsC9>?93H{9Xj-wPUC7UKYD1_TU9bVjw)7^zRpovs@wvW3&m72s`;QXbBCI@G>T`h z)cepY-C`5*xB|uh8B4#(6L{3H1o<@@6W{Q%Vvx3G!MC2x4hwy`h^2t*4?mXBn>4?7 z_!#Y`DYTn~I#dCXA6)txg^2 zTUn^#-v*U?N@1@W1{>&_vlW^a$|v7Sfoy(Vp)@6Cx2FdC$!{2F9>IA)V{tY zif;j=%h>GEi0BP|xmxpd#yh9Ww-sprEAOjFvo~q?Y?2?zDHD+7Cl&V_gr>jAzz!c; z+lSLX&cMg>9!p@o2Z^gaxo`N*UJ2Fu$Qmeue_PHlGYdm05Z}|vWGGq3nob3yAus zl4S-k=yic(n4($d)1(j;sXLWnp~aKGZOfi{%;JC*B>)z9+>xMbIxq>3x74kw@r%Kp6b`T7S__Izd$W&p}Ize z-gtgXVtUHygNsv+w3;5N2!3odYQtBr)Vw!2-2HcPdu#i3^$z^$NTWwlRp8 zaktOuAH*`<#pZu1pchI1b9)Tg|4VG&=I!&A{iUV9DH@f~En7#Zqs%%0p18vIC3fC@ znOYwj&0V#Ea3FPlt}B^8-JHDC>vv5h0nAy@Mh_Q0-0r~XsvsTt=b1RqqwT#PI_`!7 zuyK$QO%~1Gso`$np0BFjnq$Pk90{$qu95RP=;%1nr12~G>ROHE zP!XuRj3zg5M-As&e9`5Lk)rXCkHhwfFVnat-94OiVQJDmd6rNnqv}@I@9#Xq{7#W; z0acG_G|?{JUsI<&e!O5w5q0vkt&hp9?B#B7IxLezco5rqCELWi{S&XS2;+v|d6@%o zc#&|lqL;a17hRWcwu~~H|4CXp5~irL^Gzy_2;IivZMx;xu(yE%8HXrbyj%>cIBkH*pvKiDPunh7at?Cp8OUBCw55iFFEIohO*Ry834=)U# zjkww^)2no5|Ni&=rj`A)#o&D$`^v@H=FBIv^Or{7$$dU|)BExMDORuA}AF`EK)vT7Qmkg%-pg-w3@NY*g<|51RRCJ+PRsId3z8@ ztIaT4VbIS`Bnc>wk7?IL<)?t4zPG&>-AAX-#;=*3z;EO7?d7gFBDgpuro#q}bR&%- z@yyp@Sx>%=KCukrTJ@S(_cC&-M_x7E;BBpqAT`IiozbtF*SsG)%$C0~P+oPy4UhfI zdNRvr-b=Xu^Tz@0`$zYM-?~iL<=ZFq+LV)&B1D^1mH#2ypz9?z>bmxi2gM0QFD1S@ zOA}dHshT1?XWo^$eBw&}U1$vuCgA17fE!XIs^hLIU^gt6*wkzeR-#I@COP(Ei+>v4 zNdR3NAH}dCw0)zbXYHz2?Q3St_j(uN7{L{n(fnd-&6ZuN_^ma8vMH(k#PdSI&TVP_ z7zn{}{d+%oYU;78vTvL(HCF9+*XC_G*4|sI)GyJRKIgsJan;w*F71=Npa0;fR-K3I z3`u%zc(gUT8hC9}Uv7^@9$6HF{}7_pYM+%qsG|*nueRkkfcuIniTVYm#!Jaz810w(l2**Kp}qHB(}+-wBg;innyU>yj@DvW08hWDw3r znQ@*WjseQN z9Z(X+9#i1$u?@=Hgpf|lRW08wwSYsNE^nrPm_xx&Ns@Y(?%t6omB;BBh9<8N=E?Vayc6uOo( zxSdn{C3HwNH}PG7y2r(wqA`hk-e7!J)#dDqFEm!3tmp^{iTYYUw+`uE{h+DTz96^E zv*BcPTd9moo$v19-0fMz_N-CR@lC0xNkm+czuGt8w)ggJ64&^r&j6a ziDWJy0jv3Iy;iE+OlIb1HNWYUTT{o~gSHSs&Guo7eOztEuUe^}h`T*_eCYRZ z+IrRjjX{yZAZR2{Uw{=%RP?su-FWOw%}qGJSTtpAO*VY>48~sK)}Uv5k^G6at4ylA z_|gH1kls4ICj-ghyAPhz4eqor%k9a%?)%A#Td8`uwBMjSoP6FXWBOuWqc6VZitZoM zkjEVlx%bWj#{6DySmczjNC~Rdyvh>h7;)vp(`EuVAiq!ykJ#~+@VKjeXl&Xg2uwzT^ z^d3HUA5NQN?bV^Zik;KrQ5lH?cK3zca;ifADaWPKe*Tz!@Vnrk#mMgT4kc&gdd=@& z?{=k?PQk_Qq`qdiw2oO^ZQ~B9w4W}rdC|^}8MW4SnUSXe<_k7U@vYmruRv;JS|`6* z*mEb^0zp}U?-ZTnwIeePM(Htnc7AJo5{_zCUUZmSnq!^A_4>CJZY{M$I1P-X%4e>g zFAm&nkKHlN;g|ES-Z(i!=ja^pz-5MGuRJ%b?t9~^uI9=Ut&dY2T{5QM>rH}F?bD83 zM`QUMqd(GjMK?VbK9jM)u-~B4bMB5cM%ik@?-O%hF2DJK=P74_js$gXO(p)GgW`AD z(IvE`2_k9be7IQDXY@s5P+i4s79$FZ&?_->H$){%jn&UY_kAl4I#}YZvIH>ZdMo5s zTdp@Yu(9q9uZR4I4+k}RP?(lh?cXTF(R-OS9VgwL1;lqN22ai{=Y0bWjx`S5g|b|# zra~Ykd0p2ixis5fCh6F^3>eXp!-J?uYH%|-NpfW}CmZl}bVqWkDz3*Y2TePp^2Vy9`$~Y@Wj&IA zF{XaLD(}6$IqK=wCY6i>?B|6JrxPuwW#4ON(R)suJDk?fR?N-#yq&&# zDo!hUJa2y+;Cf>-wbU12Rj$ENZbL#4$Pj7_mO=-0=-&bPD zmmZ`gdwrce;AI;$3qnTF%k6C_ zym{YCZ{6rq_m$c;ip`KFZXmy%?+sGHpN`_a9qrH(YioETT>AP274mC&^K}MbT!teb zfTT>o&+?f&`%yQ#>v@7`>sXe6Tb@iy#qP4btG(|}$8CAyh9k&&8($-TUy_NG}D zX^B%R3t4tk&z?x;{Sd=F%2YJZvrUy3oJmiN4cIKB%#7tMQ^pCb+?^5c@Hu{}$;nq# zlMZw8QiNJCQ-R&?x$uas%(XK*8?q;qSW5gf9}bZ_P8OKWaN|&>m>xmHE1FjCj9z~t z@F_XpoPy0{>~$)ZR+$D-g08ZQ{@Ck#F_wi+pHE-?b`Gt&w)Cx#AvvY1Z@m<#W*MPc!TCxh2FB8{d@v3ZR^9%DOMltQ*pmobfxI_ z1YI0X6*%qM#n#UoB3NlpuCZaQL;ks6sYxPfQ#l!dVa3UWCwAAoTC|nbLgC*`2d)XJ z?eS6k)GAiq>Q4f#x{1-nnSX1ygZKo9PdJi5QY&@B3FUN1yhN9xLtX%Vk zw)WXj8nx_>*$MPO0cw>Hl|M)7QTwD5ceAt4T z$)tR`IjNiuA=O^j*$|Kpl7G-P-e4j2s z&N-whV!GB5iH+jW?s8S)G4MP829$|83~KJ&PbiX(&HDJdXZNoGhwFrP(cj``xQ-KM zoE;3C2$rq39Q}4jbxQ4&_eB9WY;jZ=z~H1ntZHg)J_0NNV&IK+8lS;^`4R=7fxjEW z5^X)u4H=;84wP~)P2T+BPYrIL6cq82K!q-VNm27t^D?gn9XL_S$EVLAvdCH+yqr3S-s4GjkZjl5pw}Tx32aCXGHh+# zqe;;Rh*xX+cVtkT$O)pw!6a@#mZBxqb)>VeV0^%E?X?e7wT?4#{etS&^i`dc!GHhl z^EC6nw+ICVl##2|P_4}Lv|_YIZ%23w=nOXY48;P0A5lSrn3kjIt`v5 zFGT!_a)u9lCnr7U@A_)gs_b73v0kx>cRKiS*T_k7WG&UUmwfXXtvw+lut4OFT`5mN z`crr#&qN-B-*x1O-c6V@P^pL1AFQrAMDVM}zlk;&T+^=htjtiQ>~(+Bo9kdVID-)* zBtSHy)=!@l0KVt94Pv+TKW%5E(&v2?s@I@uU)@!ramvi)QSrqf^RXM*x46Sn7wR29 z<+yEEZQ{`y5vG7QB?zOQ2}9Z?A36-b0h>-l!j%A^hXT*B{A4JdSeL4%$OPR=ONlDG z8~sG*x~pz9R9T!nVk5e4abFPqTZWfJ1LRc-=1p`;{)qAtGRi#I`YR#$t$MDOYFzK~ zo5{zU!*#|ZR0CD^wcR}IhFRf)ei5t$9#EX#2AdTlpj9*m`V)Kp{Wl;V_@_dsLg%ta z!-}-0QcY@cqDr5)e%E)zbGmP>L|X%4AoEA6XHp0e?E`*Tsq3c~5+Idw_LL7fi$>Lc zm^|gf_;1tv4w`)9rth(1)CV%+qH0%~wzJb@3g0)TT6}Dap#72y6)~t3G`ThZ4N_i( zwj`vRlP$FJ;ryna1mdb@E*NQHL$hGwf5^J}%!*bf*7S?>Qv-9wLj1|RZX zB#>vi;k;jOJh5yDbJCerHLE7mtO?s+=UZ)Ju&kD8keBF?p`giQYNJQ!a~VOYpZ(x9 z1bDLUfl22-e-nOFeDJl2+oW-`vFqJ0R~5Q!|I#~7OJmCp?N`*z=yJ`mCY-0pUOi2M zeL#4Q*GU<$#AL!>uEOwnUR@@ZgqI~B%tgBvJ?_@*5~@yD<1`#8SoBxK3@t10-gYi3 zxjQG1Ui!2tG1hPi>W*S?_wxc+AJ~Szi7Q{5PE(uF3j;7;Kk9*mB z%TInvOQ^p?U5uJfNWws?1L}3DPD#x zeY5U@_#X7ZB6@X0VQNzC|K+(UrGGd{>?+v>OeUK zws?@5&!406esoSegRXO4jP*cmsz;`53rW)mjH(`iLrn1#4aFe#q__GW!?vGKa85>k z9^#2FmytoMoeTt-V)6^jTtIm`&0zDh885bOo|-jY-2mzoR4!U$Ghd=>cb(<>Pijif zk!kyMyn7@c z&C0lSY>a?((zYglvS7^pmbb9Z|4c#F+gMSMqB67%ratBaBC>MaI@-wKRi*wER zYg&Gar;}2qPF>ZLHAeoQ|Ab_&UD|eoeoJK3FL&Vw|LJay{0{$Y0JIigl@0%e$PJ>L zZ)I9_+H0{#LDWX6%#Z#A*VU!g7JwYKyE4p)t$xsx0>6X+ZFC9dMH$2xmbrIb@6iSk z^eyTE9d#_~7D=^C!i19IM0;4e4(!n!T6`nuutMu8X3CIP$KdOp!EDqZ_!kl2HbIyC zgYIQMUcoIZGo6KyuAiSw%@X$y({%p{Z!BD1sO8`1HnP3J18)~L`KEc0-?oHNAJB1K zeJOI1&~j`mJ7Y^MTX*TAnaX>GK?bclvv-qL+RVs0_#A^~U0Oo{H;D94?1DJRy#cxd zDnHGb056y5Kc;Or`9ip(z3~EW!_M0239Dw7%HXsKJ=CDRU{?LnCcNP*(mA;ZEW;vz z_QAV89MOJIdp-gBElp#+6kY}}i%bcr?$j8X9;_xtvg#|s#9eeJ{jZ5z*YTMEuC#+K z2GHl*@OXMinHvxgRzP#ZKp4ImKG+13vEVnXqU=DDh0ZfIVEA4abXyM<-k($Axr7g0 z#uq3=8@%zee4QpM-gj{g)!+6?j1f@qKQw3`Xl;gi6X8iX%`Q9A%fgS?AaIB(Mzm%S z=}K1RBQ6-c|e^1gj*vl09Ae?+7Q=QV;PQ`5)TiF+4${S!N8v ztQ>~KQYBZ1uM&KXrm*%nKgwaCNSd_2;VA8U&@QMv z@~ib6g5l@jYbNE9La+jm28jf0o=!?XfY?guzPCU}W9INXHxN^L6-RY0XqEh8*Dl<5 zKdP=b^9y~~a$XwaLP~)_Ax~K0h>7}nXBgZAj1j&Qdb1s$4C{Bw@wtvCiaVJc;o1M5l$ho)2lPC4>#Zis@<1T!cW5;pz<$;1{Q+AiFc zD>M2WobgLNPj6r@87gM7dEn^T>4;db17@rV?!D~Lje5?L3f-oa8G9LD;(}J8RiQ`m zG-`&jWIk%1!t>){^`mZ_Ar{k)%W$u|nKwv3y;}iPsm>56`Wq^|CIn^Cb9hX*z(u$D z4R(Kb?9eHZ9clWy3Fdi`>qyy%YF+tF07Zad`9 zH`K1SvICz9+yWFLuhNFn;a_#0LU^On-8$ZpFIf)8o>+hQsQqV$dV(Y%$PRVyD=#N- z^JHPCU^C+-hZW6;Ka=2`SiH3IjF?N>{oDL_Fk;4G+WzKz+%CL?s7%##W=7LxTG`Gj z=M^p*uipX8du`!hDQ*=MFr^v=eki|c* zhB?0k=h$G>^QSNXH_zWcWoroFGKpx-X>k%a3fFcPvCm_iWx{T6fKpLbd~-! zrBdfG#b`PX>MJ6*Axt@vsuH2qC-D0H{nQ-viR2j83+b!!ueB!$kIfk){h;q$Eqb%2 z?jA;GX@adK@uXubYxL7(bNsVsmcwD6Nv3V)|I7@2 zn*);MO2i?gJ8B|5khMYDV`hv$snv4T{1lrZkX)Gy7%fDG6QOw{wO`yTVQ|El87Ou+ zdyJJ$qgPP1BTgU6=D5_YVfzp@kgGwnpQcJePT(H$&tKg8WJ-DYriLZGzw*idfK4nM zb`>U~&>@&kA{VqO?NWgbCTRd_A)(ET@twAxsb|i71(i&U+{22Ljm3d(*FFUqtXt+5 zqdQE1@Py4by8sX`)i}qwDa75BX$qkMSz|2kaWObK`3=7*r_~AT%EoXdG-=14h6Mwb zoE!-yv9Nh}hBYAO&qZxq5%2E3La6N#XO*cJe}NN|Uw8?$H1A)QvFLp3V_#G2E^7=r zJSH%yWjd}3i6rnl8p9CdUTNm)Oi>MWlr=>fnTimmggo8(@ow`T17^+$Cr|pfw*b6q z#S__@!p4Wj@0;;s;yMz6Hjge19t`1%V2}F{GB0gz7)RoEKMybX;|5*nx!ckJ##JUGch3Uey>npJHfwrxG>!bjemIJdUoS8RWE`ai}tC%!2XZB5{g_Z2SOM)Jo1q0 z7mf;4ssl1q>B3Od8r0B%Aqrd4v+)WNd^}(ioygF7ej4($$Oe$Sp+$m;jfMVnhvDRt zyWq7o(Y|oaK0i-Wmr657OSvbP$J@XvK~0x(B!;XQ0u#u}E=-CMJ_cG*cfs}N1pgUH zx=e;i8H1-b5E&4fqd>w2iCX0nx6Ipq8oJcZOM_7k97vg}>_*iSyWG+79WZ|j zg|=`yj7+!5F+yX6vnBdlp5%X!tfOr$<2WyJ7*Xiihz=U<{``2(1X!QEU{2jR3}qvv zV?-5vp30w3AVOMtz>MStFQU%N$PVwmQmfe$Z&aMi^RQ%?(5D@lJch^VpFSOfNVJ{^ zB?P2#cD&M!Cxazs$%=gKpX6k|gOwCZ3H?uM(?Jmf~M2Bwxu^NtMO9BzdgL z%=RI56-2Li8|-VbA#|8uDpPKRkHu+0Zh5QS1vcAM&~Qk;X0Fb?@#3x3P#JF5ETg0L zU}xbUqK>^d2QWWH{_ay|0}`k=KElu?xq9pQ=#%zCN@CnkC~U|a3&L8g6Bnf-h-G!r;*J)7;mbPrxN29wC9-e?$^rDC{A^bCxpr?Zq zG$HIp3HVjH9g}~+M#=>>q$qIheg5J8E9Wy*ckTndSobl7f@2#nJQ+d+H{aMdzuwiU zaVdoUEB!<;{+VHv-jbN%P>nJ*0CYt}*{-k7(;ahI6nWA4&>9}wJ;-o;Xz!=VQ_f(b{NEo0}m7PPkoq00CN( z(MwTiMs4#X?R*MdyG>=1B>s|wq`wabtIJ7g4updzo_xOa{lhygy7Sq$C>S}ducwRa z(e^}Z71E_AQ`r%={17Wai~m2x9s57j+jeHo=!{3FkqC7eCRZ}97-f7SBY8(MC~*uj zO`VQoBvGRA>L|~OJQ|4@iW3=5o(Gdr$r;Zud7L=j3FVd7xNEpS+&|!cK6ieZHQ(8L zueI0O-@VrUe%Ir!{j{?i=|}8H;_n25!hLzHw`XrtXO=fCVv5R$N9LBB>7xbd0J zv5J5E3bY&ASNc};OID9 zgUQLt{0_&WE&NRHe~QJia541vPn5>0UvgM@gtG=B)(CDBsiSiY1AWg9XE zRK?#dLY~jdlkfx|2@}8V$8QB za|E&g6-g{u+hqZzv!K~yuc-uPFkD)?4oS<%I7KAaMK3-!9D%w8ar1o&8kOp zrO9>A06JjI0}T1lEMI;V|M3xAs(GYy4vmdAXENmC@K10|rV5Owa-j+5aSAvso!JgN zcLFFma|kdvLNmwMb!o;)CS%mSB~=H7IgTfjVjAzB!jkI}VLYrJ4O_e)g!%sx>xc9@ zxRZW+Z)Z9P`Pps2Tb)If7;IjaD?y-3)LLtT11o};o{#U)K8(g%<^d}*LTFA4lDlMO z-@*ySQ$oWYs$GgS5S$|{O-xMQoSIVZDxuk2`#OC4%5f#GBTW%p> z!Hn-1fa8@Vc>DD~G!!kIZLo$E8yf61WG;Xk1Y`ul(+YH7vJ#Yyo4}bgpj0D?{BY5d&7P=KZr97d zXz2>uG4XV}`yV$nz$G*hau%3HfV*cT(L#}@C;djv-py^ZC?O=}Lq)=~KDaA#OJ5KQ z++oR-sz=ADe1=lQB~Y!=04kN2%8M({}h=!PF+;9?Rtv z6+R1vo`&>j8x^0CresmlGC{GYsiD01Kav>_S{n~)p%qmbGXqAVXiP_E=Q~2xbEe=_ z4qRyOrZ~_0BDsRvI7N;{f8t?UQ_}IH_q*Wbt--agIiPWhb!-Br&u}5g{~Q;ycAyvx z)tNL7ypTH<0i=rvD1J(?5=FhJsj1zAiVPGypTYJu=o%}Uzl#XT>H_!7VbPPDp9Ljk zU*oRs_YmuPWY(|JBjXjE#j5Fblf8%#rz$>BC*<$TQzqHOk>B@WF{?UxJd+ zJ*XuasOrg5ur{OPuzZN}!b9vzvrGIn#W#MnPucyS^)O^A>xim57F3cQxHZhYI_&T*O zbjL-g&YG|$D1vGr!Pf5Ky+e zb)Nd2vSAPoc7&blDi2dqy1&&cAd%=;$s5aG)mr@zHmX~ippQx15UvSU`{9h1mx&)I zdMKvr<-3(LREFOyC@;Qb9EPKj0=VF{M67Gl6hBV7+jeNWRxW#5Cv;dy%{QgGueTNW z&W*LCfS`jqE=EuYM$k^WK49iZTCO|*|ep$fSSv)-9B+=3sg??FKd1BZFx5FzU;3e*2TK{ z?_8f3cvlFUi(K>*1(lbbot)HG27julvG?^MXlW%wZO>a%hkq3Vr7PCvMFms{&|{LI zvm+?{=sKwXS%d2W-*oMyiQYX6Je=@6o;A^{2nN9wrR%&41J&0YUyCd?;|L=Zn8mz!I@demm_f)iiCR(7rti0n+W;IS*-dm<%VOA? z>;LrpDGNRSEX`fxQd@RZU=_9B{=6zHD*Z~+4%H;Jy!uGa@O*e0jwv!SAVh31_P%Ny z3QjBcA^qA$z(qfI1DhxGol`MxrGXgr`7!J zKW&deTa4ik0nX%Cf~vq7Rz~gT+n-*xFHZN{?C11HV;98fDy<~6Xa)!*1(ZCcz0>L* zGqhnDg3ztf?@|0kbzY^EkM>oaZ47K;{geUL%;av4nP}2)Qh}xCw$m#x$8q+quA1Oq zB^}#9L^1F#BAYj0aP~gGWT2!eT+tx}m7z8$eVN zbfJ7c|6-E^&p~IneUhIOq31#)Zm-`y5m^Y-3;5-w&fX+N9>(=LTYr3OrF^3>8I3Ms z@Q=3zAjxp&IBZh(J-PVitZJCzNXga|!O-2WtsUswE;5pVg5tWHeZ`dRAC-siAmC$VW_SGgF^}+n18(Gq A$^ZZW literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/main_workflow.drawio.png b/dim/documentation/source/_static/swa/dynamic/main_workflow.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..20671daa406b7822f3f4ed4953fa40fb9dba5c5d GIT binary patch literal 167081 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%0ALOejREAu<*AfR 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�_+RMnXZ1#ola?+zAf#c;@Yp}H6tQj5TB{^C6A5&B!GB*EAL4C@bp&d(6c zt_GR&g9u9D5I;XZ2LcA`g(d{|Kbgx!sX&Ec4*0L+YuA;2dBt`Go;nL5^8g#Wo>dKE z8$y2c3pmDOs@;(A%`kdX(*x}c9$K0h4l!606nSQTJbZL##2?**_qL>5>6!itF3cjMD zMYrhB%m2>n3Xo&94~yJ~sTXN%+1&zJi8xRV9|Cz@L0}o%KH}p&Of6p{o6;=pkBXQc zrFbF|8^jj&VgEyJy95@U!N#yRIts`Fz#m8G298jtxh~W!qfGa@b8*<8n}(pK$P3KcCn} z@J4~>`zPFz{-J|dWlfq|cd8ovHY9r8?+Z>TVpF};34RCXVg!uXNux}#8R>i=%4C<>LGNWzxP5!{Qqo=SaiBC`=I_+0r+3b_RlJPzQ$@G(%x5KK{*P;Icc zqLPw=fY*;pKgu;Cnj#*v31#ASU0KT&3~0E&zDFE1FzUGDm!ilXft2as7k}U(Z2-<^ zpC0h_I0VAF>yBDzIPs_ZQ-GxcpMzB(nr~n4PrU7WCKW+`0mRFPZCLCVpc}krF zqnXz9O9+l+Dh&t?8i-#&omN6bX2}tp7#j_+pW*)Cs~W+CxAfk#;OX165Dbf_|8C+0 zz7aD%xO@&l5*xxqFxx;xA`^6dgZvXTBmM~v$^IW* z;1qb7M{F%0c&wzFHHI7K>Sa6alDIz+_9Z^uvLh=}Yf6aoqk3|e*`;yY;#R!k`07F? zQ}&f#v@b$Gz_I;0xeiV0zpv#G5&W8l;cNpbytovCj%vM};>18XEdIM#>lbeqcX{Qz zcC;oirb3pFPKLYX@()?{$N8DEm&t?mK#Y+H*q%dazT|aPz;LdrLg@}+pS4Y#b$Do_ zdbPox2Og8iWrhLi7Ci9iaFj4u(u)AFq%F(xtn^FRV40nLVb_QTH{!?%Wy@yvdCf^G zBt;-)Ga8=Wuq*LahM2vY?xRC|r(bwDxJz_^(8`yKNZv&aBmw`u1HdOP;I;#q@kovw zk;!JmM!N4!vF>D=mWapI^Sg^x+@Sn5U=Y^^^uadAYce`b&dM(a0iuElh52!r^erv8 z9jLD$oVU3fj;75$`;|BZM7VM@)e^{Ehy($iz8eniPdCKdqSQW<2UQy4G+w+2?O+^I(VgVu-vH?t1wWVZ;oV&6~5}yVtR=7_(#5S zw%Usj^}B2+0YSDWkVD!9j4U6dVXD)|h8VMQHcCs7Bv5 z9|PsPlF8}zxGc>zu*6#dLQ+o?g;j*uG;58=2&Bhh%9)DvOQhbfhzb$&dw|h2GSCC& zECjp*%xs%CKZ?Cr2@Clm)0#;M3vZ;rOB?6_Vd0!)<%1SJw;1cF?!GmCE)SWw0Y6)+ioWy(+?X~t{MDbC z@HR!EPd^hDqui+dd4NrC@LMv%`&mILh?ZZNuj!B$A?Oa7A(AmZ(8WQPx0NrEs!D<6 z@5u7w7NoEke$FJ&oKQ)_It?GAOr-m}mO|y#Ue%12tsaY(B;ZPoNi>kSz4o&{JBh;z z=gBkO@aAjWO!w&+^ND&&*H2b~Dh#x{IDc$zYzJ;W(slqRBEbchRsY$m%G>5C>&X(4+Jl9}(*4PdrqBp0N`>1xRWtm< z&bq&xPCxMj&xAw8ZR#+=vp>!h(^RnYquu>^n1% zzw)r>`D|DoyVfa8N+x@i?j$7 z$zU#FS?E`>8+X^Q5vTOUiR{NE= z?2lc<)(}c@arJ}oew^zFRBe@9T&7wrcoNR}>EyxMAVDtq<#h(!VUrVY;~9M}K}C;m zcZR2S1aDwidnR3X+$#ytencMaV4}itc^D}&!!dvPmv!F{{N|DNY*3G+J0(6YtT`g*#CiQYq!E($J6x%dI*1S;2Jz+@MlVkvK z5EB*kx#BWP05>S#rOc1-h$!)9_x@6VS`1@mVme@ z_H!^gN{W(%nBvcnU`85UP5{5~+J#YqoI;WSNaPW;dPcR;9+mQyMt(`T2^xd5Q#3&A z9App{g;p>l$A0vXf*tkdQ9bU!Qmm6)>FnQpVP4(mnRT1OLo0meHGk~bcv&*A`!cxO1bwvig8iv*Ta&l(P%Y7SmIH2m^@%_ ze*}BmeZ~I55repSfmt~VC4!va=iG{ z;pEvjvhyeRIVo3*OtkthzJCB&5dD$~Ldq~&4%U1fqig@E#Q!$=n=eY8;}f;r%hG~d z*{l7&c$5ibRgBo(G4W)FS4$Pn6|1YnyeA5PO{@Ef9XZaEj?rK)uj+8z@7*?>!b;EL ztj3br&RFpzg`EZv^OLT|BRB8Pq#rxium+rMB|Q5OY>5_mzpKpTs)okTfP z6m@sLk?8ttuYKMr51o2Y4TMeA=bKm<^-|z|I(OzTY6cFaLRaQ}6)C_mO$zu$?(s}F zyYYhAj$1X^o~f5CQbM4!95r3fP}YMr8OLkGu_t3eAzDf2<&aLfBRo z<84e#4CjY2^iO^fR+r}nyF<&epM0LjVSOm}ng#f8JdFKM{yo*`SK!7@ zLjPF}Bm|If<{1b+FoWsv#eHcmo)~Zjv{IRT(<$#-X8mBTcUP<+Qs)+_R=v=xx1m9d z8mnqpCjk7EBMehg8l*BrxhAZEsnNtWI8`8lo^<;Y;tzY0EDZ$YyZ^pM2wuDy{s78A z%K}Jks-_FhH>n2S&(M9g+vxLVIlz4tIH53RA|IXYmhQf6l`6v*2#fEdc}~B^lNVd2 z-+iWg4Fo3Wf8;6rkuTfg>m|ggkL@oj&wg3v?eze60>;wm%2jK%5;aPoerO&vdtpKG|nDR!_Lqth%Mkn)A_UnL6 zL^}n-v0$!Z>y0jekq~TW0|bsb75NC2_0N~QlP=!>EtrczoRUOkVOaVJ16tUZe6AdK zZrckhA8e<}I<*4$5TR&1B012lyPIlp%aHpFqBh1at9Sr+42S!Gl!-uFE9LX(PB<_= zSiU`9>;@zGIKZHcUq3+x=0KAvhG+v}s_RIuSFh+g&F55pa|eFSh`6>l0g6n)+&5|4 z)$IBjn-e8ux$?<|lWSm3!bpXYl=N9VKp!R(KPI;&D4+jz5RHE|keemJ3a=^z)mlia zrod}tN(6kv$%CmO^hLwcSQ+sfH@$HGug%PVioGOGRMv$I-)aL&WK(@>5Ot?@IA!x` zZvl^{7e>2&Bt>Spy@|w}Bw}4?6chhVB9GVRz8U(v;-$-9KmJcw@@+1yrfShgLi6_2 zr3?&z;Z%8}$4$uou!w2p@|DXuL%AJ9z~KbZ%whXChSh9sXDYwF{3Ab6=r4aioaoQ} z;APvA#J7iVn+_c20Z#q@jC?b;ec_i1DRB-GW_f zxxXLwJtL2x5EM0}z&eEYyhr$?6d)c+yw>S~B_*?ApzGBYk&b9ulnx?cYUr$Xyqy5m zaNDppAvin#7j*j&#saquC-?x~()1)5s8)Ddf%40|`;JYw1}Vdn13jhgplgan-{|D4 z=8t&wAefw`ACgIN2h! zxTi`TA#thap#lKHe;#ji2is*64A}|>J!86O&xRaqz&X*C-o(SGM<^N-mHCUA^U`~` zQvvux4*qMJ|NgcMYQ#o58=4))0@$0V2nRAST9JL}O_8nSX#TYe0K1;FfxfY$>Eu{z zWO%qlfl3aWFq%^usImb!SP}UTqPBLc00CN9uhT;%^<2La8Lhf^%hxL5TA(_CVXk2XGP02zzSn%b_Y0ebCRz27+wB#$cw}-& zG?ijIZbqbJN;jp?$>`TXxy>_6vM{n4G7yLqO1x-}@LjP_YP0c%o|*7FhD zax;B_gjMhKy;B?nhCX`G6w)ZSxTVG6Qx6zd`=}W{;P$Jitw9HA2_UJXfu6R_<*~`` zObr&e>YhXK0DuF<5fDTEh&WqMbsSm2I5%trisj~w)Y`F)^x`bq~XpxC3ORT z5_G-R9tK0QNI~et>DZSVUYI{TU(hA#DjXAzx3$iJnV&nmsWl&X8u!H=pS>xM1Mr*S zY6e-k!Ls61r3bg4)=+AL(&@r`^RaxEFT7U4H^ zl*110r=yLU`b{&p*kV>_Ze|*gLgG)&T(AYgVq%Gy+oWKG@6;?O$?3UVrYz=k30d7r za>8)dp1sx4S$SRb(?Kx;?!mk;_vGVcLV4m_jD?H~$}b|La|Qhs*SJ~da?KS^lX`id za@r=bT10Ce6)x+v@t^F0@BVo5?HrQMt8?4hc&5wMC;J8iE|G8e`?QY*kBC*Ne1(=- zqlyrzs_b9kCa?u9G?%&~WQo(K*r21uo{qZx)4do6?>s}NE@^QVyxF64E|f4b9*mKw zK@=2CkXxE3W$?(OcGuPMjoG3>1Pw$zAdbT8KHHCJSm-GKz5U-m3OD74xJ{?~Qu!)J zAKiIO@i3u1d46SfmoB~lT( z`atahI8x0nT{9EZOW~)IAQ2m{5IGJjQp|W6@Hy&M!bMEanln^s9rzMn0K>I$vU`yB zs@`YIA9&M-$Y?oDe z_lI5r&rnHkWYj1}p`n@N_4DH<3xM=T4Nm|8qlC0H`up)h)JwO7OY;CTPmtAeZeKCk zKNS!lMc`kca^V2Vvc_L!=A&7Bo;UScxw*O`A%rZ*4G}Y}U|483ux#RVJ~VhtA@KY6 zD#us@07AhKPau~52(~sb`M|xXejcM|4t&YJf4(fNaL0>IsZafo!_?yqw7_J6p4K=W zp=phD^!7nzZL7S3l@)(C&IXAE-gDF*%;nzTjlQ{Sy0kr=QQw`Z!UBncxO2MA$@U#u zy2Uj)K$lH}S_wq1iL<*S+i>;SUxmMqF7QyvH$>NKOoPkh8+M%bna6-l46MB_V?Xoq z*cl5+mVnJ9lS~1SjXPFw1!rhRhgoTZ@9jE812=!_emDZeQKk=L9?uCIC9BI8jK^$mo zY=KG~QCr%r)({CW{|sbAi}s3TV_|Q8AsVby&11JVGLhz{oMXr@@7YTAUQ^M{~+55w{E?Cf|$kYntlxG zB4Qu8GiZ(oq_qjyB~hMlS!aeAr(OcQNUh5UT&re$5sV67@-2}-@8Qh3_-*^5=d}Vx zK!@qyKSN+9mDNZm4j_mojq97WR|27!I1J=-?S2>pQQT&4)bf>(CJ_nb-t74BF)wJP z2pSLF=qCu92{j#E8$2l_w!Mu_3feRW{E2FzGvj2-+)awfRlq;E zp+vtS00H^ugK^kvd;(9-(U~(tbiRV=<2!nCp%ZVUrKQznzj&Z?ErUixCRdR&3|;{q zWrf>fS1pc37j!|>T5TxpJ(K*8Vnx(iQ@HNzf0zCGu}d?)w|J$nbNJ`8rtSU>ztCh0 zw}6v7r9T$*%{()H{IRv%la>1ScPx^x#@Xcnw-|Y2ltC`lGXl;qZ;8s!R$TK`3yJ0`68=- zXuy6a_op}3GZC&OyBVk%%8|5c7L&)2u(YceSK&!tDDZix92Dpu%3kk3w7Kk4 zmrjU5t2xkYB?7{V5=R^SuQ z^yP($)Xkh$v9!Rf9sLL>dVh0@0jyiBhvDvm<%Q{N7%axtWMHj~!((We z&tZ-D>U`VB>H6%|p8*yv*T^)!aQ4<~RC^*eW#nWa=luH7SpAcq^54K6&e#w$Ri&EB z5YS%)sFH?*yy(M}w_6Jzm&&ns`p9;$AqH#18T#{HYp;pEM3OSZ1jG7Hw(lBmT!plRNt;y<@U;_pve^}evRrn6^c`vd1@s^bHazo)WiOJ=%mzvQ$F%mxVp`Rd$ZF)SuWpEVs_V-@K4TdT(X$0SWGe7(QX(~=g*x>%ubc6hv$%Tm z?LgX<+Xy#bDFgvdhr-JEceGl%4z90OKJE1b*D@~ zMK$kD!D_8#Xb?Q%nQlmi=M@I%C7h*rX*@6X`)67&Ajm=-lIp*HP?t5oT->~#S{p9t z6aVT-A$qL(2hF8qqS@6*fgglzWoj<4)3P4 zC>5u4X}|BMrEfi$ZY0|;vlB_*8zEU`jQDvV=Os4(7B{Q=FZ=3G0c`56o`e#(&-9{~ zuYxvj0i7e)wqj_a71`x^&--Zedt<5R?+?rSd9`Flc>yao2)-7dsMk(bc4F)Ld$g~H zb>#MxNU7A4U;e^?OO~)zwc*7Kf-5)`{oL$d zO~Ypjta&Xg?-m+a=YPka0al%NcDC0u{f00GFSfQwtQO6I)Nqj!;#}!W+N8VFjlQ~z zY$-LibgRYQXLa0|Y7&zF;{uos8w^EO9rkCTPMw~=`E(Nf+j=(l;kJ;{q{-0!jn!3F zX}lk-P3+*bk4U~#@++nWsAfFTP(zhEgIa-En983F%FMos3!@|vC!~bC?}T3Wr@XWw zQePc!-)>&GOT`tzhxSclsxLn+Si@@^7DP!0j%7LOg?qG&ZdOEM;{p%CYg1X9`H?ciln;OY&l*Smy?Y7i8Iq8AO(q)S%ix@y|p3FK<2%^Sr27o~YO z%Ihe}Ene>2Hi24;H+#56=0_vK^sr*g)z=4lFf<$HS~u1_FXBh8eLCT~3UCo-)!fIx z>-rm|r<~&}x{w5QYAgNyf2RiW`Ue>KGHxra?{)hr0GY5Cjl*J$zDLXiQrsi9UM=C# zqE~@@OkxJcvTSS8nnpin13ur<^KO$76Va{F)j5Fwy$Pnh$}RJ`ow0e|97(YO&mn*_ z)b&*>H#%CKYUSuO+@DDr4}S#R@{tG+{MTYYfUjcJ^U%iS4@KUzMqy|E2en%aYkPR@#TPqlk-+i;_rS`u8%I}&sH&T z6{odFL(roT4a;Jk29=uF#1#NQmceDu%)Ow!UufB-q;(ilLdZ{JYkQm-p5Yty8q?eV z&}T>j!BOYnRPpX?E!qA4?v~STt!K8455NeYI%4BPjFSNNuxIrQmzd)LaBEkYOapTs z-dad|o~vW1&(v9$jh&;3Mazh|omuuj9@ps1n6TAEVf_iXT}Qo}?~I}aos#;hkEg>} zoDbR|n3^@P@n}J_XY_jCgGy%W^1a;FGINPv7(d5cQ&iruFnkQ*oBRHWfJre!Ts+#4 z&*Kl_OX8O}PVo(7*$qV=ycgqbXh%Kyb2J-$M*(7 z_!ese$yo6)=@h)6B{6XttG6$MUt43pzH`4!8|o%tid-FUVPF06^Y+5B%|Wes(xs0Z zGWM8sL4SHuoWW3!lZfY|R%Gk>ZHc>Fi>GkBVk_^XmCm90c;Y{Y(PGYCbJDvD zjdHeQ&LLl=_)O{5AUwW-xS!EYpPTZ2)afo2Zj9^6(~5mU%wr?|{&5GdLjLjlbKb-L z11y`fdsODOtL>Vif|lS#>!vxTPe`deZeipE>P_ah>iSiG|FBwTcKXr@G|^NH4EZs?@=_`>dsjjl~gGABz zIIK7(QE0MTzo%}%dA8K*W^}f!xk|M-3jPp1^J~c=9sbeV!TrsXG5a3!c3}_aXzhqg3Y30&C)Bhf}r(MhXvJBT5doTS%V&6vJIxDfDC0k1x zr#6OdpC+tq!YUAlT%~E7w=i-O7cE;_{E80camye)R}iSIPV~y$DTrCoHP&9j&X1}k zcq-Tb=H4`BgVbzBgD1wM8MI{4K1J@$HE@H*RooXYoyP7y#_XxSM0Tn#&n>ceiaI1E zI~T;LT@I zsl;6_i%32@lhm<=@jG{6T-}dLOrR>1Rc^}Nck5f32-w^LO5j0X)`j{ zDOod?xxbe++ObdUFCV+S-R}g=%Gbb@Y&`w5adT8N<}~-nOSk@e&62n3?|%K77=Q8V zEt%boU-3g@#pPh8bR{2M#R<$>PA8Mw*yyFsh1N!VGR^J!%3Rw{C(Ui+6Q`xY(*Pm7 z_($2tmj_^!ixh|v4)^>srcmkGOjaML7XYwL)gaF*aZL|4g{7j5Jy>^~r+o=tdl$$1 zmlan?T+p~hSvQ|1yj>0DkUT?@2%^pkciV4x1l+eIKsk&r#m8!A6-6w&SUJi3!MXQ_ zIhnVkc6Yt^uW$wXI_PA*AGQZU3uY8X{()XX?<)RQ6v8G9+TpSTG_+3?r0G5xFRH;e zk2J+ODxH|Ycyj#;8Y3dF7v5n5E;Z*>mdOG*TbrZVvd>kj&6Vlt>Ay`R3M*Wa=Y%WX z2-z%s#wY8gw0cVxgP{uVxrqxSwD5-wS;~meO2@R~x{)}Jb;(2o;%AsF&cv_u*($c) zo{<4N=Z6sQp2QMd3o8M9c*9EMg22ybYNKwqZrcTUaX%DLRFCV-wb!gwUq)&dG+q8l z+5Y}c8&G?4O6~2^Zb9B%{G7h^y3h}XD|Gk(wCs8v@irN_xbT5PRP}F;z2;AGjt?SG zSiRZQWZX`M``KGU7MiaLQ!c)o79Fk>=_+Tx$9_!q96x9O=HP-J^5U^;oydfhj;~^u z{OeFDZI(ETssQQQ*qiSofzg93#yj0cF8`K0LI$>8fd@WyY8PHBC zvLdKs$cpmAq`aQXVwegDO+&1kCq&evXps|Gelf26+KSa3il9YKiD0jls=40p?#^av zp#KQDf0=Q~vfv>?YH?{U3cYML&LR;o;M-@@Q+b-;xH}WE33)hvB)Yno@)bBq_HJ%c z0mF$sx{WFB8Vc70g+Bb~>ValgbNi(+0rm;f{IPQAqzl%gK7($XRZW2kmM0lvNT z&8hCMqU)d`MC_$J$!jf4SfVa+Z$qY{a99FHd@j#eoZ~$dL?O`mN%-9ILlM1{>368S2RKX6Y`HX``&xsXdH30BE{R z4LP1m_mxjOCma_0>#mC$&M6f1Bul*YNVSpDK@n)Tv~AQ$kV zF$!3!n23Z4=DkT3z1Mqqc(C9F5q9Mu6`G?yy<CVBZ)QpDztgoqSt-T=`BeH%YUxDR;Yte^Y_MRC%X1H1Tlx5SP=fi~NM* z_(}TCS?VtZ60i9bcZ*5zqKZm+2iV}zb=Z?7+Id6BtzZz=Z?qW8R7!rk4nW)4uR5NH zvV0!Wqaj{#9FX%3EAhI>GNJGLtA!;HNH(b1dwN>?18R$*#zy-4^Oax<>(t9{(QcJZ zT1>c2Yj^A|vJ{YB>BTR?F7`_MTXrQ;pCT+H`aJ`M=wm;HUohP>rnIfpSzh(|a%=Hg zu-62A)g&ma7kHz2{daw_uCew%?ZNq=%9jXI2T*uw=vr?=ip|fp8i@M9v<-*EQ|~#m z^{P6dr0BrF(z(#}J2u?BwFMaM1UU7tBkZDty>Tc6@&iYNT~Cy*>uWzC3tQ>xKAf6~ zdbC&hi24Hx$vK$mlQqHNy1!Ri?4<)OtS2CoI*Pr0pFQ!hG>ko)HHvqV>{umspsq8N z2q>b--wy@z$y!$=g7h{6go-=D!l1}XoP_#*QXQ_Go|eSjM&Ez$&7GH!E% zrsO+l<6-J5hVh{CF4_qXdOLQP^1B9r%_P!cXPRg4B&gX}h>xzpY!8)gSg)8%uQ5v- zWpZADo5*bK>o?6&!}?rLdhci@&IH!YAiBW@qGu87>mn{Pw!JY7#N4J~_{}{n=5I4Y z(EW{XR620^TO`E!$KIU1%SjV5iVob1$>~x)3Q&@G`7q?G#0pym!5;K-mr;~X(~o`V zPeuCTqedl(sjY^)@qFcn+O?L-f8R_ztd&S7>CvfGiKg>hqcqYMUt*n(0Ijo9E`C%o z2qfzt9kpFu6sq;SFPxet0g`pcO?-ulC72tb_U`uvsyIS_EBs%r~QP(Kx$gd zvUmsCi$aOQlszJDkxs?dn+Lspqt&*33c^;Gru&-29Mxs`wbB$U;9{-}97q+AJB_b3 zUx~n#@(g2oD;&S?!$EGmHEb#9xx%M+aE^J_ zeV6h^JZsu~>_XZ7aKHX{c526KNKRN92PuGzFYc!V37k_3&mu*vWvpdMFlCZmSyiR8 z^3Azg2qnxpO!C7_(oLR0`*ft$`ljT@mY#&rt39`S!HjLnqHve7c&wl2F)X~1-aNc; zohp1Yv9apwcCNRhwP?22oY8z{EzC;GCHnQb`>w%s^}0v$&87p3?s1!Ci>GZb*4SCZ z*;szd{h9w?;6*=l+xPpcb;V7n_@u8jHHN76?5ijx`_pp#EMIhe;_5>hGNz@23rr!R+FMvv?xB1<1 zuTW2j(>B{mtUOpP1iyHsy(L$wlK-f&^U1chIY8?grw&$_8wic_{XP4*3v`VqH&=NR<2JFWvRkRdG za8O9sVF~e+58aIWNzs%a4Y6o6!Hqvq7?Y5UT7PQ-zAS86IP+6=`UeSmX|BD2RPN?l z`9AVY{7~cPoFB1`O?EQOa)q-i2OYM4N$hWpy_C}+slL3sI$!@8(fm!agp|wXk4lW>ZQrpc&WzNT?ny-F9)V(Z* zcjeb>;*mP-`K5$?-iRabteFzggI^yNo0Xu0W$#S0!ijG3~h4;A&VY4(! zmYR^*5u|IN3f_%Z@dpKuNqm?J^zW%W4!ygF8cdBo!>zuy!hib=Ks1c};n|DwH%1zu z!NChxi|g^?>nfNUl)qn@ht2_>x%Wd(nm;K@9Nqr>Y=X0aYjNs7riS4@@eWw(4vyI9 zLQ$7uL<7q-ZnS=LfL0hefJ=IvU1!dsU0dAe;Nv1{+w_@V zJ}5LyOX7Fq{q;c+|Eng!SMJ^}ZwLo64AUV8$b5BR>>cbOMhlYYn!yd<{x>C563Oyr zscLDdML}EkPRCbxU8@TLk5!#TynzdL?B<q-;n$KpLLb_)>TI@MO8sCL5BwiF6Js)V zaa^v|#hAxeRftIb49W0^P0=zbzcwYXq_UT5&&{REf13}H%LjtiURjiP18vB_g5|cb zy0x`N$9}xV&Z~RhPOB4U*T<6A@j@~59oi{LZe?)?3{NM_&D|kk;Mox@jDb(41Fdy( zLsvUHL7tdb>v*G|>XKx4d)D5d)^m5ZRnhgNSwGl2Yz4PU6pGT?W9K6>g@Zwx43{u- zaEA*M%-k^tAch37bznPYzbBZhZ$ZoMlEy2yKM)bf^PHi~K6KiDL@y>;ntHU`$G#u}p2}tR1&^Am=T}-E zcy7%%)XhYok-UBeOYvanUlx-xwi*6e>9T6-Vz(cwvOiXg{0n|wF+kC{=8c2fGwnYV zfv(;%bn}*S_u^}6@&OwOuSqH)AguHk;0?-?3d)$ur!JFZVsd>A+vF8p@Nn~(YoQWw zmcCk;)HLyTF`l8bd)Ybo6Okx^$k)5 zOZsFN^y^!jkoZhq&Gb4r*oga-#Gl)g_}dk6 z9^)7M>9pNzK%)unIXESIG z9_4g>^WTtgNe4Yb>%i)n_}svuOKtFjmSNz?fbyB1Mys72I<()Kt@o_0m33U}~l3d)qr^9a`h98RV8WoO7 zwfhsM@r0mBY}o_D$8+#iRVUAS4>^TyR1Rtz5&8oM$#^QS8|51R14g`sPJHus5F~Mt z`bn{YEF#WaSO^E5D5t$VY&S<~9cA74!0WBs=MQsyX26%TBCz5h&!+)>E;0-2`IF5u z{TJxH7e5L%8t@AZB%b@ka}YLDrRraYJYq$5F(~Xv+n14-|_p#_kHJ|GsYRip^kgQzE{jOYt4CGjXKuWza>qE18d?bxKN%7+i8`} z4uqu|^i7@G^iQ3BP)CW?5|0%(ODDi{cs$+ZBqSk?jcd#!CPp0pWUQ3fn7pn~M~Sat zfe()?BvGUnM| z!@=;qWa9hB$lUeVtdc>(GWHyI6uLO4PyR?;66UJ+j@Vg+PN|-M`DABtDbMsX)F7C+ za7IA*`p(^BBYNzbNL6af;hp}50TU9l%Nd(?g=CO=gdXzriYRTkMi2bAgr%WIK7NxF zuGUsnHG9iV#V3`vErv$L)hZut&z@lbK=3Mr;H8!jHWeBM5~YqPeiNc@dT_W5oRG|) zsW+u)TI`Gz%^<^2`m2Yr=rD7r-Fs@C{3EC*P52GzbrJp2f!Hr*@mO^|GR@NY>S*QS z+7CJ}8hSW1c-%6{i^OBKe4;iy^2a!+DF}>-T@43m3iRmR6rE4vv+XW^zw5o>QnMoQ zE3x5ezHa`LuSX4{#(ImQnbAhyDIGN3jhpLv`s#;Vak-dra`)eFSur)>0h~ti&kPcN zxOs_`S#rG8Cnbcff%y+LAr5Z4n4^{TB$*(dqVIqlUUxmlKj{C0u zEhToJrNG0{v95W}QMJVM1*40ynDwR6$0*`Lth@aa$?wN2`z3Rwjl?!CQe|M>e1hI} zJV;0gea%r2FczBN(w@Vm>YM%cS`NZsV-#@fh#o)7v-Wwup4gc+_uK z8R(kgS#`fHv39ude+kl{L~77t4O8TVl!Rl4ebCl%Fq~F{q+x8^d7`9YI5z2y!n)t8=CMWPue3=(mGwb zzu-!mnMep7rj7HDvIq}6`De#=e=(v2j-w2QzL<~Psl3fg_mF>lpMY2RHjN?Drubs$ zU++P$_;BrT)XuhHh5?B=@E(RHDve!A_+~rdmBdVuKl4RI2p=cfph7HD?jCAS4pKQ1 z@!w8@WQpf@z4Yn%mUKP8y}|lqbrONz#@EyMq$KkerU?@MFl0jL(c<0mfyHZu!kDOcS~m5I#9+OrVVyPeC$>m zzA)A4Jf(H+A@ZK!H_i!teMb7mtHya<`i)y|P%JVc<3UoWwOKvy&$O|ruQb)UB{>a#rRhnRlU6HDD+;mAZ!Z%^}C-dts|yr~!E@w^ZtjxN(s zO5eMUHSc2h!(mi29Olw(GgmLCGi%?V-h9IKcXjvQx!X%GX@W7-7fF$A{yCfLA(l4% zycBD61Bf8nIsg7O(HwN%o&dGiML|SOyH9rfo_GQ#!!Vv8bh4b^dVryO%9)TI6V2~1 z>Yd|ux(n#25p3(u+Cb0V7?dpK;kui{6es!-nkcs5OTymx+^Cb_1{p;eO#|?hW%%Ie zzauErB3-CuV*sB20CpzER_9;Q=q{m1DN#huuB=N;lip(mBp(u^wm6aN^SyX^P$KTf zWNJC8yB6YZ7xLV4ier)Ew>a6;4G{j0r<;GEvdSkeT)3auLTgV3XSQ%RBxLo=)wsg> z-E8iPKi?}lS|r?vhtS-XP)fVV5+*uwiu47SG#eucij4i4^10_wS&iH_$SUIBjy&max|Fq(0q*A(=zdKfv`0XBv*uZjbuC>8X~(g6A*I6=8qZh~yS4=Z|vAsMBeLqpJ2 z;%K*kkvnKxt~0Ep2;TM)k6pPuRK%BkiO_J8xcrL^m`!Q|5Y-Sd^b_NN#!q_7DF{ZJcozB%2pX1;n zt9P2s&EoZ^bwd^K&d2%pjpy`}N5iJtz%f!X7}A&PtM?) zx66MIXRf+gD}uI_Vnu1=XmL9ikdYWyA`y_UTMaw8M!KlTjiAc`3$5~x>#5F#O`23$ zzX=G2yBD=AZ+*jACrXJhZnbpp7p7$1%jWb*b`cdjgw>qlXwoj^A~L&;M5-Vc2?L~* z%(JJ`S1PGlsy1T}Q8fLSX0F!LBNHqe+e$o@Ii6FaaO$6Hau*J`y!-OTaW}T&Jgel=P3n>cCR(bkro+@(T}OTp6n?c^qr{r>9H@WFi5Qd_;vms#mI*Hy&?JZ1eK z#EFdMHpl8}ZftkXd#Z(l_7}9nTUQue+^a6BwNG0#j{bhI>2G_8y4v^Qd(3dObT6O( zP`QrDLfHCWkxlyo5+tVjb4?JKC_Fht<%$Ijq3oven<+iw2@mlwM)b*+$(H#vYwp@G z;AkowyUGz&S02$LYYrKqYeH-0;O{7bQ z(128X8m{Nlo1Pvm+Nt%SvBaoM3avU&)D+ngGiH?MvkUR^&t-xA#^|FErXFE0S1(CU zFYU~)lg|^#9{jf!K&!2{azm655#j8&B63su=$hT^YS7inBUN9 zHs?0Ll49b~)GrXCehyIPKYho1S@f)qJ9_r&S*q^6s0-q}(R6~_UN2v+#t9GCg(=h; zT==1{P^BQjLgClyjt1 z73AZ}cmoet9>VggN~>v}(=`7}WBTe-TZw!hmU)-&qDVd>!%HuWk`E>MO}qRFx-T5J zDFv@>u{RJAo^T~^S)Sn*=`i-r-Gj9u>bn#83p~fED^#}xu@|IYd^G+h2p*|NeYLauZUE^VZFD^#cTy zC0xaCZ)`h>@Q~0Z%Gp`yo|GXzF7jz3c6+d`o;9GEp|+Kz58uma)Z6;s20S7s#5D3$xu12OFVS+L&HkE98MgBVTpp&> zelEe#INP6Qci-QqpWnHXrbxd`c%y!nWm(fMfr`_cLE&q>{S9Zex9*jEokD-1l~>mz zQhHXMc{Us@4^icQd!4xBGGzFW+owK0DGVvDLi1tN@6)!?-SU~w{3}v?%U`(O5GLOA z7!O(A+F$&}Bb~7?EAH2#A67i;^4;@qd(-5yObr|pyLOAxtD)ET(8 z8R+BZn^S;OdSULfdj_-YTyX|{D$n)>0~rr)BySLGS%kHy_F83#Q@gG~3;KJ+AMi}^ zZ+=YXHUO=H=}Vh2?TBmk!rTwLRrw!B1iF}u>$t;9w-)Vw=#lPa;p75z3B|tHpP0Qt znueL|#5EtMpdBxnN_vzsVBmzH+-LHtkppFUa^a7pnzDP9{VhNf{$H|8&z?w|<7SIa1o>P({Jha&k0%m<`)s(fR?HVgyZZOA?xTjL)9|^!LyB0qHVsP~>Gao@ zGJ@~u?%IgEa5>*5hl6rahBaQ2@&N#Y5Kl`i_9ZaobEV_9CZ~M}K{?r)Oqq}(*CF{; z!dI7{n;&owm&aZkq?YLz<9gL*fRcbnqfthXSj0jkGG1?Wn)&pILsQ1k>ea(Y3@&4s zE{367<>bd=42`k_EFb$fzFOuaO(n0M9ekRmG>+&x%c{LA`}JtgAOUBrlQ9$HyPD-~ z(6yg-lyWYKPxO(?vFKAr6p z5R-3}cvfwop3g{5s^Z%^ZlCKY`daOyK6?5%(fRN0W=RG}Mr{{>ifHS^s4{(UJ`UWe zsi`GSmCU}>Fe!5Sl-u9`Ja-9^3vq|iOvGP6sSI@{Wut>AAnqL_{yB_X?|VEXVh}oB zw!wPBJBpZZe47LEO}r?`Hjm{&D}hGFdR~h#Jz_>Vw!XU0iXLWnAIA%{M4+NNyw)WQB|QtA znX59PiTDH9c1rW{MyqS)T^0BpZP-t3EMY%U!=eQ9R#nE5i3%6A&?NUZr!>FUXMG7F zzY8Q}`RGJUaDG!JQ-9uMAUsp8k(S6~z*hR^g#sA}S0~yn2C}JX$9wBmGR3l2i@AsT zM#3m?{0D^rJu~6#3D7jE#)bo?s;ux~X&5W3{t0f67kLLQ+TYBSZcGk+uCm>Mkz56h zGr~X)jsgfdqR1h|1)-~u%1D|BO#>7q=56`58iSTY`L{ko6+c|0FgXrxx&vr(db;~D z5v3d7E+W%kJ#Jjc_zsGopGSQYnUhp&l%s4Uq=xr1P6s90Q#B)CqM4phl)4~veBH~I z31`X-jSXRXTYQa~b}@mHp7AJ$oLu;`3j=_2`fh-sq5NhH9BNRTQlm&AqHVQ1+T{7t z!p%T{?{bBJ`QFj>KUr^lix5}Cs+2hT@DOrAO=7`H*tZNMN-L5_5cHf`hfiC^g9ZY?Lw`*gflr=AYNH{(VGQhGj;09$h6qBbQk6 z&eQ*DrQGNm5@e<%87|=WZ?(!0bZ~?IaiZc5$pP_IJ#Y!`(2g2C+ilCKorATqBGV==C#fGWc?vI!v9ebZuz>9Av>DS z@VDw1>Q-y~OJBZ_B#-I}Jwi5mNpLlM9U*b$um)gcn7g6j+O5Vw4Y zz-~xAAVtk1!Gc_FUC|u0E<$hklKVE;nLOv&+{ddYiZM#CI8mwT2<1!+!+Fq=hhAMI zF1?g&)68euW!vZ`@y5sBZsIF)x8d~Dzyg?Rn;VuSW#De8lv#7@45@J7hsb1&%&(u$ zJ=aKyhK#64k!7ZVkcn!K_oOjY8#5&MPFYgM<^Fr;9h1{3}HOk_rcb05oAq=Hhc;}0ltvb_D-NaukX`AEwsGixo}IodokGU-~o79ON^ zU=2`S-|v~-xSZgZ^qb&scdGIOj>j)pepZj&m=TNaR_ zd-3K+r*ir6APJI1c9#f^{hA1C==S`xriODh5t+9AwHDsjz&qKK{1$#M(mjyy-1>vV z_-;w=Zt8CCZ@zn^zFR1~QWI&%q3je~vSn(8S1*(Z=yI zeKu|jfHl3q-Qogv;~g6N6PJRvaWx4RWe&9h951s1&#!q@C6!w%IcI;`M3NZ-3J7svWMXAbW9~N#Ld>C8dARg zC_ye88KglE4~=KiU^);dY8VIo2K3+Aio}UhjxW!KR=vY;3U@6&VY|bhJh#ZuZ|9_| zv7C8^b4o@v?{Qj!3K>awakuRo_edSz|xrNaKZrj_E)^nOV#w@!-s*Yh8^ zYzHL8P>8bOQq$wtbHY*Q#f@C%C!z)FKcbS#CTg5p6dwzT>3=$-)fk$f@0R`fjZU&k zz^Q=s3%u(UB|EJ`vI6<1xAzF%B!;-c1-o>;UM_sB^gpzL>fvH(&gaveT)!2o$&k1 z0TFVM6%||C3X3pSCM>SakBiQ5xnv*&q$LDD=eKcFSY-(*I#F4RCkNtGDdFB`33X`7 z+J=OOCeZwp!gQH0XzBfZ^dM5Pu>bQ;CmT% z1q*&bYLsiW0sC@Z8-;?lXP(Wpvy?c@oJE zIGq9`jOuMS2x~nbJzIYSvwFc8+OE+nO2pybmZ-RKqOC}oq)0gY*+I4nOP>wFVre0!94t!DsKLzWzlTH@54jNxpIHJ?*=R$KO1So zd_!IK#d$s$r+*!|wVce_d#Lr?tZIBhWPo5<4@Fp<41kHLXzMMAfSW5z&XypSNQRz} zP(HQUzaYdIo1ypPbfNtDxolFAPg!4=AM?@N@Igx3l3d7ZmIcYKZ~HCx`kWy@RwJXG zXbSsZfwl%G5zr(VW_cW)AI^6>w|9#(J-wKWBAI|2CPngwphpl~2JX}2`bv>l3VrD; z?b-5kqYidOl+X7`hFQrEoP3y}|vFN@gwH}le|R@oTo>+I8+5)F1^ zX6N0DEJ?XfB3TS^xs8^WcPV=#R30KB;>FmR^eMF6Ag|UKwe(iMswwbT7hq0z*!&~0 zXYTY`vNm)3uXwD^ix2&65~#64CTwhZgQ(OK{5eA$7N6`Z1A9={w~pa2!(`&(lF4{f zoFp+dJ_>I62O^Q`obUk`$E>3Z#qo~$Cu&GcC1zSet2A^S#-}SX_sktdB;Sv(o*XGB z>G;KKy&|rkF)aFhSo*KXmtSUnoxRpzT67c3i0ZqmV7({!==Q98@1ILQ&ToL$LONw| z&3j@sl*lH(3TIfTsU%ch*yvQbce>-xt2Lf$#|Vaz(lmh`)CoB zk}0yUbCpd~$)kFgJ2tIBE?C!iJwDOy?Y_r9fNq6-*Snl>4=RzuP1JRgHV$mCAaHqj78g zo$5gfL6#QUyDn^3&>q4|RZ*mso0XDweuAdn@0enmhXF-b!a= z?aJoCk$FTz5Es$>XeKzg+#>OiDfs4WA zEOC(CDXMJnGHA=!{1K_yflN5_fLWXH4W$vD94dZjqU7$xZIgi?le9N$7be#(ugcEc z{ae)UO2$s@KBF5IZ`%-8%|wV;%-h5hHxS#1s-JW@hEIfa3L?;|w{6j-`i$Qc+zI02 znB)`P!n4M%H9<1W6C|cH=HW5cF86wgr#p(;4IU-%B}9o`FyzC_}qDK zIXEUc0eL-_oouoU>S9ejbB9yO%qE*hv=tWp(tIBeyzrCXc>cm3sn=+b?IK*B@Yy;I ztbPYhDrSVsA)8b$q9DAaw@ayo%5@e`ff@YN zxN~P(!;;h@3(^)=v~cf)ET`0|kt!2{y8Iof$+Ui6is_5S=9|;N*3~4k(pX*H7qLsU z!9@c!+;oFI)xU7)SRy)2_Cm~7f5qA`y;Jx#^&;1O+^J%@GWGp6CA*3G@Mn*!MS5C6 z?Yf<@Krhs3s@bWEf;VoXKPC;o8id~!Ue$a)#E4B?Tk!UkM?#V=nfhT&NAxqa52$SV zz1P+=+1cAUqO?RYlV8Y?8Yyg$#PYM&n0Y)|hS;@fOHCV@(|0enI<7y&V%Ys0doA0q zyVXZa68BM3HmE+?d52yKgDA%JRak`2WuJN@ZkO$pN;V>2jNSVQ)BMB5_3SV?-1* z#0a6)FJ#uZmS)}q9pxC!wr~4)q=JbHEXi>N-@4fv%XOTk@e5Q6lPoMcst?+N=TJ}*#b7#OD8$CPZD$5uhBF>{;JcWT(W}Qs z5~V}h9|@d2J4W52?pq6B3rEn2y+{?y^wJnyaB=Ve4x z))UNOv8bP=(EI^(o_cJnfo{v?W~F>qvEcqCDh4q2Rco9OJynYS{YI) z+j^xp=b+%Lo<+Y=%c}C<_(4=IVavT|AbDda68^l)ZGnF}>UOH?lL%xtXT!ybu2-}q zl#xQjW51_Z?jC4+LcEfnUgL+hP~6 z6r{rlw~c1oRz^lB?Ir^kb2|bbWl=(tpGBK>zd}wu4-w=lb93ALd*{UW!r5Ba8UR@k z3lF6z0<3zy#Zzc||AeDgZ?HhyYsL!hw$4BrxIj3==!2}WYne{tGxhTKFT(+K+d%-h z)hTm)-%oil7j#Woz00JU6F4=7=u@O6UYu-Q&-g8{Gk6)tFb05*m~dmaa~RY6Jhlej zq$+@tWl!4IP6qW1f8Xs(?0g_zu{#}m&3u|ciDAulQN|BIs&w6g03sl&P2OLCO|9BL zt^C0QuaMWVrQ#>kTpeM4tyrw%H(xJZ0zPFukl4&IQZG}&|MKvMfgD$NPfsrpCq-TXvH9KB(W7-Asz4aneIhUIV1AqcZ=& zWa-SW$BMW5)BtAoFau0jpGMyMD@l`h@(%97l_a=Cb876jmxDDS-2jSu_S}gQwTvaH z(%*CfkaD=t&PP0y>vu!#VVCiYUjG&n!*$O{I;w$NG&5-u@h4wLE=XgL4OalUg;Yc> z-|$P+c{l(8xE8jX76%JTH*lq<1TE;OAn1)vV%Vnk{)2bm3ofU8$oL)1jhXZR;K|S6 zSLZzu{#@&@Gob>|d7d02Sw{OS(&)4GVEL9b8^(f&tQW-E#s>>+KDDeYodxTzlAwg* z-V|5N(1y)2o8X&xrhG!9)%Q|>?z_C=pA8C(_K-2ui@BFc?_dk+3+tLT07NL5Wt$cO z!ecc|Ynt0tBFqZ1=vlhrL}ldH;L{_v@1W7B){WCpHQUuDHcJIJ22`n0I~gIl`$5>@Ow z)AoV&l}Z27d`qtJ@ka40Ckxi`vD!Cxch|Knx~Fl9X}3|0)}KYdgEgJ4 z+$J!l}zoi+lh8p%il(DY}Jr0SwB1f&T4X6Ub8+s24=7 z^vAyfs0Ae4Mk@e+BiClWxxn5MpEZ<}TN<>*5F9rZh;ELz3em|Vm??UHb=4FcN&k;nXK@$qh`4B>KVmET7?dk! zD3kB=MLwQ^E?BdXF}B};<#Mo(S+~ahdo|hnH|sjIfsCJ(y#s}CQya^6UeuM&KX%0G zpu*M3z`-?In760HQuDzkwEXbgaZh|xTZ%A=Wl|1^`*~k9E^+& zb(ruie(=WIxD*@4etg+#k$llrvM+({?jPGu8wB}CBG z_%CKZA!cAybI*IC0{|?!ppBuz^w*PDQ~Pl$%0fexXc}cQ>b@x0GZlO# zr)&nzZ+7vBs=?Wv5FETi2?D@UK}~Yr@`loa&mJSCVBE}P0T*A_SeqTa7GS)_c7yn8BCgm`#7)YqmqS$Z<2-$HfO-T}{saU=(nO^y~|3S74u0F-j`SEY`%R}(%KA-f)+nL3;*`18fujD2gt&VWr+vW-z zzo^UI^|c#YC0Y$qX{WY4-Z)=8wuqLhB_iw&m{IJw6%&a%@0KZzZT;1A|R;)r?bNu1(}KBN&a(M z+W%S|)H}PA*QCcCmOp-B`(ZNlJXOtpPg|f?RNt4Tk~!ed>Cf!s&r~k?sNwu3Uy>46 zvXR%lIHsXC=H_&Kp38iOkW|PbPSMlFtIEdJKJH|u+v8sED)f_hwPzaRGKypDNM~^G z?Zd9lUl-mxEEB@{5~Y#vr^!+tiiPaqAdwF#QP9$|UzjmxvOBv|*EnynCkx+55)VG5 zSK2ZlA-!+8KMd%zJDNDTtZ+EX9@+Tz;m>|bF^(bWpKyLuC!6?OcdMSNy5N|Eu3DmK zps1`~4qhKbv#!H3M>?3;Z4VVJv*7vPmx&k zyscqyTF>T2;Er>pJ;t;oJ=?${WE2NJc1_^iljFO ze^}bF^R^Wn{JV||jA2@!-i(I>c4+U+1MBjy$OzQPP1kDG1;LpDk!tTWU{MTj{=`|C_HO zG3UCT`iGA%Antqp7L#_3wcZSMUo0~{sLG26i1-Qs6h-KrJyU2;PY?VTxR~tMteo^? z%HKVkwjs%>Ko=J)%m6G2!f1MOg*b$TH2$IVkzVuw{rM=Ii~)Yw5s`yu0SsPvaE=Z&s5|@FZh}Z+CvO%iN(!$5JH+-WHhfEYG_M7^s5D+SCsGl#Sy@ z6#UP2DL>18-08Qch-Qk9>n#^?@?+}4qOZR--r_zZCDnXHA)MvMjl0&^ye8yo^vmsi zQMwkX#!~sH6NBen3*6-PTlmU1;&V9=Oqvqxn3JWs+Sbj?TA^_lUfeypeuc^aM~~p1 zjLksW zo?-Z|_29QCl!C$oqqG$j!$oM5FI^-sULT+Dn~}qjTjn1xl-NPjD16OG`5Gw_BNL;8 zSLjO!iDi7H)213wV^Twy8WC0~x~GZ>hm9=mFC@;$c?oTasy~RYMW-6-jLVxS|&A@=7!Dm#1I=ft`U!M=~cAcu0 z==?|+l#Gj#4tkgSmHX zj7hGuf<&%hXXV zjYU>*IFc%a#k;Nz0I@VcSw#+4q~%Pl$_Y1BJ*}}Oq%8Yt5ZawYfNBg+mP7VA0~7^) zp!G3FA)XE50a&NbNiW$^DEH`bGvQqr%IXqN*{A}Gjpx>6%L zH-c#8WI{dBf?@>v<1$)_rmqNRZ=4Q_{5u2=PmN2~8g? z@%-%aAy>3BKsmdYk?J4EAMJk}e;2*{rSa>6Im8Xn+Zn}YzqYag|Gb^fW2GaXGFNWY z?Uxh?xKwo0T-QjgFPAf9><9}p0Lb)K4_N7^mLs=?*7ciot{}9Zwdp}+1p)Fy`e8}@ zKna+lc&xcM1}ZXogs3HALh+d)IFrHpnMyQo!@T~f6?agh|5K=;KpxQKa@wMly5a4c z1^fw)Ai4-IdUTf;a|cCmWMvPdT{k<0Y1G^usoa%b75ALJToc19ipkfXuw2zm2Xs@U z5)RI;a8{=1$a8>UsjynM-#B0&FA6wLjKglw$)Eb2t2KdGqLm)@ z7HLUF$Q?K#=aYkdPP{vKU@?ER#_|k%78DuUM9{tpkGCU%Cd;GbbSxk!cAc{0oX z2UF!$+l^Uo`MhWR9F9^<&?_N!OtY|Py3^ABrR-TZj~Ialthll5IUGNDZis)!tVh^O zun1|5!=nuN2M-WHeXnvhShxQ<3C>zJlNC|`XPpW_{>Fma`(D6|U}tIG=7T)a;^{eF zjo7X!QkJP*Y05W+Kqehd!RmUn5(z3AXAlT0bO->J=2Ko6t_KV`oDxHIPgEzt-XSNtnSuWoW=5$OhtzIVTZRwfJtA1hic7Pth}htC(1Og*CsQfLA0Qk;nu#u zN!vB?c~%YNmGk2~izRqy>;aZB*Q{Fr>aA3DY;19CnECXI^3*2q{g$3{Yz1D{ z*UcfeI0U1#n7Eohp=hR>O+WOloASV2xK9Y@)dhe=(H|ZBsIf6Nz+@5$5w=zzj7qVGCm*_`dj` zGYC!%#Wt-%Tn}r_Ox6=otQRf^3xF?#TtJh;^TrnV`mfrJem#Zf$l`4RT%war`=wd> zJg(0dAAh{XGyy1Tb^tAzo}c!hWxV|;Bm_&>T?ypzcRzjt_#J}mn%=S|Ku`L#b=vuW zc!UFBX^Y3~M>fPMj+(PV{hou4L ze1H{)ZUJoXRoQ+k)emIc4hFv1FE903!yoNZ-7~t1t#DY59&c2c#ZDmSegZk@sg_s3 zBnZbJ2NOr?lIfRjh0&_l<)0wiz2BQT+G!`!9`qGT-EY?DdbGjhI@Cj8fl2wuKs#G$o-ANw?RFITNx3mfbgfkoCN*&UWM&3|00`x z+&j2r0!D^Y4$l+LR`)Es#j9rK|8IbOZyIW?o@fYT@Znvb&s)>9EW?h{$dq?*TS(n6 zZtSaJSY=~l{lH`S$PbQuTbI*RhZPy}(q$i{KG84$BDK$w+!=KUgw8y^U1>HH2Lh;k z=>cQS;lFR&{@4!*(U&%z>8PU2xh#i{WJv|fP6sg!C#rvZIt5S(9kbNL58d*r)3|8W z5mbP&nro~xt3eR|8xMjq??m;iFCzX-nYEN<(FnA_B^M>{w~iEj09dYXR4Z*862xP-H2V4jh0hCF=+xF4 zbC8Ij+*OeJlQ}JJQ(fFwpRZQgVt*M8e;t$0K}6^zSK98M{q>~K>O%-}x93GK$ zq79EgU$5)U&RId0iY6}15c*})9b+)u zy9>2djSi0@;2hupoAMN;Z%Y>D5A6zNwMwzwxSn$XA04Zg?4K(DpvMBr8^2jjl!*yn zZBS3v+2`F{EQbRaEIh|8QnM5)e+;51)m(Ww@NW)C!`jU{j`spIj@113r*0h^xVeJI z1KeBpgayW(adw$st()!F2e|-+g_^SBm>4j7QH*NeatiqjegGce(itfuIT$7w5ibl- z``n0wgVf^k)hSBU2@$y3`AWeW5l8lbd`1$CTomy;z_EmPzThoRKoV457+sBL#*D@* zBnKkR(8FPeYyhyrgg3e?_#Dshb!&@!Z+73Dx2XaG=UgeR*k zq5%Y&%-XNy?p=?pr%^oM3O9kz{+k16roc{eAjS$qC!muB37t`kFL~3zmm1y6w55rl zh6XG8e+(9sB;MsY?M}TXgMDXPM56}GHxOpH^@zzV%>o-jgE&za+1^#ak7z*r_YXC~ zM1?8-$7JY72=4Ok0OLo#%`NVi3@kDpMHC#06#j=;tPuIu7c9~&55z^R=XhWW^1-b7 z*3V1CiM-k{#Q`$fn3KRJ!^9W!fdtMOOd$k-$Uef!KS_tqD*@KgjJJXqu;~0l#U*T1 zEeepP0g=Km0UBTsATrgk?NscruB}&1wR2Kn)bUPHIRx&5dGG>jN&jP zRiKDt3EO#|L)FcsydU4vG+<$Bhe=VJze|X#VUotC>OK6-c8!jA4w2 z`%`qtOV0>6AQ@Zidi7O;2dxj~34ccMBZi@CRP|~}oi7Em_kmoMr9eMMMc#s#$Fx!HQdzJ#ti(?LL{o-AzTmsdJQ~=zYFrxn117` z0|YGq@>MEH2O4M62pQm_$^yI39cREL9}_rK(E#+Bxx61BYq9_&C-o_Rz^^E^RR|!{ z09wDYPL1_$=%auEjBdbA;{m4v2%5^m7Yh$T#vyrUrcSN-dQV`o#k1uJjNviIZYT#ZaNA9q#LI;~c@e|^wG-m@+&NsHq=`^Q1X<#J7kjsZO+sC*PRp0Gn*7(l zssW|t4RjpuFGGlXZ5Fm*^O;6`@vG@0CVUv^7X^v}+^wUa z*Gho#$b;KFBt~tjIFmkg=bKI)IoJRgFnZ{{&ax)kz9 zxCr$AOdz&~xIvq9N^Da7wNV)N&cL-EKE7Jm@*l zi#BtHs+*J_H1KDNVt2j$^M=Y|qLD*=Q23Hdjnz7>@XIw~V-ZkR+ z;k5}zh`K;aOkq%&*9KS@v8CVNemb66yg8PZUuZVz`q_Dh@_cRrpr||6GNY zfH6)$lfg2_lDV6?FgBWBb35H0Pv&cWUp(Qb z<$xM6!fO;#^8d*>0)cWYp2P=Fg}}rnmb)wEV5#79IePbMC7^PZ!PA^*;b}Sqh+wb0 zJKPKvvZrllrAAGl_M0=NI1ouyxs~x>VRYlg0l8vePNR-I%EW-gE{h){5|a7p=2Ped1OknR(T(&U z3fEI|R(kI;Xx%I+%shReb%VJ^yF)LBygBA77Z!9E=;d=qs3quhkUiNPmn{X#pw@S? zNfc5BBj1$B5{2BV!99!u(EQ}));mvuH@5{Q8}(_;G7>2TBBoQL(Z&I?Fb&3Oo6NCI zk8lp@U<%#8kW*^~=Ik;pQWb_|2Ywc#8}*;dGq6c{Kfor9d`%CH_F{$P7}Tgk?3@~& zKoSi5+0y>;D~G{%E++h!)wwx)l?Imwe4*d33a}k_~+VIyLTJioKEWp=Wqh>Gx^kMCk$%YXM2% z@W+BUwLq_-8p;4^mgsn7Ht8J{3Tg=rd7yfOM`8!ht`~@b)Xh92EBnN#j-DVfnF@y% zMt#rJOs;htjP3BpwfW~Bum$)>2(5e3Ug6N2sLh7e@dF`Y3P1wm)`C9P9IBibgMqKd zZR`=Ql>(!v=|L&h2U=ha?nJMSltNheAVm!)49@4B3MmfgC)5&LaM4|&z);d0FhhaA z7bpgvKEi~u1%NttTR=w{cwyn-^RtUXOMF>+@N`5j-O4T1OKqO4?lgQ{$ZAv=L&Fkr zWs@dC8rm>C;bb~+yueW-QmA#|KzD(3Mw%UJC^&RI(4?PIKnV%}`ZVtRPk!Qmb%XxZ znP>dqHH~{z;S+!dR_3V~w=4`D`~nR^XdckRIS|E_McbgXTq_=U%Igyu3qAD$PZ_-i z=ww@I!P8o#xG})v?ve(*+!+s>#=91*<>CU&`vQrJi|Y^jhp|EvOakuzANCV+OI&6p zcy@uBrxQ(6MznxV;giKm3m_8;U=-zk!Kl$*dC)#GI{$tQPSsQJ|Mo>O#5*7zUp?Jr z`hgzY0bQ7Z_fk2;DhwvoPgw;B(_s)NFE76=h$et^mhS(PJ^DY5AUQGk6{ML_ z=&!aN{S4^U=I0gmG`I}V2YsnKialW3_*?;%4Kxcz;Mv85>vN$K@TKUtxUdKKzzBiM z>g`WXf>0QU?nN+(JOs_@n61JL_P+}xIOs5-B-%EYzJGySbb#4o$e{i& z_Tc};%gO*ZuYDa*cI_KzUBFB~e+8oIYvC+^8eB;JpOS&o>jAyOKu}6R4h99GyiEUl zqz#Cf)xk^sV!>~`I~BYpM}p?s7QExDi*$Ed>RC`24(SneaAFpZ?|Q+S&dXFqAT5FY z^EdJZE6xtBX>gu7J-YEf0|(jl|C?^{E`xMgahh3+FJ!Y}E|Kp4as9BhnsoB<%dE=< zXmFVjQzzy&Jeg zaWfA1)zWrG=LVQOK_m_SL|}m__QIF>^dT2`Tu|IiwiOXUIFO}vDYN~sUF@HqIzxM0 z8NAXLt8jO7JS1wSfv)QbV%@Y7bdI?Nt$&uv1|MzuHu3g!jn|>CucI;2Ac2|+@-YttbrARwJ0-Q6hC0s=}42vPz9(y`&J z3!mqI&Kc*!`{}*Mtpj0mU2CqjX8-1#H$*JQ$5?u(u0=ZZ5Qgh>S_qZ>G>I8H)Y0xi z`U-?7{+*Lk7}_#}er5F-F%ShT-JR3G76V)O679x2w>aw-K&K47*%zMNbE03R98WhL z5j}Dhae7=4tRz$6x$+Om;F-77e`qtl&#M+*K9%>bub`37lr zkOd~BpTxC6>kkTrlQ%NUeZFzMS*$?@)A9#FGGB@b>n~lV#8r@c;WhUSss3{>VnLWO zM)+FB{M+77>c~CKDFtbt^EY8>cfgFi`dc7WMJoBvOuS_1?Ch3m&&>y`nP-gE_8@S0 z9$Q@;TGla7>2TQ)z88Mw-$(nO^&uz0f$la(*wFp=Wx#YL$8S9DC#4-5)v7(3JAw-6?)n>7s3xq^_7z_fgAicBB06Fz2<7{l-$svuW( zak>9o-b^NNhORt0GSF6E|Ig0a>2(L3|6@|v^`k{96+3(3>CFTuM@??b>D zx@lUcr6RSL0i^piJK^qK^nw>~$%oS8+=xZ5Dzujo5belFgMOaepi|KjWpxy{UTHEk z>U_Eo*ZvhbY!Y^#-*gNvnVI*l60k?or7Yk0WbuM z6~tw6R0I82sIw>ry}GP#=QRPUa~Kfy=K|+cTRAjBS2t(VwrKu)3#9qMfw9QGS`(3{ z2gUxnVe&B^H~@^izW10=Q2+>wu`RSL!I8Zsfr!z^;6B$9Mh^499u34Y$R?n5dr8S_ zN&>h77wopwGYY`k<6@1ld6DH;Nb%$!zzy8x{wIMKZtH4?1M&1Bdzbz{d`%yuNnm!L zn8OpZz6L0RiMlNVa;#k$;+wqUlM1iN)(omy!RyS3fati3qvKX#!QNA6h7q{zCuOCp z^lial1Yhb{cq&gA)n?He7eMzF20b@Yp5Ff0`bcMRY^HuYY9z;jcieC9_bRE4+*jDTE~?+Ih5f3#jbW>S>?~F3G8GF z-U+)EivOX3c^4ntWNN(s`NmT=z!O_c^yH`lO&0P1OWtcS1IFiK@PGkK5T8p3|p7^-yMqh-4|5=>2nCi1pq0cDfe*+YkYY1~IDevL;oh}d zz6(}ylZUwU#EEb8S1rM!ocheyh~}rN&3Pv*vZ{p{D?!7)g3!3Y8zCXAC*f$zcngiu z;qky?1wespGnQJ}cp8mhG!RJ4-Xn(2mJhLOdtZ(%ECiX!HnHE+f0PPd*1vcETAok@ z#j~gsCrYHGq|`UmI^}Iv!8xaV@<5iH-?9%OoNAfDyhsJ}+uMCrVsi&OG!sJD8U%wd zTn=45{C`XGld%8!K>&qG?YILV6N1kJQTXWr@_4+`YbFilW_tmG5^7gtAkYXR9qGtP zHW#-DFm843u#^uC0#?G1pNLEffiGNb0g^?Tl@SkPk?*ihSRis$^1|!AfKJ1!@Cx<- z*MOOE5tQcyC(331+UZh6?mZ-L8kA(-l*e3RRqan7hQcpM9W^WCzvkbkmxG`9;l|ZW>k{sYqIYyt zfz$Bo9Q9KGXX^wx$iO_ji$1R*yXA-P_5;!Z(U|Ew+R4^NfqfVE;%QU$GgzHG=uI=O=j< z8{?)0PA}-Zsr**I2K_Yg+iSA=Rc_eR7AfDCl4X!xOb7@M`K5Ms*nLg-m7m5-CHe=Q zMO5f<;oyq(QHZ$}-lE|D+>ilAdo`5j{S?C54RE}Xi3==AI)kd{;F!l;%(0QunoD3} z8=-e<2R>s^rNlz;IuORhLRZxtA8CKeLqjD1JLW`?4Ydr;4+)=R1hfN0bp-`% zstvvS&mTN+x;aA@ik*4z6Z*e}7WZvQtBcI|F`+PS_fA+aNr!LjkugK(c^iq*A39K9 z095>+H`!(lh+2p?vp4!jJe*)pLL?YJt(pSqw=8P22gW{rq^;PZS;l*PZAv+XNKY-9 z2$NS2A3%l_N-`URIrbh9@bM4H28eQ;J{No4p$@6#$P7-@yuJ3-J@wevv1yLIyRpHC zWP$RvREO69mB-C%j-^_Dsn@82JofcG{m^n$dHN2eb{y&2fXW7dh|)&!7X~fDkWIRU z_q!Gt2K13|FDblS{jNziki}bbJra=yWa7jMXn#utOpC)R$^Xx&X15g-90E6&a@d|l z0`AqJf$v%G6O7hNrx2_QlX(rcvPz87t2GOp!w#FHVS}LkrBz_r8-k7uf?v=L=y>&T z#x4xf?s`+Z1`uz8kl(R32>F%j17CDWcjPM%A)gEqpOGlmOOX`jLuU=Trg0W#D-EDk4b#1T;~wx9(^&`3ptSZ0y)wfV@?QS2vxmz$ooc$73PYr+W`#Zu z2IrGK__k9p+Rm}MrX@{3;o^x((qpd?T`vS3u`i55wV9daeR1$QqSAg9n1ZqttnW1>#)j^{V3lV<_m^qvA z@c`sl20>2{b_iw!;E3#9fUVdB?Iwt^yaD>?Cym8(rPpBF*U*&Mf`C{2z4hJa$cxT%ij9UpTKjN52fTWEEG;O&FG*lnLL&JQntlx4w`Oho|x#P)%`@MAd0~LCEXuB>c zeuEkBC1CEa?6COGeTsWFv4OWVg7Ra8wa`-3fB*;uL>J^Z)mV!ctwkNSI#-8-vN$f$ zOa&M%eJ5rdX8NKm(SL)Zbktye*R~=)pJ6aIqX`%s4KLYNKKk>66H2Fp7H!(7S0Gd3 zQ2M+Gd3=7IYm$ZuVTB6LW96E$m;}eU)!A80onPwoP_=t9hy!bg2{8d(m>qm~9Nne! z$i496US4jXoq?*G*FgO&$Tr&ec9N&bQpgmF!oh&-zZ_(@`ZI=XeHxicNTDdKua|Q4 z3_we97)$(2Sj=ofp`i-#;CQr@@$%H4TixtcSq(l4c8Z;%FpyadW;RfIXU1%@E#`@F zQo-6ob-7Q$4WedoHi3;f|np5 zGSg=k_&^?w_x&BjjmlUg3C!m^!EpbVFK(8%362!MXySKl2-jqhv0VW*romk=-U<59M+zo}E7a%1+2r_0?M_bdy>faV}WHAMK&DS1(I|LYV z2<>ax6GLG;4|AoOeBxUMro}70Xgk#F2NPB6g#Z__IJWMEr{)0^nC~x<<@=G6H~pmp z`K&FTZPK0GTH|@#$j7Sj!}QBJGyoJ}8;Z8NTX8StuKdQ{E5XX2`6D*{rndFKl_52p zP=P^tg4V3?q2>AC71#cY<7pxk5(D-g7P&ySv_bZ9LXCxVDY(05cMSSdcqGpb{`@fZ z|MD>+MTNIbM=jONWeuR<-vR2`32*{HPs0YKI7azza$jjY=NLds>MF569apFdvD-wv zz`)cc(ghY)BGrpVnJ8VpM?p&T7v+E^<D zE|!0AYNb$`e(^GOLeq;lGXU_a_2_Ij|}ix8!)hZDxO40!X2 zdwvQj0IowV;v~H~oWXf@Iua;H7qTYtx_h6p*AFn3?W5arq(**K0VtpTcf47h5y{$} z7wF{+H6xP7*pD3n=9a}QXqRLu8N{@v#mHXTnW;dSnpWIZd4TkIzsgB3CqqZy8f8Ui z4_X*yUhD*3y#*6xN}6zpBb^cZ(%HFd*7JV*YJv;F_UQ(5L>2VI53+b#wyOJ*hHREI zJm>p+a2z09Tk$Js-0{$I4&A6!@7&GC;5G`n&tg}gUd(+v7jG6dEf@j>lKJfMfb?4ME^PT_KM1 z%vg*H&5x#WesX7`5Fg0HSRuTKS$@T98ckDB?94=GA&pDtfgo!=p7#~S(IuA>@fF-Z zUFFiK_)ZELcTcE-{>*lHEz|Y9z}DOK>q+khrJrS)D_{WB2V3GL9ZPYU9^FVm`c`D& zjh#J2R4%4A3S(onN?{n^sfp5-LA~?C4AcS6#Aa)9>PvZ_bFh+zx|; zJhG{5Ni1EycR^no_Ch&Q*@op;skm={^rO6l+DckIt@A(k5L~$Nh&Q_a?%CQ5YmH>2 zW`k7>0*kkLA(h*qK(%cxfn(H(s&gOW6u zu;f#soS|-vNxs<%9VI~Cwh$uC#%^#%@}cLw%(U!`W>K9mW5ndNjP?I~=i)07YqEjN zz=hm{M1V3kvL#v~FO7MCYL>$_-QB|$V$|hjEv(cMd-Rc+h`&Sneh9v<(PHpEA46De zJ(%RF`Br>%ySwIwRKvixBO$-`w6?PjZhDu8wy%sthjkjFTXF@CKv`y4{vR8G_CSeM@zjBYcY>5fW#( zIhy4Y841urMn5Tx=PYAE$pb`!FELFlIKT~$D%$kW@B>Smuls^*xj zWF_+XXnj6$X7l;`GX!5!vm`24`=$)FPF#0Dl4@pbYKZU-e5ZBZ=kke-T5P&G|)JNR? zi9g0<@!b$Oz9es7@-+8-S?RH$rbpD1eFU-VAcjvIO9->pIGPwbI47upywo&j1iQBT6!vTZOid@Ptv53d28GcCUtDRN}HS0>bYb?|TRy?u%WRn@9>E!yOiX`9o{ zm!3=5x^AY+CbC{T3agLpm+j>X%_lKmn2zf$;n9dMGLctH&!WgzJr>Nr53KE0Usixvb6TND$X<^W6S|>t z``K^K!wWfQfq5|PgoRTlNLv1-{$5T#0MlyaJiuTFjUfhFlRz8s?W;<8w9ryfY~8PH z%a}Yp`2Aj|pGEZ~saY13Cj<_?8d@-lw2$CTnUxYF(+l)(p1Jyim|P-Jb@GFYqBXDh zDB-2HH&n*eobgV^g@1wGGPdH7AvMCXCa_q?ppR6m>||xT8)KM*L;6A{8}?L{5fsFv ziq7}F7PcnbS@ZBW`-7u$c}INjW)C;NztPZTdTZU$2!MA}ctCK53njFjYLH7D_pF_v zgOX_xSvFQ!*yN_v%kFe&Em`vtmm4Knz^ zFiT3;hSJzTJCj$wCI$q>23Ef@a|ZCGF6coM*7y)ie4Oe@fT4R>b~aP_6pV&FnG$eX zly2JngnPsD&C>`i4SIVzA1#e!ZdO@(tiA9_42~II(9T+B3yoo5`Hd9M$o>5o)f9et zATL?jGTh>e360O_^*$<4SYoJnY|?>Kcq}TKwcLZ6zvDB>=!NzD;CFxn!Mq`=)o8}s zQN%Ql>e78)dCk@`FvEgkH8mLFD8isQYC%6gAq6I3ra^`uF#V|yV-)nhdl_FrrK_Y| z2K2zBc$32N*&zp~y0F$}^g(&Yr4K-!zDf69O)2*EDWSEOhiB?K!YL`yFMnLb-()79aTAZS@D>X~m;R7jk7ErawrCo> z_RKe?YYI{iK3?`jg@Uf6-w-7Z4=WDtsxv;#zxPKUngks~D`BKAaj5ehGm?W|2b%n@ znuGH?XbSe$(92nYl-xh?92BMK_~@(707xj$*m3%nbcb8jtW?G0@F-T7N?ZTazbnx@ z0Jg~ZZ22nL&w>GfSO{N9iM#KENP0MOVHvLjOQ+T`2B74`g!b*_sc(#OeP$+NRYmw6 z$cTDuCHpAIq-STXcm*)1OQ+{8(^-afVe;0}w0+NU{sI)$Do%8udhyP&QDg3c@l!*7 z&Wnuv&KbY}ii>dcj$SHtaHo?y_bFUSz1FhsJ=c=^6?E(oDFuvX7BJ#cf9Fr%3HHZc zkR~Wsmjbg>2NJ?DSpJWm)b{x?r^J!06~MmebLt)0XTV{`{3A_q0mUKF&jkRwLveUxV zyGSq$1Hcpo;{OXGl?o-;ahVsN!VoEoU82$RFFxNfh$5M?3&I)m&ZVcxr90j^s5G`Q zx(z2R6UvolS^JqMHLw_>*6`v7oHKqe=q8=l3(%~QLij~`>aWoy#GU55d!vPqm_A0Q zfX>_o{@*^@Qb+33BcSR@+ggD6*Q&GC{TNMSu?mi!l`!%?@M#B*K+Iba_{h4mptw-? zoP)_Y`jMRZ`<(4$anEwX{BLE(`jS@{t|@|cNduL^{V8CQqA_Xl)OMCWj~6GA=#()P zBWs%k-UV7YIQxBNPn(DlECY%_$xX_kLw59z9;yJM!u6j7ppbOmK8(+5>2uWYu9$%G z+s$rUehO09&xYof$Q`io0FhmKY$KJ`_j{(b+G!{ zk!!{}5uA4dEN~D+YG&qqYn7?e24;*;#;K>;*1%Mvd~ml93&zj`R5s-_p-6#)ow=2G zxA>nwKU!Rg0sXR_bUJNNyrt6vl*JcUEy zZf2MBvn!&Pq!?KuNrvldHUerba_S$2^O3ttqlLx@>VeW@pSrBllg@3sVfEIhF=Q8n zoQ*6xP|uC6`Taa<5jVNp)M8xc_|!=#(4_n_Bx0p+)O6*I)MdiL)rsuo#U}45>R9U6 zvDBqbxrE>`I~XR`#5~#0rt(Ky{X%?a!<%^_#ai*QW*Cf8{Hxq9u(x(gv_g@g-?s<* zqbM$RXdDE&I1oEew*?uU_o*VYOz1D+d^rxP@9c?7$#0ymM@ihf@d&M^$N)av^_Deu z+?ENH##(e^lKCZnjG(q(3)VSBq};QcP~CQj$z?O;b4EwU;xD{dle&t+l5=AvvNQ}* zgl`=Gq@#YBI5hfJQg22Tv}zyVz;cMC!0^bGb_@Q(3;g)kmda7`a3Z#K;ZTotaXp8; zh3(d6f&XFwOq$&uy*24+XRGcq=*YNCIZkg;U=@hF5k#a{`!tMf%EFFCLTIiosSfiM zl2qc+3FWz4St`=21g9D?c1pU>15iP197rSlgrKJLLEHW}>yOf_5=kjv_4CivlK?Ywk66qIwv zA}L_t4RfT0N(^q z7weS}ADiGbPW-U_VJj%J`B#5a%VG2O9Ug*nN!Ra6Sfx{;N~k z^n+&|gJ0ULpUp3K5itu`duKFx{>eCRT1&nP1eF^@5)`Ohh1#Ep?VY(M*CDPuMm-=M z`D@N~M6jk8kDM?2dv^2@%b4~;hh40GncD|Z6S2D!`GJHqAvUy3QCn}kr`ks3DS8apv^hGy^VY7K6mtnougu_&FAD^7ReFIO1)!MuS_|x`&=e2~@F?x&Q z$RCqD$xIr8-5N9*5~(+|4#!5FO&VKs!mk@7gE{sFoT*_-gpujGEY-?*r6M&S$5M@S{J@l0^}0{!=JGr-6eWGM%W&U z9*NAtxH$0X+Ce9g%3`aPkPPxNb^NSvJgBgNsVP=dczH0`kpDv{`#v0@Scc4c;>awJ z9Y6CZ=O`PianDC~Cu(!~8-4}R5_YkDS#i=8m%*KVQm%OKD--6ycGDl0C*$Me%;Mq- zAo?DdPQfzHRg@T)^7NVEi+2<1W8-7_8JF*pSf4-NR;8$`bJx;0=5*I$6RZ;iUs)%m z6_*zanYtC1m-7o$t(VFsCX#4rYtO#_GvC%cnAw6K+jeuuHsG1H)y$%_BqN=#2T4K%8Vu_m=i<9bD!7hF5Q<~5XA@6qsF+Yi)9SLp>hCaSR(}g! z0KksA2$_5+uqaS}_F*MGoralB+_<{B##|D^V{pN6Si+&!ZF{b&ziLpwJnmBqox|T9 zW6lO;d8@FLX@x6$4qo9wY*AyQ7LUI#Z-fu>9?`LeU>?0`Qlmy9hhT7Bds>>ABwKXh z^0gVvV2&bMrQZtlI6+Czbf0rqezNCy)LH$~4mRBI3aha3;f$>eTsMB%UYk3refJ#5 zqUTAE#-4|e@jSLk3b%M^NdmRD@OpERV^?)=t%Mu#U&_^Kiu zz2zWI_BJ(7#OssiIxCe#uzFmCPL+SCjVTAlTyrLoj?&5UpomjWqMOT2}ski4nG%4-R|g<-U>G+IoMV zOXfV&rp>wqlff$t^?%$o7byJX zqz!d6>$08`k$U*@9ghhIm@SPZ@ceno_)*+Jg9FpiE`WKG1jZ1R#XJGzt@TY}<>%**3e)%d))VV^pAJp` z-HH)bwc{7yf3K0%KE_>P{H2Vl)lN$EJmHa6RUIg6JAV?sQ`cfyI}%IB!Lbt3wErt? zQsupiT_U^ZMZdz}r7wP5O3nN`vMbb!FYa~joz3o>Ur--@|K1Kt)K;M5$-7N8I`Q;^ z7Tpd5tJpyN-n}ode_Oysu9}LJu7!<$DF%0Z)VA6bfq_*Bch=c>i_>`cX{SI6RpfWE z*Xy!fH#q>@ubVH@VJ}`OqMxR$|+I@`MQ zGKuTmkH6>j2%I(_4nq-cP|Y0=3jU)4 z&Lg=c(HnZ0+GpMd>P(%b`8~BgcnJ=+BZhc8M!$1n&3Db8&vYQt)3Slidh>*Jq9p0f zhmI%xTIG}Ap0tvFxX`&Ko{OMx@P=*n_ntCm&6WL%_Be66bo11i21nD4?DRgK9|5#~f4wv$;HZtX_|Ng=+RRV@8sEmjy`K-Dp4jFU&N*mi@X3A^3wY4z$ zWu4I5{sG?E-XgGeQm1v@T7G+44^%R=G(F<7qL0-<59Ux>`A{8;gV4d==p1*r!l@N1 z!4dv*Azog4UlN?oUXyde6@0EWZaiOw44Rfy`lQXM*>mTQ)Gb`2Ej{zO;BvX|aN&`T zLJmtdI2RFpw)r&jEA%dil@TVrS`M%XSPc#pEP#la!t<-p8^t7xU z6klDS)=l;xWqaBMc=PwAoP$YR-GPG#NMtlwal-Q&WZKBcTUIr~3|;wmG?nf}Gd(hi zgD?NY32qAY(S{ty(ui%v?rMt4B+_v-DF6KNM(B>?R#Zn4ffNmEjnvs=Rt?{>?&f=6 z`E5FR{;qDlS;?ws&2UOfhXqXi4e^t>vg_ZRG5nL}6lS-gg@E-F(u3^m^WWIO=t<;z zBk6x!Chb~N%$FAJ81Xi|mtI<$r*aZq0G=Z$h3Vz^8$QGKr7I zv@}<;QQ`k|^rMZLro3O4*8P7I?I>@dPTsyr%Gx=9D|CaqDw9`TGvBv?$Hj4U$3h|< zMWEOOu_Qh^9##oUTW7E)htPg zt=a=A9CUCU?-W~*!L?Wcbyf#D_EE^8k>h|9`hobT?*moWr@(wNx1k{gs9L{awKul2a?~L;ZI)iq z<`i?VS(9hTxSlV(*64A&^5BhK0&xN(;3)Rsf*DP0z)|4xOw(h_4Huj5zucow8GrW+ z7on-tE-E;~zPS1-9hy80CCV}B{3;U?5~ik~8d)VG14Ihb0#sh%1<~UmG_jWo#|pgQ zbAD|E8mKZFSi>O~HxIUoY0Zt6;2{ibT#|H%H#>+EQo6Lc0@JBP}%nu@P+=a zyfZy}9KOl~jGjI4p{Rw|Od()rHt`z5E_P)SX8k_^0~sqE4L#8;hN;a-qjPAID!|MC ztJg!4M6Q4xBJZtfiko!`Bbj3bo^(nY8ZU9Dv5Va{<{lL{IJ_NW864u54!OC-xIJ4i zNVVg~%-h;7(dshMpZ5#-(|2H^n8UErCJMW3E2*RAeSV!?rRih5)4lA}R3pQBzm(D^ zb+*141s4wkyuSuS5%*VNy;lX~4y+eVVZvURj9?d^m{mS!gmGi954rz1kW~8_4O3j^2qKazqk(O$ zug|tAoHS_cDj6p{kK$WxrlPBS@k31DrLwzw-D%?RI{)uV0_=Ax=veQS0lme)iYD>@ zL+{ht=N2|_wPnuN;3&5sZdMcFJjf^ zikd(hI6$Fl|1)mjtfCY*MY zWr@Fwx6u+22y}31}a9h-=ky>o2;HPBMhQApcs~G<5&PF73lLN7fz4%0k zqmWG59}@t&xWU=srnSdphg~vr>QG8pw`lp^UCQ9mBe~&;-1Ayu z`%zRzihi;`ODcgG9ULLuNe3L3*aHQ}AC4>mf6}xVVZaqegE?S3p&V2S4;Lba-dwVJ zv^(7c-(Ms{2Q&er+$D#${1~Raf&ayXd}yi$Sy2zSgqzcYxy-%pZTy zg$wN24!CYBIn99Fq5?Xe&w43aTpG{MJb`36D#<-c?XJ7rb@J9NPD!{fFi!PZ>~b#& z{)9Kc@$_O_oWNDuF|zUOf4VZ(0Hkf1qB649v-i$D@Qb&{>0bF&D6a;r%U75 zC*w{6eSKA0YCYmJlX$idI%@AJsn}T$6qc2}ZJseIdMj2`R2J7fBL?*=Fsv_VHoDSL z(si%X(bZM5vI_h5?VC_h%gAd9%aI?LeVHLQ`<{e&B$j@;C9ZMXC`>vS>;obE*RC|K zNEQv-nW3;uqI4Fk+prxvUM^5L$%YE4#3 zPc`KqI>FM#z!Q1z122@i1(yDaZ{T257o9DguqpjbxKQvVx5aivxXXdHivM@MmvlEo z%QNYT!@*&lNOvAliPjS}Cz3a`WvQQwm|pN})e=FgtcOF+l*;=9=uFa{BozjlSpiSml6#_LS#gD?yL*^Z6hyaz~$a{M9)B6h~DNxzEBN zdHW$6AjL@ux%tRE7P@j#8NAf5AiCu{kJfxEf;j>x=w_lo%n7Ub#QVUe#T4-OiPd|X z0zufTF7k8Is{A@C#1h8Fg4F45FC87g84TDsS&(=ir)r3b(R1SI}<( zFtKEoU^h+80cmf@9%Z9z|B0T8B?;58>upkcVv_dae;0e*9{wE>O z!Aihu64BBv-56@Y(LWGBaJwG`zKD-h(>=nK3+KWzU>15}E9(8%l1PhT_iZwZ0%SJ4 zz?}+U>fOH7dSVV!Khb%2Yylik@O*k*SZjb%;{8KL@F8IERUo%3@Ue=geE)pqhtB|$ zcq|FgfnS4k&6;X*q^`h_N%UF~;c!4+4mG2RYw-X4>ty?Se+>Wk{ymenGZ(^|Ls4Fr*rci5})tKf5^IxK5I&c z(226p6orHORN%JrBkpx6{}Xei)K4fA?a?#TxcOWy45E4KF^4{XL+%rY#ZnIFM)@ zKaCEhw&nNJ20D0NSiRH&k*1f8xk4dA2SD{Dn{~tYYTRy&nSzzv3Gn1m)pVO4{s=_l@dZZ*>C( z#26ldKX`cU1D%2< zp8NoGCr}XDX zb>TYqEOm5rm_b~?IiZu`n)kS|0lP=U)u@1XmG5N>f^SM2U^LQ(x&PV_2GoJ0;>Ml2 zJVR#VSo6XzNq|?sP?fiG38e2*R#k4kGft?3&!tF8sd#B==@+=}K>^R?=TeRdJOaE2 zXy|m;yVhG9WG}X+LLZT+4jo53(W1|<7KXf!|Cry4$LxIbMleTa7EA|;v<8>!eqO#A z{5M1oKZyI+!NjOu4;SV#BrYwPf8v;UO^gRvw*&jvuV0E*R{4M+MGueqg;WjSw_MWe z!u^XnP?($kYbkP@PVO$0I=E&^zkhtLbSWzH3ab%BD7(3p2C#EG`{J0?8q&{u_KxDR zm0Mk?!7nQj^o@)N*A!R6HMJUx;OOuNj9*(k9Sy6@!?-|;cn<&^jy*_y@lOy!iHY>% z@Gp%UYmeS<|9e{_=RcDEycW)9h*d>T3*k6RNs+wTc-MM}BA|lxlR9zUQPyOcW>WA6 z7w9eW!(PuDI>%2O?(Xh)X$FU{pE88I)wGuR7YxtsZ}r}{?2BdK>%Nn%GQRPl#=q(x z3n8Ul;PzMa9HKbif*~RSrEwq-E(tW_X*4nrQeK{0HciK1Pg{jQ+=L@4<;(z9Hg{a{ zxmdzKS?L@E`fOdpqXA^s<*N)P%M-IcW#DXi^-Znw{Cg%gwvDDvM_;zgBkRM+c;-zSG3+{CteS4atFB-U6_ArXpQUH;$pvOx`jr? zwT#In`s#Q9VS;jHIzbcGhn@)E@4)qVK&|zkM@IrqR6fuf+NP+VvIOj$R5kjvX1PT}w-_S}hgW|<{ z`)TulYI)vHOuA9yDo9X)+wlTBAu&-2SVw#zwtl&-0Z}7Eyb56sekgt(Xf>^5l@fi* zpzhxlNeSG-&ed$33REkl`+!3Waawz@Y^5cD~bIqFb&s8QE~W zSi@0(_$Ywz-WZQzR?_ zdcVN}&&IQUB^kengDx>RWhz@-v4v)|Nz-A(^~oB;0blU~LC8OjTf=N(pGR1~DT;cv zePIS!W1SVSVa)oO0Dp(rbwco!plCt85rXqHwfo8xg zBu)_nHJp)(8E&?=&-}EP)yn|;ss@2burh!rTLJ9;U#RqS_h(ng^dq0dO0>y^P;7SS zCQ5g*pwCLhxD=%khx~_C?_!AvlsBE`lnqPzE=95Re2rf9tYayxHt)uP8V(PUB|<$O z#|<(v0;VdTx`5R5V8Hn{8>s5TKGw$t{!Aji6JPjx;FCU)x z`Q8LejvFLzY&kp*LeK_3ojgrgvST7!Jed>00YuoSnSnXie?Jpx^d;Z5_@W^MPX+Pb zPu@WgMP_f2`*@!KSib*r6p@21rNcD`0t1*BYyEF4Wu%j9kD#jsIrV?B0C>geet-LO z>2#z(lRW2Rj_)#wsi~CSAeFyzh3dFs1Fh%mtLPM{okJhH4hfEdz6Oowzo}1V>?-={ zE_X4tL7iV7A*yO&{4IL;j4kPk~hVu*R9MKBmUJ}<5c7jzXV{gYyd-43L_K)E~UVK^{2DBsaa;AqD3U53Ou31@o{ zgX}SV$HfY-{8hRC7=^~=e%4ho1(%ythRiA;Au&BYJyabBug7M+yFOc4CF8HLZ$Zr$slg1Ub8gQ66*Nvz`9i`|zOF{-^CfmfH<5_+QKL2~f)^UuTn%U*+w|DuCP zX)Pe^nG@3n09(kx#L8AdfeTwxQ`0ls2?p8l(86Ok66g|wn|N`D@98J_Xl(R+`gcQJ zEbTLA;^zYYq{AOQO?z})UX(_FtZtxkp=Xeyrsm>CHVf}OWyW7G-7VCrKMb8>Hv*QB55Wm z_GXJ`TQ;*Nd@eO8EjwC#S%y6cOT>4%o0z=4y`L#h-N3)kcfeDIzUvb*e&d?1pl>+qzOpE3<&L)erzCBdox(WU z;;i3ZU$dGt2S)1|VloB55FD%EdRi1Zqtj+kWZoOpsT-qqO=WLTk|#_0H)EGldrUpW z3$HFNRtEpcy^~D^*r(Hs;o%a2N@|xrhWM0}=a)lFl}A z!C<5BUS4(DznXH_VviJPvV8xD26GH$iw~x4RLtF4_7-eUpt=pL)t}_nJ`{OKWBeHM z602ioto4XsADL&A7yg|FtxE!z7AW8>pipbkP)+!U<-i0|xg!Ae3n1ZQK{3nRw=w}(7JyfM z2>3zD`@}wp!>G|IC*|(Lj?nzH0EW#t1zMOiepF!o7Q5(-<#EIjn)sm#S0i zfDvpoBj!7_UxE^J6`-Ce;kq-$Dzn8w?`82NYNshY7<-l8MT`mAA(>OTXI3%~9*-Il zfGu-d*Bs?b(8gD}x|i_!R?)g^TBf5t))f8X#M<7MLh~-0v73|dbj)x`!%d>b`9kx5 z9xYl>J;p&ADO;9bwc$I121ql~U7aYLf>Zi&^pRn<3z#7c7I`h#1_4$hPc}m$h*75D zW4n#}qWOem4Sx*kZTN{4N7Zg{0i0VSHr2X4Ihm=SvwtUJ zX1*KaJGwDMSo4M|H)ZqJ#a@ZyISUvkC@`tG0GP81$McekcH1YIpe7^}1c6KRd0kCa zWVz$6K49LvT`VFH+xTN1po=wueI=Db@uc?04b0p3201pi*gz$g;K$6oHuYIeejlXV zEm#wUvZ|*T`awKkfw3_DS5TgqBL?H7ft!HnwnGU!%|H3;3qP2>bH;tsno7t%xv40} zF#*6%wx8SJ7%xrW?h$(g6<-_32&@?C<;rMRCjE|XWwVvQF6wJLm=E7s46^h;Gb5Vr zXVVta9k7Wl8`;$q%L$b?bt)H!a13uzQtn2kN6A==kMiEx2Bj#~prA&nKs_T>#BT9t z?n|C{pb(N%)ZL;|`qa8OnpDVV^K!9)$$7l z{_STQa*+mAf9;0F3h(rMc0XdOA?0qc4VUt%FQ+@b;&FYSLqda(m-yIcBcIjm{qYJT zK()}=eh}!AgXF;I=;AO?@Tp%?mtx)wFXo~r_c%mtps$S$!*wq)i$3zTSplMf0Tm^=?Kh4((z$@I5w@TlOfuV|aU|iK- zfUHm64ZTV47EWS4Ze^=3@)It4zEwjN`Y4?*eAwyl?80UJ^tkG~sZm7C@Yv5UeN=Xu zRzT7I1-K`}%blxBjmx8kj+7KlN=LDl$bc$akPQ1!ZsIYWA3$b}O^?c$FBwbGFK=AJ z5g31BiPcq>9UaaA;l#WFsN`2p1TDYH^M?B8*=t}zjZjTip{{F9vi(eLe`o-x(KB{j zocfJwvUn}}L5W06<>gINko7c{${PTPdsP!kgHe_=x0I}&G#;w=Idpim&y(|;VzsKX zv_FyRjIQ1JaZqr{&dz@KBk|e-P2jVasz)h`{#96V!$(Ae&aaMH3gaVbdyUu-O$SiS zbm(mhRnhZJG3AhJiv*zn0P9Qr8CAp}79f`C^TmOz$fzzcis*&df8D7k4JO?STumU)DEG>)ykbaT+z!ZZ6?F zwXg%(;F7_$9lGclNBZM6P_hr&Fic2i4nvixtP?X zu7zSS7XotM@cvG#E`T2g{lYzQ-k`(FTvz33w*LY&#Vm)>vX!NqXg1{V17Q|*bMQ=# ziEa~sQ&a|Y^-ZjjN}jitYTP?~-Y0W|OhXD)J8d#so`p^0{_PRo?FP|8LeaeFVe=YL zbu}?k$p63S`tEov+du3`R*4isRz}%nOStVlGP5N!dnVbWD6^2v%HG*2(U84YsK}n# zd%fT5rhd=!yzl!@pF8EguIs$c^E;2@_(Em8A5?^1sPgnB0}ru5ip+pPBIuN(nGTIV z3z>Xf7}a=MtYOH6hAFh_9!Wr=dcpF-2n~k$@M7CdL3UShmhFQVwCo%l`3sWY?0B~9 zS1qriQwgFI75mtL{W|;amjuOOBy$GvYgUWFTGh$}GQ-Q2E{}`%Cittba(ASgOeceb zY{SxUaSH?Hw+{3vyG>|b=p{)@u)r*w))=S#t;xsE_9^U-ZU(T-IFE+%HzJBRaP*@9 zzFw{=6)+^!wEyJ%RdMC(OOhR&A7;3OVB@^gack)Rj-NfXEbaq&%6MM+&pU6b?i7g8 zBpOJz`HAi?g)c)25Ep0d1^`s1JyuT6ScK+`&;hoZGb8z#5jj&$B_e<>kl zLEAyDMZt+NrUm05rUGSOSlcTph2pUa?=F6Jf>n|e6Z6AkneG%pGVKJ{ULB?FjE|&y zi9s&il@Ow=?L)q9P0XWK?6Ws(#PkKJy!GH{W@l$B4!ORiHLx8HJgaO;d}SM|NJ{ta zq=}K`vG!1kMQel~TceM-1|fP@afUf$Gh$5`Ju^JW>vhwVWyC9$WRZ01?RUstaXQ%Bh$k0!nIN3Js|+KrVmm}T zn!k)-DU)*OUnbLc@JsNR$%=aV^!AJ{aG&FX5&nPrUaWyz983>*!6%@wZ|QCZH3g<) zuU?WQzLYvn9;tAwltd#qtqMso{iqGNyF4igyF297*F5uTl#E>C zM!{R>$wsKF+RkxQt*Qx*JffeO)h)4%#QS7l{ItWrXSI*HHG;(Lvfgj}QzjA1;Sw;RsUF0=oB)Kn9pMVIxim8Bs(a zb;hj-NWlv}*bvB1sfkri??1fY^a$@c4}ZLZX+VN;aBC8hcXC^Yv=Sj4^Rp!#HMNMW z03^*!!@mL@O6&*%r<_DvCz@4@AliMgPI&$b3aTd+9fq#otTGZ!L8W3Dejz?0B*<+2 z=Y9Jw2HOG-lGM@R3aQ@(Wz{=B7G^&4DT{U+c>!tOw!`^GQ%_n{$>~HZDT|hlN?zk` zKs0Sv8s4AhJ!{%=_3l7=P-RJk-R-YWuKLkjI`wR(?#j^)CVJGo{hBK zs@uhyc`Bv)vA&_S5v|qDG^litZiJ)@Vs5{Z=l6Qkh_s}k62OARqnbroK%@3jCGjwQ z`Ja1ZkV#pxVR?h4kwBV`gj}~_b_CPqm&x%{r>H56+Z_U1lbjI9Ayi`xXU*gde0G=2zeYf4e6^A-lq3B0#uAW%*pWh`qL-~L#e4Uq zS~9bV<~XJ&ze+&DL50VUjG$pEojbtNQp&=(qhHG#js?F}K=E!XEUCFUcYmd;^`0Vq zoO!bZe_H#aO)cA(N^LTOr02){I{^gFLz?_80d^#IR24!QAF+pd%*2tO>%b2=PUbai$0K1Y^7 zD^QMtmxONk1ytwzE;C=2#q1Ed;!-K3^lB!Zj^t7yF~iC2Kkb6wCj|<4SCvG>v^Tt% z&-~li9>bu-O6b=Z!OIkwFK5g&3Akj7s5OsPSp&!Cae4is(f#A`2~*Bz_RNADMAvi51sHIMX8RtT!BtdG3niX@1Rs1)G5lDRJiOd>a%y}f=*|*8 z(I^$oT$AP~P4((Fi%nQN8!%w8jqYj_v0)_oDfJN`agajBP-P77pQv_I9i+b$rV2#c z)OC?|F_sd<4eip;_56(2KlCPajOap&z>5 z?%w9=ffU7HN~daVdPfR7?iVJg_wsSBOT$nDpzLHiJ}JetW2{IxeGTK}o)3YJrLmM~ zipgUoEi*Io<4wRK-6tKv8w_R2 zp~m7tyHMH^h(RO(HF4qJ$AT6E)(LOe@iHbeDFA^-FjBTvp;3)jd!?(v6b}qD+A6=n z^7?~i$QphIaVN8zH?P}Lki%`?VX#dK;Ur12}{Sn2v+@4Pp@^k)n^s+flP+E4rm!mp=jN^s z3;|{NKDBbN%V+?XXrfdJQubZUK#e`QbMoe-Njk9BKX^_P$-1u`%^jg9n zpdzhW8*(e<4DJ_%#KFOL8bA05(qUhYm;Hsc&JmY~*dYdog_-#bfulftkOm+yzI{>H z=o2mToEl}bJ=gDMTcSkM3H`WR=tk^tG|E|Fpx=dHHGAmU;Y<5-HN<-Vgtc4x8m)Fl zHVBTH>1FkYMkl^+zmI|DdE2ppAGy99GOzU<9UU7VBn-sTwab9-W9V$xrE%pff& zBHT=0L)Jv=C(gpX5mr2XgT7Ji?EeZhk^dyC3OmT(_d*y7AByX#M9JBCWbi)rh&pNj zmAzIYD?P}2{#EgFo+Q$&G<$pg(@_GpHdbF_zABs%+$q=iu%hHd(D;q3Nx^w^_=)4_ zP)|<}uaM1Lb>fNS`O^u6351a<=Mo5iU8mt`9{BF69J|nEjIXfAFse!9`aidJ_=(69 z_S{FB+aBljkq=aQ9x)Z*LF>3*%a7a^!y^S8M~$poY(l>pPsuBqB;E}IJA!P1re(?2 zd;pD0HFe%jC`w2!!?`g~G#N1N;9aQLZoX6Dyzjg(BO>D@^5w2b$vF+H+3n8@hi43; zZPAmPYuJA2hK|Gc6 z_xJxUr(X)_-+9Y@+sNWDJO6Q*Cx}PFSlUxElRDZx$F;?7GX!8fu z1>@#zMZ!_C_6_RFX%@O*8^G{&jNY8ZdjH|fn_HtyIwhMzI>mMYxrXnQwF-2q_a+C{ ziX6Ml`zuT3%d|8B9k>?mQ@|$;s9$IR&;d|5Dmso?M<=c`O;1gF2NizbzBl5&Q%Cq&wid?`^XrWUnHvT_kPA51jX)E(3Iq-0#ug0pv%P@c5Ff zwcfZeRzkJ*!_}8kAEB{E{QfF|YxsA02j-E^an|w21*G--X$q#d`tL3eJ$MXc%~H9g z`F>#)H_F1tr<#YPu-AvAg60Kfx7UA1KdZFOm&|z66KZ8+OU*cd4xos5{J>71Em?Xk zdU);jjJOq2!a@r6smNVMh42xf?l9QTDEjM~A{96^l|VVMA{gP8vO zI~?tlS57&ei_>JwzcP#(A39e*lX@J>H*MqL@xs(%62?!Y$5AoT)2nl>T9^lw*bf;F zq?JBhEpf5RI7myA)72GHm$tP{?C$B6PwbXcvJHh#4P~~2sg>Ef**R-%>pC|f6-q5C z62EijPJDM_wE|7Q&!)-wz>Ma z!1U{E@mQKqTU2FbrAPSs^fWL6FEunYME-*cx!!5!qbxe1&1F-MQV;5Vjx;yKs%Ut&jC!sN>@74ra`T`T~dgyI1?hU$<3U-uvY({UtcHf(D zl&SxSGsjNjyOD2Ne12i=0{(?jh9otd3ve~lCRM1n#vZnitS;uc_(;rI#Z$*))caeCpnXs7q# z-1F5rm#x{?Dsg2Nrlzvc?N5W|ljE9{g+fP7L%T4xyqi{xPG^Sa3h6!T);ccd-ktR3 z$8|}xzT`muilW;Un_BK2g)FlpQ;&D2^Ts|3tH4ysE6CmUNPDSycp-hQ0c>f z?Y}|6G0c~UMX039_zbdRnZzj{Q(5x?GINg|g8YX;nCi@`s;b7>oE#i>olktKc7wh< zEqtCBy1zQd?B%f$xw=|X5ihhq_IkYL*ZqcpHA*1l;5Rh1M*Ud6OB#7CZheL=Zp|mT zF_5)2lB%fKbiK}~zHPlUW^M~%V`Ps2P~(bzYEy<@xqnTY^i7=4G8P0cMGVCyl=l%^!!bNFy21dI^y3% ziV_A=AwIP^89)Bg8Xk!N^!qOq}2GGmw;6gGYkq`AUoN8v&&8)zIcZDI_& z2g?mEcoNK{J}ULmFkZ=O&E|?QVZ%znduE~elBb|AGZ-CawD*qNw9nhi?AJ(|+VZ~s zS>@pG*b4(Hts-X6fMe4Ucw?V$%Si2Qsk}==inEHSv^STfujlGk-*P=Sx4u=ldOadj zSsOxPE=`iC^WYGf_|Nr4hz+5V)t7_v00%j;YG6U>)*H6bQ~_8isHs`P?fLV)TD_zQ zA3pI6tnz9hz^ON@D!I#Z_N6EV!Y8lWDpa*{_1W*A`YGWyRp=G;RI(gMax8V!j*nb^ zfBSe&Q`3MQXy4HrqI==*c_(i>`m?~Rh$Odfj)`Mj=+n-so0((1)+FB{9L_lK47={2 za2#jLW52IRy?}bTQQhZmsSW;7oAMtwet=iuO5edLOsMBWUx)TYP}D->FDdkViqKfM zRB5ntcfMzl{H>9TkpL)|R4h6riH>ewn=61tKDYSwuE{}_S@p{Rvy7yBQHjxv0H|C3 z`2F5;jj*FQiESDY} z!t01U{2+qAokHVMc!am}6$Myr>^#laEm{rFNkC)s(U6Ew`(i3nD#wnYPZ%aB z+RxtmwmrDXz|P9bU7S5dU|Mxgaae$e@b)zT=ZGL=%+F%48*q0o13XwA17iWPc=n0} za_20WKk`m~e(TggW6#SzJy>3_I@81YQfvP0{SOKEzMpx;FGB6TEu~Xp`j*)~Ir$XV zfuW|Rtv}1ozG=jT{l|M|wb{JL_B7pU@BLZ}93Z~82)dO> z4|XE?clBDhQ~UmB1J=PH|5fS7c8Yq|pDo(~n201qxPf~CNrg|i_YOn!vcurS-r1ty zr$pS9TmDa|g!q2hU&G$%5L-YVdjSrhyM;mnt~)@MYOQZI%Af)Pr7C8LmE<$7v<2rc zZhw8MUmavU>8Gcy95)V@i&Y}&-mS%kj>o61z9UIb*fsEoPxJmmcAox`^A2q~if^mv zRKL*&A8EdyhnS7I9nH00(G`?Sqkg=+rA0PdTsl>EqPJpaIYm{J&%3(6s@1)Fo&QBH zB{4-HlH3qs0tB4yylLel^xxc($b=FH>4*JsIXSaP?u+u)&TTI2vY&*xfDT-`8P+Yy$;F~4IcAp%((?&LkPfw*}nzzR;k;~;RUr+fIk-} z3?RW7*#8emFb7`qfqCTjje7Ovj~PbKiMhGB84C20#>U5iuv4Z`>aM2s@0pX z$J(Pgc${Tt0erV8+IJtbXH~g1?Wr0g?wO5dY2fAoimv^%Fcm_uK=Va2RjVP~xPnpo>o@cvAcTdlWRh^D^c4st}T4SQl zEb2lMgH&~oDI7SQ4!mhRpl}dFW)6Buv~?0w)hENE2I=}(5+N9BN?%q| zGc*L12m5^cL0|+mUX>xO53b&d)|_8^brqtF2P|fXSm5?b-=8<#>~c*GgHZIlKjl|c z#O1h;kb|mcai#%#t#nPc-B>7iC;+>}XGg$Er0%ZBY_0+*6|{(8%$!o9aG?}(%Z*D6 zp7#MeEkH@MSOB}_AdHHA!>}eUxC7V~_My#a+}8=r-n?qkG*{Ku$*+Bxow%tk zB1U2zP6 zYoNYeS3Q@kk6|&;Igw6fo5Luop@B{i2t~F&?XnpZ-w3@x2I-+mWR=tO>9nnt^<8idZ|9nz7 zkq{RL1t&HN-3}!Q77DG7cKL7o{w%jdk55(qWdVV{fF|e*cp8CbLrr@tr@;p`k>qmJ z2aq`%is6W~CuNV+wC-i9O|#gz-tX1tU1WWbXjZ;!U^*2c)>(eHAhlbG@jr3$KmPjV zV#-Srf?S~P2YW|$>yXmMaQT;Uf=da#yodJ`aVepEUZI+>%A;{N7`5)Lm+L};EUl3E zy%1~_yCI8puWdw+bzj2_?`(_8-T}dQyyjZ+F>Jz^!KTRbbnX*>MfLmaTe9;j*!GCr#>%d!=-uTLjPI&NrFrm zsSM0cH%RRkeK@cD9-a?CfY{}D=X@W^$>KOtwKYC2e>WFgyUBQA`(@|_D*I9@ zC6FCH0D}=!Ntau)j%xblCqB6$;nfcjqss`_&_Nwlt)H#XI1@|An;A95g<)6LGF$YY zEJ(Tr;n=-}_4sgRSo*1bP)HEk&VdB(ti3Px)BJy13udDBln`t!7xQRftDP&M<<*1= zN2pNg#bK!Ik?@~mKJM3x>=ZCEzV=v~Db4&6Qir7-Oa^H4qXOi#|8+6}IE>6SN0<@j zn#}C%N@6F~)EOZGu25&iw1WiLQ6iFy$kG6zrU2YwQ`(oX(UV()2i-HKMPY8|@&EY5 zBkb%O6#m~kJ>rmgc7=_MjI_V6X2^_MRu9LfB`SvXi!QgHYKjnuv{JMrDa7%L)(C3BKDoyr2J9>biwDxjN@|a;3 zTxsSu18s4qujCe~m2uq&i}&BJT!aX>aWBd;3t}5fgKx;jLeaj3`;3}Zvc;`nhOkUY zsS*Fhp*g^sZ^pgngIqAm5ju@r=FR634zA@DMo!Lx4}w^lYJyzdXa?Osl3$3p{T-?q zNVj039Vz8H0<{8wKD?zd9rd$7Ry@S)`!gICBE_z;PASluYv{mW<~&R_yo}*1KEEOc*`z5Dz#8%dq)I`RZq|MUwH1c%rU$M&t>uwAG2Pm;1ls4ELfoxZ+^dJ7$C1TYfi zvpY&NkwJYIM2wmM6~nT(vtcj((w+gqV%-C%v!bA~Frf3xE;!U+M8(8R^b4jzNUHzt zdd@Td!y|?J_884-;4W6m4tkgQ9oa&HFLLsiU|*fXymjBZHw8pya5wcJh^wv(?;S)U z|KCe5T}kl(7tQYkz1b$v$FfJT0hYd|2p`OLjd6HbqJTkh_?2U(v-N!#xmui+a%SK@gmHJ6|?vTH}k+f~`3- zGcyLroCwzZ3ULHLjLA+x-BFov&934X_SW8l59j<~Isf=Iv1owI7&tjQEBSkEF8+#& zjlDFWl5xRy1<>GnL&*RiAcrt-tLk@wErO?kc_c%tQUL-MiLP2+i(lt|ogAbjFW*BO zYuGmKSQYzUUw^%Nc>d7+HOTj@`}(EP9OIZ1?%oq~e}Wkqu!xhGm^W}O&r4V^b&xB# z7*s+H^lWGQJRqB60a-iHT=YsTM(B5i1O$rB3kfM9`+J}m7_Ddbw)TRyo*rvK)%pv4 zmkufOYOAjF2B4i-?Ef6-6m4nAT&^WEs?W+uVnGy4-uD;VyoRee>u21!46% zz&wvZkDYI4dIC$6hv;>2ie-)TY#%>91zN4W`4lUKT?e@~2<=H(Jnh(r##<92@C#nt z+$T@wKZtA};8|Q>uBY!TwrIolLbR=)kaJ5< zv?X&Q>aTknLqoei@v^5JDNI4;S7pzUV$mI7&f^Ha9uO0)bMZ+@)at5f06%mwP!V45 z)wAdIBWI^~>LNErAXUYu+HZ#oGr@#RTOy6EzUqCmnC;;2JiD*zrk=14*a?5dYqv}U z+?k7)s!Vv7PZwj@Pp=IF?w!XR565c1Qj&9OFe4m$c;USO5p())I9>r`j}*X>ekR3e zwa}CHcLPsq1a4{5b2i-IQA{d!q(et1=rq+psx44%o*@PW;0^SZF-aWbqun_Q7{UNj z<#HIV!LIWHzJ&RDH0YKd3_mx%W0>;l)h8?! zYL6*8m_P3JxcEWy^Q#hJf)mfNo5lsiND_O-7C#f(oBRq?bJUIVIJRQBzYB(Nhb-wlefwk|G!OfMrih8`Z^c+66Ywv!T7;cZ)!%MZE?1TH{l% z!()baC-{p1Vi(Wo{~k2=Cet{~{(sfjpLkQTVy>)gY^(Xi^3t?&n4X4_43^pOn6n@~ zvJX(8AMKqfl2|UmR6jxOdY4#skeTcdzb)3-~1vJsk^2YR}?Gjdz! zLjEt${0~Q60$nky_JT{`dEfhI8C6nWbC~L%hw2|HnCm6 z3EhwR|J{&rjxSlVO#guP0Fon1LL#**qxxWlMHSOd_{zl_E~JrQgQO5!dJiDuEl-$3 z`G3e*+<3d($U6S}-2z|J!PG>vX=kUSvT>^Y(1&FJ9Lo3Q8{F32wg5OZ5>w~^okKC6 zPw8+=LqC}RVrqe(Z?(w?T3mGzeRe6MgMFn@;E-5_Q0uh0{=>0*{I z86-OCNTNf1^00yCi&8xSvkA;95iWX)TckG zX%DDjL50$qAH;8^9d1m;Z3ndphp*LT~%B>Ls#6F#I1c0cNHq1Jm#a=bLDH$T(atSd#tI zsA8!c=3V}G?E))h;N?)z$Hc}qF~;g&RJpzss1F=hHQ`z)q?^3OpvxU&<`<+;X}HG!N6o;g4%A zRu?oni~xH{<}{O)(FldZ@%(qcqhRvFk3d--+!c7HxND^Bx(vYmDC}1$caPaeSlO1t z(y^NexmQsb?R;$qO62n2PEc&siSE-OoDzg&F!DqyQ$_aLVGxTthQ*VagWw8|c}S2Q zzI)sZUu}5fJ*VJ}Q{kZZ=ig}e-=gmJ|2J!7^P&tfqr~{&r4$T~(Pp&B7 z2m=+9>3vZh_5J7lYO5B`Vk88q??D{jsg^{$ex&ws%T?XqGd(#)&#N6G2=$E`EVTa(F6h$dw&mk*%WXC$t_6d|8Ja+Vlp7MIsFQIDpu z58rd|$-_Rht`BA>3U&j?`6N>5^Y5u$`jbirLYyUEQ77t9b(i&H4{V)Vc(hzWu@ zTwf0Yu=tKSh2Tu)>lbVfN3k?r%A$c>Qa@il#KCRR$|D9{A<>`B*E=ESW$LlIJh44n zz`t_`SNii+AY-`~144WlievZY-qejnYa3<}enfQVTSazk0M2h2K(0JOkZpO{e1CV# zyy4=WRw;ly%pM>z{p7rNG|nF9SK*p}ZPya_R)^5+CF~*^rIXHU2?SoTk zI0)<&BPsbaSLf=Hi!B4sSz`Nz8uttPFqS4nzZZe6C;ffgVb~4hXFU`&&}m47Cqx_# z{29`R3Bz~N!wlVZ$MYpp>@I!G5%KWw1TQoxOMTz+$udHgZ>C_T*g)iw%`hIZt9SNc_6OX;0K)ks4W#21Edi~j^N z@w*SB$h<*xkm7I~bl?gMopSoXe6Ho{+#hQ4-!HojUfM|+3%*KF_O+Z5gyEzZ<>t?T zcKZ0*&PAfvkcgfCIPfj;pI`Xrm;bte2sS@NhawyQ4{Jm{b0!%itY*gbJ_kz636_80sbOp zyJ$Lf1`0O@p!_Q8&mtzOF5W8&rKkT<-Toft|J>jW{Kb13&s68&E%}{wnB59bksnqL zb+}s(#kC5OX*3w(@3SC#0t*JhZzz1~9imOlSv_%hBh|PF+?vOAtUl7)ifbOZU44)? zg$5Ogc2I!04Se>yrQl{%bq4H41eM!2F-S1XfHZ)|>z^Vo?s>r`9>v3d(Z-s4{%^o#Lwfo0 z%gCI1Bn2G7z@w z`jsUm^Ip!3$0kS&ot*3rBQHIS#3EQ=D`!Pz7^-01JllR&%NpO+dRx}|nxw?xp<47q zwTpaP#t>9G+%Yw-ezb;dYkE7aUYI8ypURb7FJHn*sVv~w`fS6JpKN{(>Cl{qGc0)K z=v2bF@@F|*>YH>#Uns4$YC4bVjk;%sx0|L9LtEd26aMbP;k&)wW4KnvwQ;OX5|69WF3ET*Jj}xh$ErD*9MyQCS8{8q)?~Rq zBRVr8R01zTQRh!=rm#JEt(=U`tku||yw*dH+B@3#?NKO&p#gie+;)Nr{Lps;lU-O8 z6x9@zl$44IhPV269A9GJJrM(H%)q)XcA07y!k*nwsG zICH-0zn4DdS8?LiR45y1#%zLDTDNIxSY6O6URHn zeURR5#JiM03l_u~gf>E0pPVy!?3<5~$?5%e%ed)L`{{rCD!8O8 zR<5>zELdu0rYv{`TPxD}|A%c?Vbc$eK&L&3K0( zcHccr;O4{t<5w2}%D?>;M5%9m1r2?#$HpMYvb<>qM%i48gzxXO_?9mp~u86rAM9M0Phj&&pgo#w(z~EI3;K5TksXZsaY<>K* zvho_`3kk}jeRmAQ=w#q{0J{+(ap++M5PWx`ep~!bugFmE9hC7(6_$s{D2<0mjWzz?{!39`&g?`7X32 zRSDUeXZ=o`B&`R{E;9(>H}oH-giLe1%DKmMd!-O&d%%icj;u4P|roa$tSV! z9tK zw@gwBz+Rp81JQe=2q|^x^mC|ao&shMlwua{%|aJZS@8t;fk(biOE?ep?<7M;j=Chk zwWC#}v8ny|neK1_XpLW@#>foWY^aqGlOfJpv*K*|P~;hv5wLpn@BVOIhT>MwMl$DU z(6UBK7w%1Vgf(?mHTZk0@P__dn0b{3ad}c15PmY=p96e+FfLN1eH}4D7D!CyJo9q zi)iaYN9WcRlP|d3j~kJB9?#U3BatC^9;;K4&oUH2Wc*fol*Y-a<*RJuPiJmC%G7n&kpRGY<_1yYP5$~vj>K~%Uo4AG)58+kI-R8?t#;dHwpIgmjR zIl$=C1ln<1w8K!H_QQj28q?y=(814==Y*J^d=3~^9DU&k+X6SucOJPd@q4vv%>+$4noPQMXR3TPW)fg`RGPX z4k0FAjD1Weqk`G|c4(3L4-cJUx6kXzvwX5!6YOf5n(TTx*{Ru;+jZ62@i7+AXHDO4 zsE^2PR$SR=rE+F0u(klOaE?pctcmx`!Q?`x_O-i>p>OKu!cYz{7MoV!_Hwg*eCEhxTsUYmHc9yBYHYcdz^D~wrY1iSjpr2b1r+%GI32dI#{cgqKT zWqZh@+-DW0WAMP#LPZ6Jjace5efp80Q*16LCxJ-|F5GbU3{=Br1}QoIEb-r6@Ods@KkXCr4glYDSuZ&>kndQfFtGkFTzt z-X+)4QngF2YU+CQFo&VYc91VCKRagT&faMACpE^uBUrq>?ndne%`@-JS7pozxjdSS zc$$c*lPy_uA5OvIPXSrpZ=fNzeI}JV-2Nny$ z!>@CT4h|$}@z|dQUZhGT6Ek*{5)(T|azbkE)fCH)g@Ke2%X&~g!EDHEr3uE#8J5c- zYNQyfnU5bZRgp2{iC=z+<$d71B~tvrEg0y^8FIIu4fa&PPc+c<{m7YP_+b-^)Y3T0}TieW&+UUT`Z>VdAmiV}tCb zecQy$8o_3}s*QQ!wrpfc&M$cKjbu7IJI97!N)(x_VQ*P(#}?f&kh_{DBC%UI>sj<- z6QsRBM}JEr&&gzR-ASw9Y?@)>1!ipyrFD{X^)PGEY~)#g(QONF)aPGDBlnZyS~xJv zcF5jYzM;TH9m6C-Wqu;}J%&Xrj;du=9#J4mX@JU#2cs#wB0dKCKls8lT)RtU#B#HN^#7|t()@R1|J&BH$lBXzVuEHLym5YMxGk)jFN%R_z5+k4C!FUI~r|KEYU0t zBjY*aZ?%U`S|$Cs@79!`xD}OLtpMYZ=kKT6Hr*ai=(^vyWsywUDd6JoJC7xc_05j% zUGJpZ^>Rk<3xgFOPF30Xj&IbZ(y&@+KN0TUE}O8GOg9Ux6~4>R(ODt4N^OZs%ABEn;%)R zlC7B<(?Qmv&EM=75v)Pfvt#1X47_ZE_~A&Yzziy$6Ektp-3r>cQuUeX3P^_|RpMr6 z7Ud3k76(E~dO~Cc;WtObYv#Xb>65lF(4D=^ex}f79ExKVK27hF$>Nq)2a*!zE+7c^ z5R%(IiOL0Mg_=%SY(#yh5;AKRqIs;PiC0c??wqWhUH;g__>0+qlIdtvAK}}Zy1bLl zJ{8xe?a45RG2Hq;ulH0?wb=&K?5T+AY_EyP_1b)6^YNJYeyZPitiO z!Ahy(o{8PJ2|Dk<&?h+8C2Q6<&&2r1sqiN&-Co*S{c6n-HL6R)I&|>i=xJ|Xw{~QCo9PpoI@hTF(g}6{%C!@stNQ_~xvZ=8z_RaJUQws~365PE9`@?<~@^xkGsV3&>Z}}|yehV*e@gGEI6(7GuxJHpuZOAKI zl&!^=)??AO$NcK;9t}u=Jtd&ztN$1vbAr`}-06+})v1KcI4lV6m9j8alH zZU@9Y6Yl5HPpyB+SGCqP_0*IUCW~4}Hj4*UDE-Y278>380C^h2lFQaX$6y)ZP}Q&_ z2kN^n*=U6Xt?EVN&TgIMvB$Stuu5mUBeB;gWw(~C&ZxMz)K1n1Ckj1pyu2N{Ay2}s zw5&Sz$aAsZCQf*=j`+4v8{5rFHN*2eVqcuedf+`x(#nIF=^Q#C_VgYy8>S zu-FA}LmTg{g`sODB3c@mYRZib@ifZ3Ls56%+4dLJYG`+?cONfr3^ov|6h1L3Mmqtf z<;#VuXP=4Jq;Ga)*`9nm_nw;}!`yW!qt81Lx0zl+S_ zTm4LZ>ACiqbGi3RmWcJ9k9Gp5LAW)2e7W6Ssmzg6PkiLsDgCVs7>(cgIJy>}!bY3T z8)s3O#Ju9zveKB!W+YYEk4UNgK#H@m!f{m5mBN-q0|q^kMq7RQENg#gWqo)X07hTm`K8aK2Tn7=iR1po$|O}^JBO-G`#=%>;Kdz3I}ME` zQOwO)toL-!J2errsmo$2HuJYJ8VlC3;3j zv)LWzH1#tjJtwo@;U~ve?DzFd!zxRQ#)EP=pS|eG!LA~$kCxgy=-Z$BQLOE4u$rs(Ccg7Epi-8M|#vnTD#1+%f~RlAcXemGf?SLu@3E($Qtf!m=4Joyep}8neA5g z)_JdQ=;{0_htFlC?yBpZ2AqNmdE(LmzOlI9s6}m-IPY{(|G3tmQ?-A&wAh;BtbNlU zowK+8WiRFJfU$-C*-F(1Z5f6hm)`WEkYjL@0R4z_7h!XA+%KdcBywmRnpM-xe04yl zD|n{@np|s22lbs5~%(Z75uWm(M3 zUo)*9zqiz)4~hTDe=t7WqW=0slj7Jmk?9Irl%6kGP4kb#R zm89BPm>VSuwqJ@JdPT(8xd))G%je)+bnMN#BwyWC+4R%v#B!$|O~VU$7}*ux+Z9IX`zAJOtsq3kt~}?)ZNHE5!t5L z2d|P<){5`Ei%~LLeqwJnL+0#dPUCb-RB(&1u6AsNWxsZIfuq;{ozF*c^d2=PgFWij zAJF6e#Ft+8hTm5hmyDV34J(^I5`r)Ao@oS^sS)XkD)pTEYn_OEearFAsbDoH@*CMv z-dm*zfL4?|C?C8YFy7H>FQ|_-Oq6{kQO##A^dRO5wFRXLa4ILi(nV>eg}h(;rLncJ%Xp@ZeD33? zPoIG*D&1e^nlsHcvYj*jzS!fP2;p&YT580g2RJP^pRs-^|7t{L@^s!<$V%I@T$X6l zu9*2E$0oNdZ6Q61-W+rLV#ec}}!?&{TObsr;RLJbPxm$1%pMhbiAYvp}&IemB9CTDP zjRUSQrpr9|h+g?)n7zbPKXxpMMQ^SNSd+DW62C}v`AiDo2jO4pTay(&@mE2bQOPxW zZf-8(E8EX3^EEcad!;I^FsWVT?s}iAz3;ivb#cpKfDD3M-z|Qxy#a+*ULWtZs)i!d z@qtGZC)ZUC4U@87IV}#0b&YdMaKx};CyvfsIEC%!PE31-NM+z>GAp%sv}7$|-cQ&4 zxD5HxZC3`sgr26p#xToo8x28aG@EYOwL7D4sYFlHh_E3bHD>kndKii-RoB;B;domR zKp83^n}n=*$Fn%UPA{bPy4Q-??5O zVsn2NcYMW4+M|-kvR$>v*<@!+V-Eu4L>7YC9^QopRPwFYf;e_Nv6j7`iisQokdQP~ zmgx*9)5wZVtDU|f(xYysvyF3ChyN{2dsar%+B!^(XAb?2dNm#W? z+_eD;0^Ku&z+h*Xf8n}=MoQ<}=K69U9hpMTgp%+Z98x?#W7v`oe4prs-L7Bq4wN|X z@wz)d!1!7wJO(YGr6FE6~q|!4u7vDHH0KG zoz5lCFVV9dL?zjY#4m60WS3(TO4RToPPdP*5rsBr!}zcb^Nmf3a4RHgs$YfpoQN^j zK0!j3B%rCHkx86u@;JooLgXn;weN2zUmv9@QE|S5!Fi_U|`mZzT- zjP;Elyu0@DPEU4Jw5C$FW?NLYX0~qW8f0t=`}v+7ro(_q^0KxbT)rtdxtip(-=CpV zYDjt11o-tLkEMWWfF8WD_C^1tE^YRwD~%)oK)sDx!WF@;JX~ebdj!vE$pR6Mh0`3x8C9 zA;;-LI~Ei<7E!i?Bs!G-<7oT<9HMOFH^71Uk^wV;U8eV=9A1d+iZWGCS zxH{V<5w_6I)Z28+6ZcCr$|3qUyR6X%9w!cpc7!WnxL=PQpyeK;z@x=TJ>I= zzaFMR>2(=EJMy6vyq}WUf|F30BOk8XhSO}4ZP>OxLR;%Sh4%ti2+`X(Q2N+QdCP>U z6Mu~u(&@gRb|A)R4B`oEgfd%SLBadnmZvy4)$f> z&6O#W+Ql7GJxRv#43SC$d8b=}EO4R;1?t17gcNy6YylHg&13VeP*&8-3$VCcUfV7= zmK3zKVh}_JNA<3gRezCLBtBcKCO^m+UvXARyrzk;U;t4R3y9kW80L2gK(74aT_Z}j z=b;~W`ROHSrY?uB3|2p_MS~iP<$CSViUT; zhJ$&F2zF`U8UYA2&@$(jg>xLVoD0jYq4olszu4cb6g9cZA;l`+H4N z4jnqyzWi8C2<{tsDNXf$cYIOL)tgVSvFgZ;*>RL(w7O<=n4vkHOX(O>MC z4MbG>nTpA?QdYF{s)cgPOlPj6M3!M*cD%s( zlbA^mbJwU($XC`9i+=9waZ{__|?T2!n#w%;pmK(CYI21XsUl8v)p zSdMe$ZN71tR-DH@UQ zPcr6Va5v9rBIvz=4rlrKj$pn-g<3j7;nj#Ud6^NZx9h?tcx5tQ`Dp!mn6EO~5n@?c z4LXahxz(CET1YeYc?gHHUX@4b?!3JZ_iQ!5wv=2+GEThPzC=O2FHS--ejW6km!a)Y z53l(47cS7@-T=s_DQM%1oKe+TFWPb)9L3qMo#^^JK&yHUV{q@}dH{NBgVeFcnig%a7 zeV#Ng#t56;->s>>>1KTMG}b3tNcr(@v${M$9@|d%i3k%szk_W$%oVeIc7lW@TiDgoKb0%HHcaK9{@u+kHRJ^LxIp=f7UPUOw07bDqa}oX2>- z--p3d-s&waojfCbi*qPVqdVQ&RalOV6s#hh=h`(*KCF(I4InTB4or5RN7HuLIxb;P z=jx3RYeQL4s^{~h0R&j)a?DH$LFcqhWNboQn8P&W^NBhO6Q{V6gEBp63zgVqqODy| zP-R=+iRrhaD*tZ(8w*f9U?iW$m|#$PBhE6%Td__O%}VObt$}kd&V>ME|E^hoz_p9e zV}_86W$EchO8f?oNW)zv&Mt81KW+`b>xUs00HPEZ3E^2Jq-11&Q|G&H{{6)lfITm| z(T#QzYy&VjB7%3_9(8|m(}*(_AsZU?1M%ZD55%8{Ko+7r@iJejl#+w-ev9ahDJ%vb4tq9gwY2^p@NA_$)2qSW~pXfOg9_1t!ne z(uLnop}(!|Y|aK-%jCG?UZ>rg9hA?TBe5JGkwI04C~`i+ywEGG9rf`=zd4pWm=djX zl1uMfd4>}GXB7@N!EjQwcjVcVeTLv0C!;T-_h~x#ca@j{HvjI=FQ^EOx?Po2B^TJ# z$y0!}kAVx%G;!K1>Mi(Kt6JH&*}cB}uYx^pA^``D`cb^?L17~K=L3_yk_|6p@+0!` zuK)TfJq2$$Z_9(%M9GLB!jV09wWC{?gfLmf?ASvS?Zr^9Em>sJ!Ut$wasXD6>(1HP z>fI`U6@Fp+@-gQD#@cc6IObc+o_fCjng=-uCo@>h$N_)+flA+?GVqD{#HfhxwvA z7KoWK4teXEd2X%kZyz2yDo`oIp(hxxar3G!e@ zscgo5{%}v;he#%0xs<}i)%-BWs?n01fn4L{S(C@!m2gOVZE0w9738C94dnCNU18je z1pMWU3RIb<9NqL)n3jz`A>Qd-y|8N0h-2MW@NPPM90>LP?Jr^waWb$8{Oncx)P zTIy8gZG?FuR(d~&s)x?$nqB~&fQG$$M(EG^hwYiqL{+#>5V9cVdX5@@8hhm-9Wq|I zD)^@-F2F+6&z&RGVCD;U3N=?2xVOq*s@66QgiO?i&gHHFm8Q}7-T(`P0+Ap#s|bl2 zm3>&H`|9bp_3)v;C?DXS%hfTX(Pfh7zp%cQ0N;9B}U)6TPEE z@6I9)*ot>)&jI%$HCOlgmfz79ez)6^G;d6wO!*B2(aJaUUPe>E2B-PP8TY64&nK>t zSJ_~^7eLpvsl=uWnd}2zfeV2`!2ql$oOhueY0((Lf~bolW1P}dV|f;8_8(V50v@3M z<_e@x|`Z8wvE#UB`X<4ob<9`PDlH2alY(>dPwjn2Bs1AiF{K@<~0m-b>;* zkuiV~3qN?0llMjifl)JgIy~zubIK(D1OTP3C0&OP2xZFhlyTBa4L>wU%$I+KaU(?l zX(;=Vk?j zL=1~Vdz9EE7Vd=EFFe#bm$&@CVjmx;kAdh5&jbARwM+q*tmen|^uoOuaMC@*(hs!f zKaw&Vcvt|+TtP%DS>^zg34)F6-yTr-KD?XAgweeA2+MQ5Es+CpvgB_{ZVwnB96^fq zNdrs`GK;zinKc9!x!js;I}J0NvtFe19EKrPEyPyNKhsIHoi7c%B2`@?O$8Lvskc}Y z!B4O3Oqs+xL}!6S&{yqM9duf-$=|-jhUGM>?b0)G{gROYQf**|JYq!YGY*qa8ZbRo z&p+Q;nPsoolPvSp!uDmu@h#P&ry?tnDoCL_%i{0~(k8As3`XSgR^aC8WhS04|Z5ZSqTcN6sM!P z(~rQuaG2lV6js?P=;UHK>8HUWe&Gj7-e7(Vgm_~CFr^S8xwAHRa8Ah%AKfw?3b2%c zI}xH=h5uJ{3#AX58>|n!r@^1R4v8Xo&mgr$ykCc~oDsu8Q-!?($UC($5N+Hx zAP|k{rb95JwX%e(zz$C zf+l!v_@I2fx0D&uftlkC5T$A%B@o7kX1z@2d!d;-5}Gwc?0pWBU+2WsfD-pQC`x0uu78`y=Bp`8Z*^lB2NOBGc8W+X9wz@V{P(Zro7Oc@%*7&cZXEDmRH;XP1`^rL_{q01T{R?GN z;$EaPY(~YcvmftN!Cd$M`B=nUp#v;+Yp=2Yuv?0O7M}MmS>E*3sObDdfdd4y2(06q zX@&bsJyCp1i5UNRf47wO>Ir+_t0xcWgBa}ub3PeHZ(uLXLj3*BxSz#r3}2{XeDNWX z%>FU7P4@4Oggm7_Kp21|F3Lod<9K)G^9`2KUhE%{;D73A%!GIokrIJV_mvH-LLPa@ ziWH&<=nU6XyR6(sR}ER%>$4Y)q-VufC>V9-n^uQS zJWnl0PGoar$2+EPV{!{{Z+r*lR2WpFRY2YAegEqNm6Dq?0duE5;QLVMsGn9Z+P8Tm16NRA%7NHh#4k z0F|Cy`&ghDZ_az0DOD4R_|ndsXL-L&2Y81GpT4fhdsy4VbqwVS69?W=^iJ~5(7Vs@ zMZWI#HHHFD5WD5%$K-_;f%a2w#MTQUYBor8ozCa7PBvV{Z9K)Bvni3u8bu$n}OhY*U4nKc`YT`(G zkwzVSkIjxfpr?tojqH7)7)|x^!=4-d#t8Q#&pQkDKh2Vv#s|oG2}ps7v+rfSryR2R zCtUP#BbW;$nG`|ArfNKs!rt0AErZk)?3rH=<-E__RqEDu5e%;Y)p=?@GhaZ)pSAQw zU+&z3Dr0zNlING1iztHvm&sajOK*)aQysbk@OFnXsx?@;v)lW2c1U~Zzp$S#UQnBU z#V(Qb<*%^jfADlbbf_i8WRq&ksC_w$3FvM-Y-dD4Fg%~~s+_3ew4|0k4hg(mf%T^* zAC0jl)_!2vx3V^@y*omth;w`_eJz!&rBDsGLzb+v*6|MDAUh#0g!rRsrVM#9bTfti zl_v+1xLhPB<1BgWi{2r*yv;HLseo0UmfjoZtTKK@&f~^_p4WnzDvYX&>M`2626$)d zG~UAJ0kt9?T@%;zlAC>6i8(KqhMG6(T;_Y8mO|)dCqK^fGofNm)u7z??e z!b+n;nGN#)vLGVNjzH8QIHTc#{$(Uo2`g&p?zF*Nrw_>NhG+Uk76G(k&PwsZc07=? z;7N3x{?P+Z_l?kAwE%(edN!M`X$Pp;5Q>gPU1{kS-D#y>1R`rR%yc}xoA)zFpe@Wczw+}7 zdBb_Z>sI*rT|stSbOI&2NTXnVVQc}g)f*%7?awZ%v6KMAv%^R|x&0W85Z5Fh`_B#X zU8_5J5b=EQC84~3MAa~f((C-?$!=xdsQx^O3hImSLAZ; zmO>~6AbK%MDrb}2ud4taju**xdUkKn)v=K!RtXaMz?o@CS&FW{B@}3b9#`t5IC0ycH_3fwNxdvboH7h4Nv% zcyFcqt96C)9SonMA1Ug7<3Yt26nPq!FjWJ=dN*QGoR%_!sUyFAtbHbA9Gj<@G!2t7^=HeGfOdgUkO(td|4X`BVwo}lXos{J3vpx0_;Je z+UfmKVSmJH8qrx;<5HX2L28{OR~y(+Cr`%jpi{0m)IqAt z4FztNt#a&nXKu7uM-?Oq6^I8!#^1q3Q{N-TmvVdHjY99R|GM)|*X0YXY&xH63rYEr z6hk1!E3so68A%D#1V{P((D8B}KoGSA5@mgUHnF0)EcjD$9h19#mMNR=0Qy&xwBmVc z4vl}-81_SzXyv+xb)#JX*1xLP{X)NMZ4FXw8bc)URXBnSS6YYprY(AP=7W%qTe^fo z3iLub>7EFcdfW7A?R{w;rK0n#g~dAw3!lGNe#t0t!Fdb;TbYqhy(hnM8-nN4^OsU) zQ0=S5cqk7=mRbrFkrFpdKCb$2_``M9zAAco=x~13Mz-ktomoo7#O@NCE2I6Go0*=n zbsZb=8-%;7{>8kn!2TK}*1qlM95PK_dvEWHMz?$>)kcS5cGEqTCEtrxX#3-;u51T( zy$jF{e|C}PS@A%1Z;iho{vxXZP%mcq{GXQ^#8OI{gov|kx@k$Gjqy)5L#Z($6(Z(Y zjB|2;QZ94KkU@7^EGv8Ix>sN|B!jH3S=FyU+xbuPzAiog=A~w;Lfm|bA1B5^kEnd= z`FWi-&(ct@xRtBBbhs2Ot90~ZR$@WE`#^P$C(2~qUP@Tl_<1$=*mIea+m9-Ra+Ols zt<7X9OWTAexAlQ#vRC~3a_Pm)uTlqPB9~UP0ONcn{*S9^G_8-;lB-4v8|Va3;+VAO zG86-uzvhwghTxG-4`VlUP-)hO?=FX8=`a>J#z3Saf@n0DKG5Vmh4a$&GB%PMUXxWj zCJ7avl#!#i;`e?2K8EOafd3KR%|KvX0NJl>dZg!Ja`8!TQ{;zKT~XOQ`LIX>r}ReygY9c z=D@=piOZ|F3R4(fa-~C|uJ5!eriMbf0y}<$bwM98ZN|QH!uX3aiWxi@NND~UN&Lry z`7vTT(r`PDU#e|VE=Atm$i1m1CZ;PP(#Ws&MzrzZgs2+sM(6yj*KRqmT|W4WFHwCl zfh>Rd1TrNhg`)D;yR7(;nJd-u*(6G8BiSPI@*Hh+%QTtjUmR^(ku8ug3F;aWp>^pw zH{C5E5HKl>Ix~GqAsIWGBiNWlV!UgYm!lzSn;DfvXBE(Sutca>0<3WRx0y8NZq9q))4ZNWZkUl;_djQV3=l}=$zG*80L zKIZkWqkXvhY*npRjz*JbJj)e$}ioNaVb5@)}3;c@8U7@)hi$RUa;y4 zl4n;}-0N+HE}#)*$IDxWk=_vgq~?>Vy||fhX*7aZiPg5=ledu_(=pxk>G2lS(pbZD zx(S!2Vn@u#yx#bLqx-N10|7apcb50nWi)u)aLy;5>BHjcScq3O%tZYTl_$=HUJz3c zl9Hz^nOa>!hm5q6-^QI&I1uvXlkN?E1Ii}1XvO)Hm!6Q%oH(G`lBZu>@6TBpkFBSx ze3R+Ym7|!5J=aE;xRw@eg|VK*SlK_jV{)8%&|xH}o>1-ERJ7C%w?4D6 z{=~h7Jbl>tpPpM9fpQa;8sql|)mr3>j@MYCN)ef6pU$TBs4rWo_xkBWanFPzTcq)j znj2CRIIpQyVG|)&EuH@W#T}d1eY8aUjVFyMC$)8#g%yZ#vyGW+Mh#;hgxy^6hjI z&P24KTW%OB{}TH7h+6)3hoFs-=I|qvylyuiknwxcgS(aR0&%RtJ~T{bp&S z2qERWT&YNjGN(dOWqoWP;`O7+XT0bY;MoRCZY|Mr9KYo9$db$bk4vscqWyqHs*(pY z&nrrgRofD^7Cc#b(i~#PaTVg-&*`dEPL_(#v4qJjkux4jM9k%W0|QBWtH~&$=6$0y zQq*aDjfhi4J>RseX+Mf<|Ns1@{z;^mRd_T1uy$h3*`@v}pFBCz zy2~5Q?%R*H-uWGtuXfmgpfSPMDM9GgrS53xY5MVBQdvGr9;P)O;#Lf03!2f#CWWaf zsNBx;=JiLC*3^bLk+HT%QpvMLP}&ENo@N&QYX7jzE%khI6NrMSY3b+CPL@ib6FG83 zbqQ=tC(y4)+H0>s`ikk8VsS%hLR7~xD1*vnNYxe3D$q2S0bG+>DQ)hzbiyQ%kUL$~ zp@S)`GqHS1E^P7&ENRm8-S98yb2W6dhd@V+uPf)AYCdI`?W?VX(Vj1_?Cj9|WyYE; ziK|}c!2V|Qt^Lrat$@WR%2ZSZ{rYqeEWm#ZuC>0aer(J7biKcdp|UhDILx7&g;C5Ahk5MbcP{)$W-TAWs4gN zOE7qoFa1aAEl}i-h8U;`fHe1Y56EA*UUX5Nk)e-kDt8-dbW7MLFzA@Z!Ed))2=Sv) zSG+brz)Sg@WUj~3ou9%mZW;05!EYfa6=AFbY)`@s4!3P}eeSSxX=?)U4Bhi7xww%6 z95mC&>#UEU2bY?J)b3A5%c12y+~}eTg+22CxgsTyq*`2=%55?G}~BK#%_BgGUc&PQ=hpI zvFcUO9{Js1Yv0~JR1;_a71<<4UuSy!Wd6G|4KX`V>M#^3JcbWRL{#=Ald|nC z`tOn%G5nv3BmJ>_HbOJYr*K-`R%SR5WiY7q*1d98qeGbO_^IuPz7Hf(0z;iWc45=J zZrhYE+GO2VX85!fsy3!LIgy%x5o*K;#wcGuzN1FT2<+NeW#1b`g^-dgK(Q*J>Cnc{ zZxFzq_(6~RdjG}D&u%1q?RIP|yiGIm*i&{FG6*4UA!LN#(6Yp_VJY2ZqH;!AkMIrl zWqCw{ugtBXI?LsT!-EOt`hI0Yq8vhtjI;U&PD&< zMwCP>&nlAS;-nUDx z4tlgVBck1w-vaE32Z<8;JPUG;DFmH53l@ExM6(2??M%UzoHF#}48MgxGU&3Zb20u~ zH~)_}Jp}s?et@cin#?)^=3)6+N*MS{vpOqZEizSdYwlqd4jJVbu@6Qt65H@*eF~71 zLhJWeRem9pJkOCcQVl@ACuzAlE{<}J@xI#O{w6FLw%Vpy5})RC4WesyZ=CUZ`_LpO z`9V3*u};s4g@&X{yl{E&`g}50BF8Ka8oLcaiy)fU&CJ!ko0W8>BQS3m1m?Jl6n2T0 z0r`!wEh}6d77?$~1;IMSs&o#z0R9sxkj*Hs;)XPO z(x#JTAE$xuWF5whP~H;D$2wJQEvPQu8%QO+d!Fxyec4!y;rEiR%YkoRxV>moVQgR_ z4^!G`xuv@GMARuGD;rARvx^s|B)fI9cacU5&c2=e>Dpm>3~f)5r7Dx7W_1ZnV0J2f zv|-cmcuMc>{U^^JK#+!3f^y4-m~rTaT`qh2yHjU$`$Z=b>rpjmnBO9Ir&ZMW~!5km^olMh9SBUf%38yIOUtXR6Xe#%--S)*Nf#*iI3UtLQ0{^N;aBsEi z;mk{Hd)kP5Fz3e;*CC8P-ElkDp!EKGkr4`y{A}+_?YUlKXO{sIwV)c_9z5lanajA_ zGygPWr}gJ=7tq8jEZl>6uXXJX)TWNuEnl3jOCz0F0SYypyVxphh>cT>u|mq!E)Xos$Ck2WFl*VqOxx>sNb8J^~t>VdofeN@6E@9eU{ zvC0LRNdL=(9dV|Sd5G4nGPT;V3js!IJkx`TcDVYc&n9%Sa^A7I6WgWz6p|Rd0)Ry! za~YIRJsP=(NN6HJa+m;mnjjF%fGJ2(^N83;h1We*ouiij_2UfP91e;qb^Su7B z;!I|hvPULUm~)#Z^E|p!;K_#xxc37r-haiPZ;gn3GN{W3{;}7frNi=VSO({?w3yz;@jIUY^_tRR>?NhaV#*A?E^aK@v+_CKO+?ZuS`ZS z%ZLd$K7mQ_latEU7hl*8p%vAlyFVwrNG}upL3DwcD8dh(4gjIyr{{gq(95`Y6M28L za(9KtNR!FO9_hx$p4$Gi8yhA=1fuQcRel3$%9LdrQ#n_xC$b8)DG25Z1!SVv>@Sz< z18gR~j%mmatXFPy9V+~nv{AyR=ieX21`+twlHnVc?=Db56KYg`wwD6I?B87tI)=}3 zhAH4fdH6Q)zWA?B7lR+MwV5iV(HEV36K?4GsU;7v?dm8K)i%@vIPJY?_jQQgZ=4Lh zS$&zdXD!#^Yp%kUeIWCw6vGbE#$Ah@Ya^10o^$EA@Dgc}77koY-E;M?VSjv8gLeLO z_DXz&ZNh~E75of!WCrEN6a=5+ANff?zXW~PCONr7MPd42Py6>*u{-MRnq8}3OQ@Irn> zgg@g!hTy?0Ji%;B<=mOmS{K+1Z}eo_cuoz4-s)5WYCV>eDZm>yH-CNPzHtFN~$vP^lmqI~ccRfB>X(dg|5hJP%R z38C99DZq@&dpT~aD_^kdEs-DRH91|HOGyXJ^1A&BW&!_rlk)_XLQ>VyxjhH1Eu%5FH%V8T?@6}B&UzU!4DFUk>EsS* z5Gn#yTB{J~93MWM>(=b-5@0s=x}K&A_d=SHfhb3kj!Dyx-Of&C?%YJ`(YawJ$M193 zL>U#+=IoPcMeoZ&9L;>_IBgU{fk@TXJ4P$QaNxjZTEU!sKv{y|Z3Z@HiOV~^rK#)s zWm33zYvhW(mktoblDsCDG&0c& zAD-haOl$5X^XEpuL^toXPvSq2jE4Y@B}M8#E+eflZ&rcQbVtU;hV{U)QJdni$REXH zU`th3G?MSTHfHOnp|!J_p+6L(g5p%UUf05y`Msj*;@ArlHtfpLPsdOvn?Ch9Spv5m zPx>2i+Ef}a=u@aEa_$y$oiZKu2<^@{R7JRMh@M27;_g{k(Z(td#ogwiQdMWJ%=BnZ zw(a&A?(NNIXk)RLoP2_S*}gAOJeGErOpURI9EX7GjYv{uP^STT2Ur&bQE`>Z$9hCj z{O$v<03d97OWj1U0A|Iu3VV<|CGa!>QMB!Nzxmg(-$%$H{q3Q8Msr$Lu|-EGs%je) z*R(-Of>pn}DD6gcwx#3b9W$#R4l-;UNijNU`8v8;kym6%SLnl5C7*Jb?w&KvD_f)e zF*qjDS8=EO#lTv^&5c{-pm~tz`m48od8}x$EsXW(R9p|e%Xl<})9hfe;oYAtv0Gcl zMeeJ&ho*l5mtwJPikoU>c6w8og1|C9rLKCk zL@F#~%3J7hWD(0SFIx=Y9hvRzL)XYHLpsx z32%1Ux;qv*F|)BLqIHgVKD~@PhrWLOgX!ZV5#ws7KX_GbNlPTI__;2{B*&^WUk|>I z(pefRu}h-!3X@>lmPQm1wuNqyaAD??s-HiX0#!m5Vcs4i`m~>+#$rusviV^`+@UB6 zf@Fh0PqKngDUkqgDMHi$c{gUJ*tUdI%g{ERwlae^M*E{beTM;d;%t}*;c#uJ+zSe* z{Y^pb?;ajl)5nsEuON6EA{U%|gu~xA4{Tl71ENF=y`ozlGv)NiRk2SwB@d3!f1f1DKh8DnH1TK;E zF*7xlnTUuICt{Dwh%jo9Gj{|R)|#;-#)e|7 z%MMoxLFw1~NzIV>Qb?LrW4{S}Go?^YDmzPd2056{<)b!x9z6j(`l|qbx<5U-mM`Mb z$KD>IKOazVh|Yx}W9VxLTPI26F3@aNi{gszJ{9YH?zta$H2~D!nYQVw2q1p~pmj~1 z{2^xGo+?EiY(S1;ky)!7^>U}?Th-@Q7^1}$#jfva9 zhqGSD%C7-VXbe3=ri5U~5~8D7RtN4StuG>a z^3W;IT$=7_=URkTx4`aQ=z%sDTzmi3NX*<%xn@OMKMR83#m&VY576BDTr`7&xa+?5tYmCsQBxbbNmpuLM1^9Z$q z>k4l(N9?Cu$=0w0)&j!xQ-w&iwOu1mgbN6cu_kVf#M=D){GhbQ3b!=}kj!EsUj`V- za>6<6{4I6nQPY%jJfSiSZ;^|ar2hR9-v4U^ftiI6{b^(jWPAi{9NCg*-ZnvnjggMG zb61n^3)ofN-yAwnWYfIzyqyk|a<Chv_9BhVK>l&g~gPH%T|C_ z*ssIeHSM`n>Y^je6h8A*;6xK5`ppTPk}$X-eYr3k?CfFCfNcau923&qa(!6>=y(k- z@+66uY!UOk^P-1Z2z~Sr0$iBxN=KiY(RzH&kYgi7y z^FsvC}lISQw}mG!uYvQwI#tofz{*>r57Z%5YNv>E7cWPJV4k3yopI=v9 zdU{cpRc$w$h{6}mCmC{SpHCVCnGz0x35!B0^~0vDi{lCH6koRFxgHgcFG~}^)Q70| z{u|0JzK>8P-32;VC<4^@j*Jfh0PvG`(t+}Ov7Gr8S}>S_V~5dLvDX2q^TzTRe~0qV zc|xeXtu#6`oMC%-=y(i3dE)sJ$B8c&6&H^o<4Qmvn~H#Z@=j%y)z;d){049tc)l%u zY0OIFhvq6p7^Liu)Iv9(tmRh%zB0ry=EsWm-fW7ElVu;A`BD|I9Ibh&ex9*W{S**bC{!5*ICl#>sJH|Qr*11n~hZ49{ zb@I69T`GLhM%(7|(iS#k#6D6sy1P**7RDTJZG3`T%MY0y*v zk7NwQ)j)E69N8$$8i@o2&~D)ZrWuXGdW57(BXlziFf}l&3UtCRNqX?+cxT;TUl^Z- zy$9*}GjT$<;;D-PHq-fBdjH}O_p7gFwe)ofSQQh`b;~$Oud170Uv~g}+Za&s88Tfk zR_0`kh9wXwG8h9%FMqoCL+=g!Kww)p3{7$3)&y7Op&AFOr(Xd~fJgn?zR*m41P82P zM!ErT+%!Q~S@iByVZ7Y?pDEQ>r)`i}?wYVd>^;wK_!-H}7^opaQ&z|+V#D8nzX^N{ zjD$n?cO$>Ltfr3lL9I2OSxf&GsE>RPZFm)FH^CkDN+NN5dMEbn{&c6uI`Y2gi*N2k zsUAw?F?>1J_`W^#sED&T^a)RO`NqD~SuXls>Q$-nS;!Trn*~8q&*i*Litn}x_N?Xo zBw^Ll+|B5wCN$nO?-SAwNheZbJ|uJrjHfP;ie?z#WnZt=QW?z4`kg`m$Lq7lz1AKg zTpF#?8`=V|nJ^uawti%}FOaI?6^`2-De@`Z`oQeHNyKxx`;8J(k?Ysp^)=9xUj?LT zdow}_fI4UR@cYM`L>%a=u26ZlfJT~QhdfmyfVAw0xS;eb=&n28w*R>J)odJ&LB4DY zMq%(fepg~L0%`Op@~m(qK((x zzb|`vP30syf*!+%xXc~RlibEEyg>P#*!oq?RyX`hH~$zQ z>w?2hhC;L*z^Gxs$Z+B8h5R@6}4*?_dLUF10;x&BX=v&vK4UX2?LPca2$7|b>;z#~u(qub9Cjrq* z34X1UlXo7d)U@^BoP~NQ*L4jz{-Xbvj5Hy2WklA%v0~V0(C=q}#a3YRK`RmB+Hj=c z5yJk26kpEF4Cs`hGLpSGXX4Bodz@W{mDmC*+dCwx0)eXW&>+v&t z;bVs&*nRF|>+Q&gQtScVokW}%ZRHTBFr0Ci(y>cb&;u;8Y{qkWpb2r(RWCok;|2#> zPm@mp0KzTPAsXpkyE_Wb$w`V^{lL%QLE1e)O4UYCVm4n&vL<}de{ti0tlJRMpZ)=Lgvh7n5oe)kutXH{ z-~k~}Bcs1o7>T-k!%2<#@|+nPPu5jRh-n}Nto)O3c^L)- z`@{%ZLa3mP!-8Iix=Hj&iBLt4)cvKj;+(_*^72RN=b^h z`~LfU1TIA8xwmXxmLQ*2Wc`D5XeV1I7pj^pgk zT*&p9KIu59Upe+}$HQY+fw2bNRd|ZnSDqn4PRijeR_CeB%5jQ$H9Zg`> zYzD^H5z_9d<#4#qgDgIzd9lW?kslXXi*?bsevG&lN|`$>Lgm*n_#4C@5m8iXoTvRq zcpDZ$gveLSdKoYbwIG7e+@wBhgG`#~Lt9KxWmvX_dKe20$Hh3!9dJl^gY z)o=9*iI>WM-yugdLr4Dc+!>qaw;j$x`4>4Wt zXYeFCc;;|2GUn*}BbwV`2*WWBlV4i~s7d7h9Y382b?#`_<#xaZ1be4~`sxCVhEakZ zV(XK(XlW3!2^&?4hxK+Nj4$pVh+JXlS69;HinBEzVSH`6xc~`VY`xM)3M6 zg#FfE;1aR~ko3Z*E9#BVwxwGzNr~$UY=1*8X;x;prHTiSo2eoqgZ%>nV)zC1RfSgb z>)OdZ?8xu1N2(^Y=8>A=_gHyV%eweGpcE>mUv=Z@&4Fh$R0?-)j46ReO`2<$LT8b_ z`H$Yb|9hd1Na!AyFPhu%WfTlcxikd`Wecs!g>e8Ogo9z|BT@!g&^{v1{R(kn3S$gg z(tRypaE`buJ#8=*w?ivupM zGeeCAAvCHO%`U>ZX@Ww)Art;_Af!hov|G(Zpw?-!#BTE=>Ye z5ZEYtr{ZwCBpb{K#3!fylP-i#XS@ ze>G8N5OujTh6<0QULf*Cg4gPKgZIrdoqMWBtX+ck$7;fz#$@WT937{Z6KVv*6%{ln zaAqH%ss24!crXll{+AJ{AcXmFgic%!5h=(c=^W?9bX2z|Nt!Bz(s2VPQ;;we81GF% z^e@UF`k2?gzlabv0b9wg8p9P1Bb%t-UK*hYP2Dms+`7}ey9{fQ* ze}Cr=P*+s~IDK3ccSG^rqIWia-uR28LNz8D>2xSvhBFb-l{d2&MEzZ@lZpcZR8)XJ zQq_bayscU!#bGAT+QF72kCixa0IrX3!~^N6&Qs>P67^owtBF=#DBc%|WtIICxsh9H z?mWb@&xGg$|5@2&AQJ`7UU>1SGBI;J^tPE;Nd&O+Ggz{+E(}?zt*xv(X0iY zW_GZC20_b6@sms8A})Ql;QiZaA#M46prQds?1-MTpSLBvwchox6Nbm;nN|)eB3$k) zv4?m{ZZ=z_2itz6SjT_v`f=pXA_Cx^u_$77|7Xa^Kz0yb?^;a?ClMEjKi2R+OzU;@ zr!N#1k%{gVxZF*RcQ2TWaWfaF@$SWk&mBp6!Y;v;%p57$claOo7BCmVT8Q_bG(LNk z8Xg=&&0H5FyX9Z`mOQ)mnL~CPo&=XR)o3x)C;z&^6et3e91;Txed(mj}_onPs zzkQ{lU302nl9Zqs9$e7E!10oHL=j7!_>&d2*J{cNp-E8Y1Ff&v69R|&kuv(#i?9=) z6Z{Y0g@yK>gA~#HkHQ-j4maV*{13su=AXCFzJ{dEwQgOav9a@!0RKIy#o@p1Ji7e@bveWf;bOIC?MiI zJ|B_Q3#P0zlZ9xKCNGH8$7QciIO0J1WItgcLf{W*&7(%)O@WaGo~Pv~{wEb3eyC;? zp6Bw_n@chs4y=;RBHR7N+ECvF?*mc{W_#van=vL$%$$fsBE#N#drNfUEFj7E|L;h0 zc!cKr;-6`V-Ep)`_NkFcirb2vJVsE6FfK*X@T<2Sc(1X@5&6hQgvaIhCE6Gty8UPM z*(1UF`N=y7K)nwd$+fjq2pTzzdkfSyE{;IOw;?OvzSU#@tA4JM=FrlY$i@4@-Gu)vt`4DXk|UVa(v^^4Xb-me35LrrIl=MOJT< zYBs`h4DT``!DW0e;Vj>~74eTo&b|gKoE}TYl>J065NQm9uC&^B{`4Hzt_#Jb?Y$K9 zMVFhLc%cogcf>a-z*xN>1K@H#tWa<7dy(UaJZc|-FnpnXB&)eJLlv?WvBJeD7OAao za#Bd80Fh&vea5YG47r?7{`Z&j9~bgpt_aUoFWUd!5pj61R;LV;Iq@rB>jNJtB6Xeg z@6X!{n1m1`g&yaXbA+z0u0`ez#~>kGzSB{CLCv%$=IPU)o3G%8i=n78 z0uDvV!`Xio!2e!@n*E3at5H&ZDYso$?a6ruXvp$%EIa+;Khh#wOtraEav`d!%5net zuJC3bzd+QY(~r({g&F{0o8{R1$$1-Q`ZzEmqEWu5+vN~fdbBd79Uu4n>WdGTVerdi)Pfl9BH z38Ub_co8&%w300yFOP}lFn;3bT+Ra^e%l&vlq-9$4YR7%lPbXPClurL3u^0s1sO!` zgY=IL;lBR2$DiAzYG+|cdEXlE6+aHNQb$sopu|bL_grdqoEu4`x`Y8bmqmt&oYcZh zE}m#tU}Sh!5|<-F0JL*P9b`8cH>({GDaF{{Bp=LEf?W#tX0Qn}b#H3?w*r?QASl44 z|JMmnmIF6ILEZHrmuT~Pw#k^eYF(5ypD2je=pGP_)>*O=KONu=DQ(DA_>sh;!k|$R zqBF(lNqbRyjY@dPILOcIZS@?_-Z6Jag3BHus7wF7%ZLk*x&+7HpJOnJ+K6%=!UP2- z`OvdSfGMi?8hS?^TLjZfn*aA5nZR8|XFv z)v&MWz^LgQuMXX%lY6B^c?91r^)D+2N*(01pXPXOUg&*wWfSP5NQFN!k(TQEd>h%@ zyhB*aXp}E{P?Wy$wbqCtzk#5HJEP}`u}fR*uD|AZ=UsVON4eIhwp96_*{&c;dJJ($ zHTe2;k?_CPE**eJHS@%=-mLo)nY|ZZ=%{NtsO0G6zB|Liv1!{m56L0<_Ky-hVjYO0 z#^&c+GW_YE@kI+BX7P-=MLN=;sjwDX)J}R4OHorD<-s_|YblVj$5^dR0)Mq8V5RV{ zU(`X+S$@>wh5lDbyg@KUcq}{9_r^Ij;>l7e2(P&vxj#a+lN)Um@DdtsF%0dBd*|Yl zTMTIWR9->u@^_K~SsO$(lkV* zA5hr`q#C&rEGf4$;gIKME@-3lX}=|viT=3W)#X80dweyHwco$?_&u(8ETXE=)~7tK zImi1;PZ+fwc;Wl019+?W3Nc_EcSO*h2*lrZQe%#IgO;lfMm!|my)}0QAWmTs5;FVr z5rQ|F(I{*s*m$8Ex(=jPZnkOg2VuPef>Bo*t7{)Ir0!`;rh(U!Qwf>)*V%SS1g{rL zbM9bsJ4{J{scOwI;?*PdigcaFM;{78AbOX<+=a*D)H2awnjL%x!Or=-r{>QF(9iQ- zMc2ab-EWJCz5cekw!t9lo9T#bg#O-%!oZ1=VUd^o*B&W@T9{M>_4%fsFv0sm$`Izx zX~JlBpGR{p^S(96NI9UIA671S0Hxg;=KyMg5yh5|ZjM(+6t`MqT43EMb{8!cgVti# z4B6tgRkv*TnebOw6sVz+PVE2J$@=TM=Y4q#m1#{;W5f2;IRdBTcT$oN1|UTOFj55u zXpmDY_b``rP+I@YNYb?mTE;ntb}RNI#u~((LW}z z{PCja z8&B$-9qvm6a}44Rs-N7YKoQaHS$GfFyTcid{r^fI=8#Njuplxa=aXGl2)(4q!oosJ zfr0cGFudj8%P3&B_R?=wINvadzbKy_Sh(MCheW-^n(8 zjp~(By(ew{W^6B|*+IOO5Cb|c+TOYY(U{u1dG-z;1qiK$$<-gZ#R}nw;UiJ+R2e+eV&((r2a8|DA_|o56WsAA=&UEl zKC!BtF{O|V(%*{(PC*2cc=TU3%7NhHZk#fyP8YLmI?<8z1(z~%v0NPyJNo{HRHq~x ztE1}*i0xK|o#lKlS3B7ky^C-zo(W%5qJbOVw{hyS2^bAkPH2>E;QQ*=kNB_ccLlRK za*}cnY$%18&8dHUB!Vjkv-vK(1)5?OP({0*iqV{ZSsCc%-raXp24&aZos+}n39OCe z{Dd`fG0uK>H*WA(HzhSY@{jLQT$D9bn2Yx+^rM-^ubodSocFEjm0#?yY*TK2-X7%)0ko*Rp%of{F@d&)w_dR%vK| zvC%lEfeZ9ibmbJpWDHW?`v?e$;2#=UHB$;T6YWU}x&hXseewzq7AJ2^iS7MgBY+;ZHx%Q5|UD`HW5siLrvw|%jBy+8eXY~s=2V0fS)DLW>M zZ)*I~@2A7h_(XMPswc(k2FST@uG|t671b=@f52(J&C%Ux5h3BZ)jN}s60CT2`-iq4 zdNjaRS)kA}>O}6(h8x?xgV~>$RP`jk$7<#0RfigSQd=4ISZT|6QhS|f34@=rBw@#J zaGEHn{`qs44^(+>$Da(8zf$1n>>MR=f9<(m`jz2fvBjt<`_E;G96O#?#riz&`9hkA zUeJ%ia9eZn!moE(%kt?LnqP*u?24?j?4G)F@!i)&)t<#}dSsbOs5Ee$gKZEJ{Ac0L zk@`HIJ^89!#r4{9)D2fY0W(5#vI5U2diiO^bw1kZBi~~em^iDW=w$`={>TFs=f@S@ zA!OBmFF(5y!!yr>_K8;ipLtpe-(s3AL6O)Ho2i}p^y$;SYpFpWsabq9N%SO}4reZ> zRy^qzGlSXiADVf`>RSBqZ&M>dbRv63c0lyccMHq%&eRn++Vbd{t4e929yN#0Y53ML zxxNj}%P)eKObOQ06FH?lIoNa*RPbxJ!u?#sa){jC6K@lLy`2Sn!Oqgu@bERa#c?(0 zzqQ(@Eg$^>rowTXu(m6^Vkk%&+jy6rWLCS`HFrLeUJT_xZ)7CRdoE$ z1T+3omWN@VE_f=a|G7_tM066BQ+K2)HSM|`Dh4MYd|Az3kGq`tV{1#iE>i(4ClOv+ zRGvw2`q45|{*zN`?(p7~#`Hr`rW+dFz`=r*#K}q}tDJEVQvLJAO91RJ@ndQVJuomJ z=uz8-E_|;tQ<8F&$=<;sd_=ihJE8S@>t*z5cmne7Gm>JTL$@1hh&RZ?Og9_`(skD@ zskj>`_IBy`ffL!US^wBG2C1u@KE1a+3iZBHy{Pcol{iCB&#Bj^l0P7=nMff_pwnvW z`9*Z&BmvE^Tfo&ILQ?JeQ`%09zl{NYPfDGz zaA0F>%o5vfU6`XXlb3Qe-4GIHdk>GNU>seAJzLJxIl_cQkEr0$=C`*`)%WQyP=uL2 z3V6K5A5>h7H!U9nu!&C;Hj8`9zh`h#j|m-Qzct75u9oMp>-{*`bJY7b?XrxwR2AXp zP){@S?a2o1d`prKyxX;^o|Jp9b3%!fu zI0Q7@5B$35yJn62U5i(#F-)Jl%|A|w-&J^p8&b$@h;&%krQHlIav=Vlr@P^0+kuxa zGl4}yW*q;LT(KQHc6gYZo5y{8%%teBAd2y|`|b-4H`= z_&O{+l^55ih7@=Vjr%!l_9zOp%gM@u4kTIH+|2B%t+}+q%Cs&oKmWbz^2?c4_V)fC zR|+aPEO29def)CZ_Bxx~Cmc+(fvI-+dhVZ3GnL(;x$`b4yIu>(|R1Qg_DOi&qBT#`zL>=n_}RpQ}KV9@qn|nLoYh z>*4wAjd?6j#D6ZGt?j7~jS_KS64(`Rg&h(~P_Ni%6_l1vefIfh?LjXY30LipSqmON zejNCI)23UNs&?0J=a_i|H{*FtK6zxSGbls#b41wZ&1Q0c-EJ?)beH>t{wMG6;Zx-x zOX9+M5rTosrZf2uYsNH9TyAYf{P z)6`XmayKD|`U(FB8`UF|mspCeTNC%ZxVU)ow9`-J7jy-G+I_62gQ2mIE5iPmWcX&K z3C#_ECOM1rG(sFKu^DKXq5Jha$eA}_hQl3^i2J!uAAaEH=bt?{ENS|rjMa0)AKm}B zdtH>s0vAQEEw^vqe)f6ep(!U*F1?u{l-#8x3aZ>7c@C6)vw-D9R_B&VXbIsAOevB< zw|632Co#%$P2_6I>4KX0 z9B87I`c*{~6W=%|lulOY3J=S@yiT+K?Y2!?UXlO*+C6(X2c*kjO~cpZi2QWrfXNMi zf`Yf4oeBx>8?L}SsTb9!ikv4=%tcgu8Ndo>sp(vOXb>VtH@tF$G2SSB;P10fv2jYt Qy~+Rtp00i_>zopr0Ebt`T>t<8 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/options.drawio.png b/dim/documentation/source/_static/swa/dynamic/options.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..94d433a9849161a860c86f8803de9994740c69aa GIT binary patch literal 42441 zcmeFYc{tSX_dkvlC7~>l5HE`C1|$16GqxGb*hZ0MjIoay#=cZ!*QSuAR0b)9$gV;n zgebDhnziif_ny4o@9XpXT-Wcf@4w&c8jSmSKhN{r=bZc8=RD4N#+oAGtjG9{(b3Vd z8X)w{>F5}!;Kz{p2pHkeoU;ah=t<^q9lDq8{4;cP$NnMfTa!HlTnHXGI#C7PgKwhp zvaa4FvZ#WdsJy&`kB_u7!2$2<;7OA9!jZucxbErgOmHFKoDb&6%gW13$wH;%l`wKj zq6*p&W!f)@w7ilW_F%pP9_RHhK}Bgp^Ia!D_ApQ55Xa^SuU&8+&L0buq?0`R5g}0fdjf$(DyuO7QMKQ=*S;x^u`G9+W zoG*#s?e(9s2PiZE4xXj1^^dIk^|*+2{` z$U?yZEh?|$hgI-5H`j6Xkkz(8>l084U`z$=mMzE&t03T5E!Yv!kd&_$aWfZMFF2HIx+Mv4knU@F`j zjF8PNbYR*TV?BzQlCvQgaJNv=Gr-6xxEU%yjUfbG3q1ua5{@y}_i|Ivc7iDy_&^m% zegT$FHg2A9BSHYy6iU+3Q^Z-yV&qkvfChC8bzCt{=2(AYPlUdQgTIBLpOT}g3d|wM z$6wnO;h+e?!Gp{cR3O$+xTTkc1$d@E)WqL`#*92F5aMO7>}+Jfz1dcq3y3%GE*J z6=rUxLiY3Vz{(i}IVx%gDi}MN2k3cN7$9J7&Tddsc?%yj(p8aS0{8)3o8h#r%?woB z+)Z_ZbakyLW(ZHS0NDVHrz6oY$N{G0CGV)?=cQm};9y8`w=vZ9mG_53e7(t*1cH&V z7hE504fofxP;kLp(g>Q!`ch0C0%e1cfj)Yc0boQ&R>@o2+bzIH*WJay0Y)LoxhVRW zqs+Yn@z&n%x{3<^@Bj}33rk~PU$}*-gM&X>#mY)Y4r}8G@v-#4lYQZ?L{l4I8x&qg z&Qr%1=Ix{}OEL3u@`1Wr;}OOLIek4JB}0O&RiKWK9>vnoQqIH*L-5i?J2?8d8Oa72 z0UrR9Ba;9x!1Qzs^=yK`H$QD38$CZ|M*|BFxWA)mkULqyP}dAgF;ey+nW9{#uCCgdqnSc`B(GXq%Ia0_4ybA3&MpN;7V>A`;~p=wN~I@^T?5t6(wa z2pa;HtnEwFwt}INg|@anm@g7(ZE< ziMJfw*ue$uqKu;v)YDb*lK1w-T6&`)2J%J(BbbM)KHh|ANy3?0Asi?^6j?W-L6AQd zZh`PH1HK%lV1of0AP6sS;ELA4$oVN)5inSP8!v=`AJl;Y)$^p7C|Y`&;33vt@_MFb zMn*P%ZV(*8*#}J_k`#cK)Cn*)#OdiF5X$D31WJIvg`6(Q$kEc>80>!?M?HUIQz(sJ zw3i{2=2I15NPSZS9EPIopycj{BrAdqr{ia(;6l`gl6~aif!cohR+b(f%GMACYXd_C zqLH(SydOATl>TB%cBB$iz?o5<7l6RC-_Ax+O`B>R_D=6SBiOSY~POw08C8!RJ=m53! zfm&<($|0RlPRdAmtb&u5kq_R?7>m+JTDqbw&4cueQ6`QQFErdu$=g&u5UymQY#l_w z=qWoWo5{)%oiQjY1Xv=(J5UbmOeT{d{zgW+6sWR;wu3v#)X2-q*_C7xprUK-X^C+{ z5D{+fXe+FRB?_F&I*N!Ogq00Ehy)IL7pT5c5YiCojSVs)`#J;|s$dYFvYs^YnIHoZ zrU++Wgm0jayeLz^3t{Hzr*4!}7D5KXL6P+dTQ5`@GN2tg=!gfm732<=l~mPTFK^OH&66cVMb8G{h5Y>ZD7;5|s`7NP$)a6H8x; z93j9*#RjLK7!(kos{%n$e5?a>^ofo*JwLpazpSH^p{x#8+1*P=CBV>>Kr!|73?xEK z-Sx>dzT7ZI2!C@uf3lSa$`eQkW@Vrp954rE2Yokv(*XY<3v&lEcQXZ` zU^$GhLXfM9HpbmL$i)%mM=}iv3{qB>b@kG>@U}35Xj=q%VGy!Dh6b)kH&di8nnuhb z5Jg0rd&=X%cRx7;v>Z{+$)Dij12cpfdn?I1n`o2Wyp+9Vi4@>L!!pXvoNlyMwjtDuJioCx(I?z`c+=QUeVh`Gf zw)g%MxBLxa!2kaSgbMmkI~8o`=!EDD^t3Snc5^jHQ@I*@_QUI=9C-a1m~%!LP85rz z*ULVFakH8Y*U9BwIQ`_Bo*kq1D30wy^GS^C z^6wuN$?s1=df!a>KBx?>s(fBqyQ`-0eqaGj)u5(tXQErht*}_E;ae>_MxFDof>z!7 zi*YQWn-dSnI~&B7PoExdt^PvW*$KSy9@Zf5kI*qk{QWR$KjLp7u%~t&Vg5&Ksn^!K zbD)Amcz5kE`DgR(r>O-N&tWw|t2r8>TVFcD_edj*^z3xt6WM$+0-EUI+9{WLw9xwX zwWg%AMn(^$+rGD5eEIf$U>TZ<LUas5SDENz(5hnzcG1T5Mfp3wHy)9RaVjCky?%n z)tlm)n)WJL@89cq+%ZS;vK|o66Qd&*q|46PqDERS7Oj+C)I|GK$M4UV54W$#4Y1Lu zfDaZB>XG305p!eQ;O~C^vQpxeSIy?+LnxD?Y`-h>!D0^sR=6+@rx?S89=V;u$k%`8 zk9y4Xm%`Oc;99o`^Zpw#Qy|uRDcL*zSr-k?YJ`0EE_rn@hmIi2ArtQ|MozZD`YtePxS#MbB`Qd1-W`e9+%^#3L(sL1k=$k!A<9 zPrV)xy%>yD%0tG!zL!u}tDm;ixz z=Kw(x8DCcaHpEtv^L?eQE)x&e?5_Q2`JsL2fCZsPcjy}O4J%)dv<;t%fD;N(V`oJ95d4sOgJ}Et`#M#D7NCmd0-_p4*t0?aD*X@ zW63>E5WN|u&**=kG_o+TMKok2UXd~2E@wPOrfMV5N<%Zg4b^*`hy3^cLNLY6;%%qR zAoG$+9%-um*A+@t7OTQgqs2opH%?nzcjSe`j z49qeWSa1{le=L}BuIqVGt>JL!`q|yz59*G;otTEKH=XhRGDFQqDi8SRk}pMNMMNA1 zdY59BugueoBy{I?Hs2N@0N)C6{UUU7j6C@{4dU@#HXTAZ$;vCQx1Ut6YtQV{OWs%- zh4{}|7g)YXmr?SB`2K9>xOuM5syVA4%J2n`2CgQZPi5n*I74G&BZi7RD`8)&mKivi z)?i;CX;{0vX1lewy_lbu7voDJiS*#fVk-2`Cc9_OHfL>pJb7PB=mM}E?b|R_p@oQi~ld;rgQlB`vLMbn#u4e!t8O z3=HNL;IaaHpUpx?pCt*s>r_CN~R;S8hvKkV7+`n?d{i0I*@ z!u)hP;oySki-p%BBmf5m&F`g|1B6D}vxMDe=^u?I3%M6aM>J;@II*+}jVJ>eb+PXS zn4JwGN~k3+ZNC1CPA>@eWm$vxZP0Jt>8xR-?5&yTHGwp?3{I74)iW_PH*8SJRe2+99_xoSG~-n<8jue`|5~D zFyC=}DFZ_v@EdLSg|gUg(8YH@_g>^f*t-4`zz`ljd8ODUL)e{fAXRq_0_}A@%2*Ai zt{R@`I1F|*#B?B1*`)*u*86=ldXDg_x|5GN;2a%sHi|FnXa+dqMw$ zN=M|A2%AX!A%VQDXrWPhM=4^C5HQy%&-|2jC?>IMe53g*ZU@uJ8;N6_HfY=jgBICh zs(GrEe6$!5-|56Sdubdh?11v%*iA#h~qrK+hC z9)i_;{bRbks_l#lZ9M8EG;#*$W!UunEki&;VkX-AhZ1c)8&1f8h`D@?*AeH1gn*B7 zlsrv~IAUZ2{kz1#g#0OooS%S3%GD?{_U1USV9SjqA5)rT37$Lg

Qd`Ps(@De&xSh%u@T*j^VC$_;%SU@FPZMK7gJj}p3t*5#{eR*w>~6mK;(n4pm9}M z3?Ooy7iEXlUi-?TsCJ0K4RBI0dhEFdaNMiBc`lP4?9}FTH>K&Z0qr%+;zqq{6`0Y_ zv86bRM;HtMuZ}+dU9bEsP3#@IB1=rS)miyf_!uM6G>Mp=))q>E4sQ0H;FJ9+-Cr3> zN~=A-IVfAXzVNPg)q8K)?umu_5ViBeM>GAGgzUk9kpX$$_CQgH+C?ik2G!+uUeWG#G5{ep8E3U+hx?pWI^ik zU3ho3)#Rn2-PNeWa-A({@AfO7S$+Pcmwn}Hsfyo%wU&MOl?++ZZ2QpA&U1~|!2@ND z9Tn%+CdR7ouk2(`L3xMM?&3QaYN}lOozQuYoOseza7q@R^Dp?>C(bH5I)-ev;Ef-gI4m(R9 z*i=Ugt%?NHe>aO@%Dt|9%+B8Vd46RqUglEvAi3KFX&X|pJDyDnmQU-}zJ8?hbDF}l zxytR#Hcj2;EEiq2j%!+Lz^F^`%q+mpF&RyGq)p!M#_k=-vOWC!>yY67yX_qVHdYjW z^6&$DXzSrH&DnF68#&xbrav!gTyOSF%z|D!!ghMr*(>UTS6_9Hc*nQrw%H4FKk5=* zB$s*lHpsDjU9egsYyA4MQ2aex|KZHSINmy@M2IVN3}3-U8P=%ZObGoEK4L^=E8aB{ zL!$e*=Cdv8BD)0_C!L7K3G;X9j~8 zYgVS8B%1@j%}-weauN9H-(M?I?WQzaho-XbOlkhwJn&m3@^g|2OG?;sM~N3Z(mp6Y9Ob}J5-9C9CW->@^BoE6mGwEjQESYK!+?= znXE~&_j=7QQ(H2V9o#04M-Ju;c~X{tu(TGonKXTzCvi6B+uL++94F-P^wwD3rGD64 zlspbkIIVs2#94`w+PjA@KY=CkKR#2}q+kc=$%IvAmQ+?z7L#Jp=W=XhQ5n$N3l&oW zA91hmV>YJts;1F7id11zdb3x^@R*A8pX4*e)V?ntN`!8m1@Yb7#^_80^V3t*Wt~`k zAyne|^xxdlEXys9x2WBXqPdT8`j*9S@|HDu&~qX;ll&R;*guXwowqIO2J%zc8zg^q_#?k7Zv#baNOYxbn0*ZEMdC+~S)?tWp_qDY<5qgoML zcznPT#$iM&sFcv@9CfGyHuYSi>@oq9h)#Nv(1j;Ejl}KG0cP-+?Fpv z+-g%EhR**E>cFI-U)vZOw*}jf(h(VPZwejT#946f8j1$@nzQ(px#-V}fRq>FNT29N zk>{d*j@0KX;`Lh$;i+0}yjL5{qlt_s1@%F%P@bBW;GheYKeL{wDNKfTdn zCvU4YF03t<*X_P2;f>EWptKXj{C6|DC?r8u|H3~;bnyvuh2VoMHrYh`BTi|%=aft~mpM;{E^pigb_`w8AwPYk-zsW}LazFBULjk~wNab3z3 zZJTk-tR=0W8>N|9yS<?J`)qXRN)V11KCRwNlOSQATS`etNc?tzj!t+Nm9Y}{`?pn!ozfhS-U(S&0*?pgm9u)c6rdg=6+Qf>AjIaV^ z?LLiGXaT_neVo_0m)+sevuyarHk<9P=6q@QN#y#k?>x?^8vVvAW-ZCH$f0V)4rg)h z-`pI50+yvNGVqulJa183)*>TLU_1l8_*!|!;0i5B5la-_;Nt?1FpG6=*nWH+>L*B+ zar*}RIDKNaTKXP(M{sIsudeo0M7w)PE!xHn9FpWeMO&uJ-x?tS^`_@_W(;F3^Y0j; zG!!0gjBEvO55xBrMzulcq7a)y?;+CjZf|wAmr6)BA@=kAu5uvbhxd}gFNbJt?DUKl zP1kwNObm#Sw8GeRS-5g`o_w~rBM`RX@bMA!o*l;3@$vpUCc!UHk~Ity&nWvBs4hEf zS=j}OhVHI@BX_8;Lpv&r5?|Wa4fQcM+}!Z~QP#FeN|CT|-P_r0Keux^Gq&W%_WB|f zoVyW0YjZQ-N2c@!gUdQP{wU&FIJZ8b!gOS6H*)^0KLk6&^2#hg=aM!Y?ZG;RAuwzShD`(JW&~q@w(Rg zCnqkgOP;nFh%?U*uKPZYDeqtIqrNU~`y?OGPz71z_>QAGPrf|Hr zD!!dR=;v*CR~(u|0e5cZS_TgVK93qH==Or?~Ze1r&Nv&4ZM$dbz7nx1X#O@iDp4eXGfK0I6y>MF)oEp;a zlGCBMmzN6Fac1QJ3`)Jg`DT8c`eiU2Ka9p9#~ZzACu3*xgh39F6q^rW` z$L#tQ0adg0tf;5W9={V;93H6RIs)P;)2{ zwlV6ZtYO=t@mrj=`m&ZJ%ZSqT%3F%8agcucNLteEi1{nVmNauple`A-_?)??s9q1% zSY<9ERh%x~XO9^Y@|$D8`I_;X%ZPbk{9a>8 z0@N>AyE8c;SmGntw-Ph&m6)FbkU5USk&!;Lf$(YhB>n?>yX>qZ@ZFs9pTQZY;Us}60diG~O zn%lyWNdxs{IAA;xV{IJ}cj2d9)#C2Fcev3*B~Rb~(5~7IUwv+`qPnHPL9OO(t+BPA zD=RX6e63_o=r)w=3{_)mS_IIZY4IoEC(!GuvhaMRC@( z4nNP#)8y$PgeKX3=|jsniH1F><2hp%c*LeVPw(WeY#MM7pE^sLDd+~mPLnvXEbnDX z8ktwejGOuy+B}zUY&@=vjQwNk_x$re-8^-R+Pw$JavDfG+cJ2wm?I;^#~_T5+pZut z{CZ=K@XrzR`IZlsuXjI*!%_z^wkajK3NAvaO z^uGXW1SdEq#EsvIdw|tDz_mQLY56j$CrPBJ_qHMp!-$OF1DD+1zAxwi$7$%1f;1J| z2JvEQI%~DyfOapY<8A%LV6YAP&jddSIze>9yp{Lw1}#krv8vdOD?A z!tMod{*lAX4M1{@ssBy7pL&Azf|R=P8xvra>wH3Fgg1>v-J`k(xciw}Pa2Xz9ZgaN zIKo6SFjg+G+ypieAQnCju?}Sa1@MGbwaX!a>^5k7+4s!M7XUI-z<4oX>!1=4)K_AW z0aE&Qs9rCGf5DZD(HU^ra_4>MV<3H2uDah%o?O)CED1sE(KA4I|36c>|4y;P@qsDU zL$0ih)wCLh4r>P^aCUz~6IXx`twFv#h5^O2o_P@&!2<+kmp7VLfAkf!k;{`|m%5hZ z&xBq%(bs)dC%KRyo6&iU*%?>|#P(W%03#>+1*@0*DfjP7ygGij@?^kjkJU`oV(k)2aXiyx^2F{#JmBb=C7#q zSBDuiXxabKrw%T+)Gc^qolSaPN8$c^EV40%(6n?&?~sX5aDkX>b2<%C5qbnLoP3F5 zP};Bo3v6S^8chblSU4TfPqw(^wTJ_F2spBUf56=wml*|g*S-!50i;g`Wql};h7ldn z=JkxwiUx{QVB~)N1E@#lQFHqLMkqma(|!D^{*oo&{-{K8?w-#LE_UX05KVq*=oDZ^ zfTyQKa4y^4Qg73!Z%%jVVCU8n0yQA2gDLzW061xBBQqYA{V%vn_dz6*Mfz>T!rSo^ z1$H%+aF&4MjQ`^X;C1ExQ`0$0^Z8dJBBB{@sr1NR@HzUo9w5XHh(}(9i3r`|1-yL@ z81*`+WlRHB5|NUfcbS1a6HR41xemq?z*=2yuqa>Gk_BtMKAK>8fbp*Yz^=gFc!YzQ zy+Qm4{ole=#0xORGf{2pg(9%u7atBy9n9qfHfX`jldD}%t1lG&T;e~NJ_DwkBn#~% z{{vV-L~~^_{4H_Z0xH`&^tAH{y!(9=3*p<#E9C9@^6sCX?q;HBRlnIEL|uLu!?)y|y!5Ml#Q60B_ebBhgx<4-4&S8@lyw#4S(r2iuR+VzIS%D_J^G>krj@O*D~`}xQ*pl`74y9<{_9ikYm zAJy*fZ9_r^wuSb?Bgs#|JdfEqo;W1q~(DPfc9-C;M`-)5jC( zvJTfecOz(p?4onYtbM-Jj<*ma-^75~De3?CT)X$nem{p>3i}11 z@1N)Bs*ljKf4LvwH@33UjXH1lxnuw1VTMXzFFlI#OGfM)lMlT!ghjtw$H~z%&|vjn z4Kn}|^ob}Pe!{#KavtnXRrAvawR+hbfXvrhZ|hB3f$3v4=>7_V{S~Nu)8+CQ}O+W1}q+7<@f0{X>o{h2a6m{bxr<1)E!*wRMTxxb$x^-S<(QBuV!m7{QzeujL z>}MUYZ3^m!7!K>y!;!{EUtO5MPKb(%zJ_14ES%==xn4-fg%HEp8D(DxGU7_<8P;g( zlD4nSICkvVTs$PmgE4Yr4n$(G8?66Ut~U^15wjwysSNbPN8gr!0Cp>h=g2{=@;J>7 zv~G>$Tw#O;Uvlr2#II}k>-^vf?hcA4gwiZUyZ$&sZ!CJQSJ~-m|C}fu#dLxnk*v7~ z?M?4jV?REvs-(xu{?A)xh9f5dBV&T-L-2f@^y0wVo4ry$3_U9^>zQD)JZ%;`uiRxG z8AjjDIc%?8&kyWjvf)@3R_p4Ig3MCicUZTsF^~QV0-N7l&;4{iS4ZuRPW@9yuVRNA z^4{UuzhndDa#pRb3f?OVdh4*M)W0;OBHM+jVQG-sG># zqi0{Dh4!kdYDXDr*{$WmS?Bi)W3W6wJJVF~8IFH`jPJvLJ@9@Ul<1D8y8qbh5=)4P z5CrO2WYYf*>UlBeuVz9Uy+W%QFL79JjcLyO(*2lc@jy+&{^e!!Z^(Q1yP|Qnd4`FG z^S05ryr;V0!_t*8*?RzrQR1a4a&L4t+6eT5{CL(j7HB)DZLy( zPPCj_o%@#7l7fh17&WyJ@qyQ0fEEx>_Fo%QJ?9XfsA`K>ld**9_KO# zS0vqhiEB51E$+Co&G*$NSFX2GFR{9(GcgKWKWMQ4trsAO7Ty7cEe zo<#HXuD@uk5ezr5wOV}SRX&0Kz%sk#!V|5f6-}4Bin}l>0PZk8;8U~v+_miz(fSF* z1GTzq{Z~4#&1RxiZAnzMx^OFw7dDl#m4p39Cy=33mh1Va z^g9=Mh8%vvL+L=wwxl0=QGdHO$FH^Q(SUfg<0HnUMZ%-Eou`?tK`H-hy6KZA+NVZ* zp8~Z%E4w0n!nymTciEVm`3n})1<17ZkA8vNRoc17%HVduoc(;nwbi?fmQq8AY%k~= z{(Lu$*S^#jd}cQnE>H^6mFErwv4Ns(OidkY#>isEV^c+s4~e(jE|?T;$?R1xSDLWD z=}RpL{Gf4gTGoNna(CjW`~6e5q~Ha7ryi(Ysq;{n=*>$2vm9(a1iQDmnFOye(MQo7 z&G#2YJ`fv^t%g{0Y{LWs#r|gQf_)N3QQmB!6kgYk5tu+)jF+`*DCybo_>xaEGMuAX zt!8dy!o}x&o3Hr^`Ylx}YV%vQ6W7mTd`lT8kZHcyNWqyIR?2t-6A0dD*fj)lla zN7zpwEGPln>6zrEdWU=%{oQZ7>@b@f>BkFbkI>&f(OHRmXtsb+oR0bNF*+}X>Ga^C$Xm3dX*rpI z5RqbN%aVjwCieRi1Q06bJcR z(}GR@-3~cyc?e5pvM;svQJCX&cIfLvB3mb?HQ$uiw!c$gk6{KUl(_#dxbx2=-xJ?| z`}QTWBRgH_8-1?Z-IMY*3S?v&#B>A%IjOYo4g>OUoC zAx>);K26_~J$ZH_FZ_U6;elDbu}mplACJBZtmBFLN$~5e{R&bLC~~WTA?t>*&=nPP z?f{hf{?qY^v*knjCVbgE#UFpS;U$oL@()x8YeEHAryrpF_303d zQ`3F(-vfX*Dxq-#?FKZ!@CnW$=P-`o3j->$tQ zddJIJ^2b(ZugOaPH7lnytFljJpq7-~gc2~}nR@edYG3VUnb)wf!ubwgjfZRBIVGmQ zH@YMR>Uw)H?xoXyk&NV{HBV{c&d8jrSIU5VcILN@5I%?pos@lrqzit*h{Rv@ zUbFMTM(U3BLg^{R>PK0~bKPA$F=(j|V-L~n)Y`{4&aop5Xj@^Kj$xV6aRMPzmpYqi zd;Xjd_l<76x=vl~o>+m|6ESu9Kj$jLzg$nUb~b}vZN9PsfD#qqWl+aVI$aH_nB--B zDgJYxcw`PE&LaocU%$mg_V2c2B_*Dimww`2RFM@xptqO2U{$nz>)&eIrv&M3;`;m{ z$MslI=Iz=YVWk%x?`@c!!(b~HZN#9K3oB(IZe2O&j+h<;YU&ga0KbxCf~agD+zWN2 zN9hPHIjM9_Vzvu^y35%_)UNc$lZVyURozW&g!bmTkgpR&@yL&fsnf=*C0EIK_+U8d zJTi(dF*|x{jZabS=CMnDiAU|Z-wVeF(aOIrtLexi%C`kSHRR7#+T2r3Ig`Oo_02G@ zVHx}SwfUWQ_g^!#9WFgr&~7gcZ`pry`vSbBd+~boFuI91>*drOuKL!`V5=8_no54z zG-z!mD~IPy>R6*Vs% z*-jFyR{qzZ+ITZ0)VU@QKRADyO%$Y*ft6=tPqXv2oi_S4n_PFt4EJlmjSoDJ(E_kU-X$bN76M=w_D%jVfTxg?JiJ@Y0BN~ z%laNUT!FT_A{LqXpu4L5?+HY z1zI=6G2-meGXe~e3Bb9!Bphc;g$YgjK6Na}?2wrFHEF*p_c8|~CO1^<#*`9rWsJW! z8(pCzmJD04i|KBTDmA|OU#IdnDE)?CIz0L*{6v@uOLl1TofHw)_e^K{wJN&rnngns z*IaKx6a7OvRYMQV%0BxYwf~efyb?r4ZeMAE%5q=9!;+!BPrg)p)8w$s7gCgCM85fN z0I%p@)?Zwq!7M1rk=SI$wXovs`)cLaq}{>=6sup=Cf|3E;G!>@K%O^F)iOzkJbvh1 zn^xvMjCA^#^z5Tx_y8d;yv+I2Nst+E)$IIk{aQ*urz?944EnZ8wNFt7{dn3^<*rLu z7M>3Bp>_L4nllL@Q^ulbO&cJpax4#9f$z7Q1QR}yqP|M&tC(|fj!|0iU9jA##A82} znfCBqxdp*B_f)S`_=?v2X;+1~eZ2q=SQx0d8-3!eAuYoIO`4`3lg`F2rm0e1lGwtV z7|P6^z;Fv@J?Cwz*r~-&KUcGjef|8Fi-!m8<@GYH-FEg3NTIr*w%wk6zE3OZWA8w5 zWoh?S)dQA<68Tl`h#@l&CHRiqR++ktbVYaW*7Uf5*twaDMb$b_;K{ub?kyTR8MA9H zo4-)jW2NrjUY2^;^cDE*tx5Lx1{4|mDD#{Fb+ae5+^edDW9DoFL60HU>lQi=Q^ucv z%x>ZHOj3u&vnjifCW6bm_nYm3)Do(?!Puic?}d2&WW*obwW| zc~(nuouQ#&M&Zm|l!k#!_0lyF=MS}@4<{+2f9=Cb>i3JcuUxL%7-LD-2(A1h$byOa zIu~$cx%6)Wa{aXByYl7HJ0>fiwyykxPQs*6mdEa~jZ#=Tg8Y7|TBHR?fcntMjs*To z{VJzvV74LZQ1pO)o#3je@fY84>x?}@`zhqNx2)W+a!#grOq}PsEH6%JaW@H^zkpW? zn6-;REmN|3@$}o@osv6C3ElkkwxC)!g?Fqeh|_R(JT(S6g`FG(o5}9;fPn7P^i!H3 z*6RU+R7>5<&@QnXr@7pXH(^-| zsM2$BQEpUZCco`>_GiLwuhM9JOpvC-dIfvL8_*t2*plpFdb6ZblLwOxbpba5!L!R_ zILAsmincG|^rB)o_gdn*8@*+of@UF<1oAO!WP39Y-nkU{qVcgSp4NA@^XgGrR7lZH**2A zK@G+pn|?(J(A7ICev8e(iDg28ixrTCl)daJ3fm-{x2ZtiKH7tu&-vojj z;j>j=K8u&+gR&X!^4+#u=T!}K)&hxwMR);F6-4H0d z>W>7yv;ng7+E0&sP`PUf;_bBhcQrvL*(VSeE%FgOeo)kz^SB1_@ccgyr0jR_VJ@Ga z-iA0%yQXhrJH2y5NPzKL-6 z#oCq5`-!;R-+?7u_W!f)-#$E8wd$AFh2o5ycc*l{+r63pZ(KNX?HZ0hQ}c+M3MSUKHtNWABl&j>g|i~vC+B-raL-zqV~!*66Md#_&)!6U*+{^b<>n; z-It|1$s5N#awh)C&*GsXWnp`V-F~gL;XI1774WDh;ewJmWiR@>6bFMlhq+}QNm%&K ze8Rh^uK&KnJyiIyqw-_k=|3K}r6t5aN2b(A;uk%?kIY$5Lc*%!yTu!VPY<(ch8dtm zk==KdV`ia}=TpIQQWi$s}D>E*}DRMdK9`$!e zEzrE~(TI*j-->Q^!Nn&Fp??y^DVG3#7qs+_X$F8>)WzEE_P&G(?)-v={N}QF+_|xz zHv@>Dt}QS8V1lAYc0TVNvcFXKbxE8}!3FhfS>$}mr;rwn4&Lp~Q*dZ2%%Nyw?8I@j%WYr*l_$2B9mSAE)Bij*OZee`~02u zQccr9>93O8KmEqu3cFZYR_+F!dw#*O<9+E;0 zLJVr-T+FtBzBr(x&|`jRT|QcG4C8#uMyLu!y(%sBu-x~4%Rgg}oJ#^t+uZdA0Ou~3R#Zji#*}40W&IYq2%5UOrMw2mAa)VIgD|%(COS@@^%G0d0R3ziCoz&G z|3q!eDA|dgq%Om$%e!M5+|*B7qc@>vW#@BCKM406AB^I$LkNcN5V2=MuAjC7-Cenq z;ZUpDG-Gey_-=ewV3SR7%X~$nINoAYL9V9b%;_juE_Z#KjNjQ6C+}JxtFMh&EtJ$! zLAUVW_51E`mw>KJRna)~8;<)>F5_>7Hsj8>H+i~P&nP*^^~Y^r#N=rKO!S<1G57j`A~iP_ z{dyA8_tw0E-$abmqH{;ajQvB600uOSek<{vy#2g(5O`FGV*~S4$4qZVv?vlxe;z*O z#P&yqO9Y`i}F?!RS7xPy; z+nUqY%JP0^pk*A}oQZtoxwq<|=jw=G=?oJ+a2%gW$lZ~XTxZyyxruz@{fcY7uR>LO zT15l1Ss{bBWXDMsTsb$Oo;^9NCaG#-{zJm}_>GhBaVYvSQ8h1c%BO8sF>^KGQ`WkU zvc{ir?k~${3P2&YGm_=*k@f{gZjXgKPbHC?g`cvluFMxcAUzORtwevXIg_sM zyW_&KpitiU-aJF@ljbRl+>N}m<@FOCxg9|_!a{dHUHRx3I`mlAzA=lVhdQu39vqmi zxF>1EI~kJj8DLG~AIO;d{j|U?xAeKr@e;*$u8}@Hi}akC31U(2)pevx3+DZgyQnnrS-IUN#r12 zvWdk=racySC?wix{bKN?oYa!ioZoC#1H|mr3-WK}@#?t+ZldjZ8K7;nL|i}PMH(Ty zR(&tLG;EW*AlQo*$<^>MHmQNGwErYw5B=G+??v<6DIW@or}Z|0x5&gB2muaSt=b$L zKA*(4oOh+&(6`_z&n*r63%4UkS^bl(>K36U<#q-g2+lJK15FkDPuRT|2%)cebz#jF z)UH0eI@^UuwY#V+rVA}5zs*#u))$1!!*?pa>y53&Dkn8$uQq2_wd%$d-}WN%g=Zvh zc>Mg*nFQrx%4%IP*dVQFesmrDEk)M;MVh|jC3TJO#N#)IhqQIn2=%0 z;}oT8(3DF}|DL5DEQEZPKMH$t)WfE5<0wL_kEH5%7&=tcEIy-U5VSNZcbLkXZtVf$cIrCt=5V0-tAvNgbE4@?U=CV z*Ie4el`hlp5c!7uwB@J^J?FhbPPl>iDPz_@U;0<>Du_d~wF}O=y%#>FqZe+l-}_^iX5`p?YJcF$^~;41c6ak`I-V)f zJMygtnc^7;+As|!OI?T0!BhPYiXeB0{KlaGfd1P2Y4hxT=zRa1=OwMY50n{pYC2M$ zZ)_-QSaDgsWpq~B05LJ{(Ty`orCCyunGe^x?o1uaADrMp*N}cWJ4>fPCs<9E(M#1V zc5|r|)UPSaPoms+9I;uy5`tB7TjteRjN3iLE>Z9N7`xa>Rxh9DF3(>uqVPo;Pm=ei z_Hz{%L-Yo{TB%}Ed@c>cD-QwmkbKo`ALL4%xdpWp@FEX2!=SL%qV!fmM8b*d(8i6} ze;dVyoG{SQ(H5o zgVxmDzLwG}R&00_xyT36SbvjV?e%7TpF)BunN*~;-d-50O%7T)s40w<6@}?!Y{j8f zo!F`UQH&>e!TWKb&Ey>}{AdG!(O)1i26?4PW;saruYq)*_7+W!3O&Fx9aG}&eH(RtcK-4n$M@gwPDrR=$DEBx5>`tc zuOjaYAz6=Ok4WogxX`hbU(=#BEF7)BT3(yE7+>H^_3zqw{q1s6>E*y2f!#~!&EI`i z)AE_;8}es3jOR5EfRn?t*97VDycgcxV0v*w`|3>m{?jpCc)s6*Nz4#{{+B}$7DVxc zy*Q=7n&;c~Ve3SU-OeR5tl=-I3-EODGcn!9v1xvqwEl=|nLO%;x<=x}f2Tuq)pxTE*{=H)}xy4H0wV3(>H z0rIhtL!rH#Xj0ExwR)X5q_SMtb^+2I_OvCV(uf-O8Mm|fWNhkv5>zH-7qONA{c&&6 zfQ+Oyc?CI7>XP>#F*(7lD;nLzLOCZ89o{`Lm&o2}pPpC_umIY!;3=xL(^vk}NpM_r z1OQ5)4Vj{1N|`~IM`Uhy@qc7|AcAw))I25dw68mh95(q9B3fXUD4;Q=eC--3JVR4{aW#B{(Q+ZM8O6^Zo}tF!LhG}0q<jdD>G3>k*w^!M`lBW zB3rgdWMzxnp0`37$yP}AxQ)mN*`w^u@3_$G{d#{szwh^t@8jV=_jO(8IL_ld&*$+x zo<~NE*Xgk@0mR=>&dDaNJcmKk8H7$F_SiUSidxMn;}ry8l*n=f6e9&_gsgGlx*HM8 z%jvRb?wXF4xT9k78Atp3_fOBnAD4=dvaDAu&NGc|0ix?_?j&ZQxxx5=Vw9IVS>ZeB zA>C`E1=SpGO|9mt&bLJPoK+t9P63* zctYjdD4=0)WC;S$J;;c=UkI^8B?=)3wx{$R6ra5=>~<0sZbIlB&A-66&lVK~-=?n4_4Hmg`6H!{^OoEyP5H)L#&x`B8YSjT ziWSWRIS=ZX3LW}PZVPla_c1v?uVc%7LgOz-n?IF zxG0V`Z#VGO8ZAQvW08GY$}o~yoCHz{7+mXWOE)2W(}?o+3S|DJ%nFmakpJGj4r5U; zcKr7#h9rv;^$143M$Ij+?q zsp%agGse=be9y6(-zL$iuiWEKgiK|bPPUcV;}4);x>vek2*FJ(#Y;^;5f?Jhm3#VOLA*B@6= zielUa5`w;uOLJM?8?TFx{HCNwer@emo$2(8{l zMhXk(9`JD#MQO`cYc7O26wf;%!&T&RD|!83AQ_NhRt@*MfB*eR0VS?P38sJ5y#2)! zY8MBpaT%f18t=om&>!wlwD&#R3*&L!IUHlfpG7AmUh}y^>ng`29ikrMz8L{n|JSy$ zqwbLq0Q=7jXX$$mZO>DQGE1Cv7CEz#g5Rpsgeg%padI_%pY97r3I=5%2ve@B!1Ux( z#sfRVBA5a}0*#lf)yGL>#5|kg-QA|n7tMr8k2f(<#IZ`hx`%tPAV~0F>8ScKY>_;} zxjd1VyqkDVb@utKn>>?&>RXo^LwhXr<8CHjF#A=1?B;=fgenl5W9dqvLF4pRmcv?C z`eYJwhvzlIZK4H(A{n0y!hUCAW_f%>;HVuWq_t+x@6jE@OFfSJg$^9djq>84{J3v^z^d4BznkK@Whms$fl5{`3M32=r8{cJK7by13fH|CRrEBe(6 zPAisE*M=VsC|wdMGW4Ip!h@t(^<`zCqm_dDiCwGxiE80drru|c8X*BZLNnvr{=wg+ zL?_0Jf(W;cG#!Mo-~7G-$JiF)%g%R?VZVv)#XmiDIE12w1m9e%4xm;MUGH1j6{K8N zva*DyF5Zfv;(a6vaKA%o8AwXZeE-1c-SI02YSbAPxawT_d`LAsekWQCMUfl zM(w(?RC$4{$Iii#M#*E+-i21Dxv;Ywd0D&DhmZ`_X3?Gf@FepJ*&&JNDy)j;(q=T# z*_u%zM@AVsL)66NBnGmW=KR`AY$t)e75=E!kF+aOnU*EM`Oi-=D#)V_q7fwT!w>`? zw>uy{rrZ{ldU@Cz_8P(dT?m{bVIgF7ypM$So)aov6~yuyu4cN!8ziX*`WbhTOz_J! z!AjCzo`L-1?n@?YkNsZVuI)H}@R&CY>T`Z@yENXzD~65bL2l($>JG=D+GAHaOhFRtKRi zZQ+G>PhwnSLqpnFFT%rxOhOO=561ydpq(J;8p$6Sn9$WnR3S%Ci$20Nt{jGN(n(?} ze6L@~v%uRsd=&G~gbo+pdz@Lt&6O8#+-`CB&v3%S*?yQ5bHQ%o;whZ-nH_$N&Oo{Y z51_^678^Vd1bHJqW}hs~|$;gJfISw1>7VTCIqT14O;)ad4PP zUO#)LICb3hNLdHQHW0{CSYW~gxTFRL{)~kG#X;}h0NboS?miA;kv{I#(no!V^r)8e z)zQL+XUGWd9&FwRi<0g&+kqW(!*Fxs1#OE}TS4>P$zB}EPSE_*aif>XgtVQc&=5>t z_2l1GM1AmdE!tA-xd`2BKhNf-lQu{HyGw=q4;YgvCx9^tGo_1-6MxtNzq5yrA#4xx zK++0@1f+4|&Ga-Qt8BCJ~zMQc%?oAUS>_GJgxACM82ZkG7wTo{Zi>)$n0!IvK zkM|PZJhCMsyP^>?hX)j%-@SjH(?lYJ8aZEc{b)63ArG6x^J`*LT}QeK^Emtjqy`Qj z&jNdbS7+Zm@tzpx3~q*EoD_mRHH5QZlEl1a%FB67Thky{tOHp!kY;x#>X07`PaiE* z*u96bEecHkhdcx5B$0xq1C<+aaaVTNht*Y8NyjH9`U45vjvrXq!BpakMR=X@`ks0c z|IGPYPFIC?S1`4=yWLq z`STflxG#D0=})ZujC;7aPYxAYHkAG@;Nf*^d~e}1er<^I0;4{V8WHm#h==7kMelhG zAvQa%oxOu;{(i)5#@Ddnwrek%) z8z5R_Nbp#%C|rwENB)1h@|Z6?e~pj^o00}56?lX5U)e5fc~$$4|9Dj6@*_)8%r;v~ zFgp0`IZWwz99nbIq$@j#lK-!}ScD@~5HbDDyC=Og<*#>U&N{090Md|}Wt~oO$hqkD z{)chXJ3T>J;>A%Pe~OA6+8+ZV_>kfyS)3wyw{C~8aKC`zC}L8m;$Ml--P=_Z7um9T#0#1zu2Z)iK58gT^w*vWGT3`IrM*iR~U7S znx34V%P>_94=51P_n4G+dDOP%)>UC7+-;_Vp$eX2Juqs|5}1sZAevht=l?ga(a}X@ zFYIIPkQf4__)>JOwr~>tokWCrLzo2-rB})LacF|40-a24c}Wg`4{AMo29kv))66pt z7Az5htMQyfM{5F+-N9C*WOc{K{y4`>*BJV7I!wB#P3^|2Vd3w~y2X!AHpcf04Ya!; zE2KRE8464B2%@v|j3gGwW0J$v)=J5v~x*esZ7B4Gcf*naQcQV`^d^( zxryTmt;tpA*`yi%h<3C5hu9d2=evD)_KzR|u;p-%=I(jNJL3oxLK1{+c<-oh2d91- zde_r97YVc2rDr;5rt6{aROc)YHxCu$c#5qNgNxk_v`4a`{mm+~7D3wN0knBL_-$l3 zpPoQk?~PNox|m@sPM2kq*0;gB{J5i1ywI}G1c*~!FI)~=zu(5o=;44-fL zCwr{boerFmPulMq+PZnXO|%*dIfosPIq?Ja;jON2r)W0H{}Q7gO&F{#Bn_CY5xu}8 z&(t0s>K5^SpLWixN@ST+3}t@q4F3Z_BQMhYYc#4!9=7`#$ z`N%53^HYycJvOXB|IfA;fmNeyg_~j++(mtEGZVOX0+;>NH?56F;}13ZW~KfPkWukH zs&^tEBN#OmVF{Cw`SNQDEqy71@#ORnT8eq~KBL=a2qFhWa;L_rsFX}*u(JNU> zoRk@v6NC*;J3_iI-s@o5FE5{PInCijW2o>}J!Rp3bu_Q@h7;&!Uc;YgZF6W3>{B<} z`6jE8TG}tC(--ysz%CHaotzWEwozt4QnH~qiJM$ZJ>RWkw&H^IT z!2kL1cvf2PMu){o!=Q(Teat^f3#>d4%-I0d80`BTIsJ5rKmK;*#1$?}F44O`9fH2g9*tv-bDcg|6fIG4Ul_E!J}<_9cvV0(Gtf z<;T1V!mEXkIvAwWmiV6j6lD=_RNq|GmX-An=W|zgo2Ck|nrDc}tkVb$TVTtKnW@0_L|!nZ3UBYGb_Gh}8~J8zQFM z_gHSzMHJJOE(?x5vH7Aqed+P{Ddk&H!PM6}-prVOo@xy)-A_ zb~99Dl^i~jtHIXHQNSHr{uBT-W7~SOKM!kmY!nXro@n!6gD6g~hlhoZV z0_oRagU5bhUjpK80YJ7&pj1##r&e>y4^CN}w(Q542Hq#HDj?gc7ZDLs2Ne90(} zt`oaY@l%I$Yy>*%Y)?$ruBUh9kD)C{b|1G1DYktH<=X3;@@IVX$1@ptTY@79s?O&8 zVFEY}uN=lQN5&*=*sa+&KJnzGSh?p16f>zWXc*tF(HESF6jK@1;9wdlYH%GyM6HZ` zpAYRY*EH@{qCjb>KtVFl{>`L)$?;K*Xqk=K;}Y3bw=j3S`4y!J5~*cHBN%fu(isf8 z#CC(9kv|I&z9#gM-ana8wH}DoludS^f$rk*o(8?-Rfd?%pDTm3P&U#y-8_@1+Rzsr|f)9O2M>6ONM`FS3!lbSBx zv7s@vDdsNmK)+3qvi!&_W#6Cr-`Ao;P86Ph@2>T`X=ruD~b64@M^ za|_{=Z9NZ_3dCP!)-aP?me$R?$@k>PB@)L0>emCOmb&=!uF%~28~34^{0EufA3?_%IpE;7$e_Od?xDae0rQfnUj71ob8iG8hUOZh!}jrO zIkdD{|AQqACg1rsjG;2E;>hS6cVg+-EY`& zS*SBbWl(USe&1@M-mfjS9LX$GcCY1+Jas@B3)|#gFZd0LexFGgy4yPJvah^Ze0*?A zE%H`Mw+DW{`lhMTBQ1eW<54Z9%Vdvj|L^oSPoTev`KgD#+1KuF|9EyG0br(&eyd*z- zPpU7#y)W>}Mc3$pZB(-ed6KI}Y+1Z;)dF=voqGV|kVanI#NOL8nbTh*o1;tS1lw42 z|CCgZqJE~Nr07IN1Q?=R7D|HIgbBUhzDE*#*?dQK7?#9eT)(*N`pVaZXB1M1Q3Vn} z0hHrd*w85k%`^;|@-2i~w6e2upZ#(H%~Z>GP3&`5^`?%uAZxZ zx^N2nfTp&=_{xKUPu7*jN@J9_(;9=bn-A>DU!9Wm&AqRKVkB457tFF(J;mO0qfd!6 z#^VnTgJ>-V6mC%_B{P9~X_Z$Otn60j4USniRG?epHSGe_$^916FIr-6flf^$hqi1{ zXq#KMcnV*4`JANjuR4D+qR$nfT%r6yMz6wJMGS+_a48-0+7)Nau4Ri;=F0^TXU2H0 zpyG_8cUeK2r8RqYp?{m?4-S>hnBv6UIn$N7g0`=%^b=nwZ{J;Fqb{=O4UW8MSnl*; zng66w?%db50>AMG!=;YD7tRj;G<}9z#FrVF6j~n;Cl=Ycx;t^B%6e|`>>fzgD7D>M z4rJ7K{5_R9sr{epf{Y8!&)z-&qJb-rTR%HCyNML`TtX2qo#DPRBT? z>lUC*rZ~(0+}_$43&HgNq^|vRpLA`Z?6;gy_yTjN{jY8Q9}UquMl$w2@z#8b*03epof48y97- z$r~WD2Xy(UWlAFsC70Ei@rWBHW$t+biuIO|GOm;n?Lj~I{+@X0k7L{Aw_ltqD0!w`5A*~v4Z!865D2(Y}v;Wv+|=_twe@OlejY%#~Oim7w1J14Y}-o zgi;Awrd|!&+0ASL-yy-B|F(w4Q?fqgR&!_4%v+NCpv7228b3#EDnaY?(@VXUjXN_l z_!k+A62Cmlb*rJdoiodjajzOce#NiOZF!<)_xx66KWvB~b@4*6x{ELKo-L-xExZ?H z6N**LIzH`I`CP|#CSi+QaJX*b)`uQ-h4BJqbPuYu&ZyjAoe*omY!|kG62)BKubKG9 zWfQ!i{1q8`dED~nQVJ0Q9yq1wXKiHX@_$a-e27{B+1j+>-37;B^afuhh%CK|Bp|Qj z?8!BtZn7)wML{1pZr-`DywwQ`f4z2VeWnNyiehthoQTL=HgcKgD;(TBE#g!Vgz#C+e8vH`H*Q~joJ5A?! z#k8pwq3yYS-G9H7!P**eLY3VK_MeiR4f~db?*Z4otP_5SeSD)_Z)b5ge~hi$(rxHM zU8d@vy0|w3kisRt?U?}J~TZi{945Q%3T$A)Be+~0xc0S zlIPf0YsW@43^e{U2f1$lG^C9__C0;-O6)`AQ6?sH{2m#4@xJz|$}OWHEdnu>glrjBeV z_k|}u-zh#wgH_NTSi!s>P#MZ?8PyQbKSiYioY7uBSF3c!U-QdZ0cv6oAxdP|Zf&0*4bJ58Jc`7?j$X zo&Th4MmDMuaJAZ>j==SkF_~MwJ4F%Ox70?>%Xl5e{nsTv^13^IaN!}OCOw|DoH)jl z>3XXb$Rh%njfEg4%jCDqc6%NB7gFt;irevW+LGlq#a?`u)8t^`ghEI-{JmhE%sN<+Z%qT+TaTAKl8k?@&`! z{TK>qHrv_ixw<`Pxhw21<7Vj&M)lHzs z5vF(!ZrvnOv==_Yxn~Kw`c1o4dSClIyoT3C{iZhbCgjKzy!CK3`KZn)q&gAN7NEbg zc3Zb-!fkR+Cii8+;}*1!yw{*w;qTXs3W96q@+~)c3EvIAr+&_VN)X5V2eCZLVZOh+ z&pN1y8hdXD1l4kEcl6+DS5A3thmBI~yavTX*AJF0XrhQD93O`+lJ6yETvwjuzV0_T zL{nm=F6ERGOXsQXrs+5&c5JkNm!3+!LLJYSzHoC4?J%niN^#l-LxXQ7CgqEpr}x_S z6)lD~{YnR;lofS(BQBi_`T==or1i!Xz%rJK%ibD-q^U$3<_}w1tL9=X^NeFBYte>d z$A>l~ups9g=S?ytSyQOV_qvE;aZq?x7tsS?sSfvI1LSfsb^WD8UK|H%lnbGkN>oF>?xt$#21HoHrKGB+h+wSjo^AO_E}oc z`GD!77a#kvz;ymW`$}&?&nM*0?>HT#Q(?{N@wI2FGd z+(hstiLPPeK5`=5P4Z1NoS!mW(BRTt8UhF#f%6eawrN&9S-$f4-VoeQxReLqi5*BP zGRlieku>%HSKbhuUItYFDYeEqk77iMpFV)7qSb8CyOJX zz4*bO-2u8<>^Ux{ZAR?)!jM2N&=RQVA!R)TBxT;(WHRH8)C0=LwqNSNT#`GW?WaEO zC;kMW9*vzxw@%`4Kfii%nNo;-Ea1Qc@KA||R@?!2j=7rrAJUrH^Cqt?0&6PPg=%VV zenbg*#osfKZUv1lG%f&sDW&O!dupG4T&J zX~hmH%vV&K>CW8*9U=TEuj1P%s`I>`=15*QXyLz*0~j30l zMvvgxuM);&Bmn7y>U`qBa}Y?n)QqbndT6I+KgDrR&B*;UF2NimK}HBNF#wunx-C3o zX)VyHP|yBvZq^T4La>u0r+-cJoB5=H>4s1K{}8ZD@Og0a=#|7hFWwC&$;AF5rCxak z?7Z@N%$Jxzt{#6(($7>HTZE9Ql`Hcsx?g(%*nt%x1|a=7r{Hu3WW`uN*Gu3URAy6OvgWL52|sO>#aabxxV5Dup@}HVh&5KFfr0G5_qSu98IP-m3zmd z`Y4-BR_U2Grx*OIFH>{1K&l{!Xh#kpev*uWk={w}O2~DGxWGBA@Ba8+SsC3H6Za6ge@vmEOB?yPw9k}se|=pS0Yy4;Vu zr94kFe>%l6^b*pfnNLX9A(BmOz9E?xpA{)MZj;8Lphv-*s)g5*LUDCPMgaQ_7v;E8 z5=1b)3UTe6wZVyjWd+e$VtJj#O;K9_Hn29p{p2&>-(KOHZO6TK90Y8QD~)eaeierx zLFJkDX@f{uzFob4YGO|PPoh@+C(hr)ni3XKmMNC3(&qYeP*4r-BD^Ne=LZKM){O<_ zLy$3VKQL&>I8~|P>Ytz6{e^|N&cBJS*WzJx{>HAWZ@}tlFaFwjK5Vh>rZu1(Sy;(5 z1%yvaFm-L@oqfI$$XFKCQ3*auq7r?D!DNIFBz5~ zl6!WNEb#qaHmW~(xM5^qy<&^uNEbo8LhO`?%MZe`0W-*q8|#nocp~U>%q!uL>cM|7 zf>{S6*eFWKF8YY26yZR9gxE&-A}!+lL@+KBiIF;{fQ8vQf1K_vKH}&#l>akF#Pe6ZXq)0ERObuK*}b0wA*}t& z(-Sz{M%-8sZ6y)LjvvxIaH=E3q)vCKy&#BiSy!dP)_i-&4FYmBY(#QrUT=nl^1k>1 ztvdVHhBQX*dYX}t;A%u70~q+>Dv0lhC~Q5V#{C5z;Px|%zCpI5MOHwq;nXjPUDX6U zG4#65Pgx|s_#W|(M6X^RSUn}H7#_hq1l1x0a}4tE4ZeT;V2TAxl9J})K?H1;U@FZG zS?WcWeknEg$TlF`^z^uav-{VD$D2RZ*#(?Y2*n%Kc#hlsA~C{=0DT<_+3(ocMKIvW zy2S2sAzYMJ zQHwxv^h`W7HZT5Fo-NRxyGZaZrpkBCLrWs({1X2n~?iTa9|{KO_e-KHb6 zZX{kt*l1rwPsD;Uk~eeknrJmOVqq;d6Uu)rtoitv1cC&Z59)I5N2CYr6eyE*(=GEG z;#MQQ?vGY`w{$5*N!Y{9mLNl!>*ZUfy5?-mI`T=i>u@kjlI zX7|dx*1#}3N&YowV>H*jkXgSi^7BC3`rQr zR|ghT;d`?&h=prWl2fN zh`2cFLcK@C(4993gA5D18{)f~WWH{BxEscPN2+REoI6)xo69p<1g$~O+ee)?m;ec} zbHVO0YeCT7S-l5Wad9aB#XJ(y{D*l&`Ls5Nj^xteaKNSvzTKue=?aOA1lHKuvD>CN zi+xbA!#5$M;AR*b9~6FS{4=!myQ=GbAd=3#Dzea;3j0X zURKa<2U?gY)nWf|fM|CLhw2RQ$@uK3IVF9ndvf&9Ao-wCV)HOlx@x12Yic&HD#M`6 zp#y3hNJH|bo%>$g@Q$yc$F4o-f1C#x&(>}%=*CTvs@dE!)L44#^(QksAXd>U=|fbC zjbrlfr5d++zi*-l=AD{sMO(=0`E#5th+Kk7wKziVG#{?4z)bD${ocQcQz-uOv<9p( zb?)>Xq5$nsF@yJav3JL4_mcocYDZG|2Fn~B=k%@X&UL-J!!!9?WPh`bjfF+pEwdd5 z=1;4@8c30$6q#9%o)>pYARfej_j#K$$=$_0D?aVXlSFe~!U7I+j!k{zQ_;#wK zUXYb5_@z)eQMfBrnmAi6{Z&d-SlpE>SM2izTo=1McDMFDTqbcoszt|&-DY=wNTo$Fstd0wqFDH8b8eJ7RDe>(rPG02}`xT=~eWC10?|2ON z!^ZQNTkfaK_xE;@Z0;2RIH|%Z&OkX6`n#P%l40_fYT1S!g|S6z+x63zIHigoyP_D4 z#r2r#rd^ivm;GDK`~cr@ugi60Jj_ySv) zJ_Dl?Jj|-^{stq}P!}hVBPn0b3^J2kD#ezA<+)leZhFO*nyp;QvOfjT{NO@584p`- zT#Fu07!6{cKJ^%t9t|VV9Y>n-!VAl45GclsMb(c+zPz|6Ln#3J{Uf@=N78E1t5V_9 zm`ruFS~@S$aUU$N6#^N~p%wG5cit!@L2*aB#ZgJ!!bhrK`NG%L=KBg*AlS||*6)k& z0soX*p;;3=_I>bSoP+{(>`WYWwF{+OOqij z1@%wH4ntnNAk2Etgk4I z#5!Z{EEZJ@t-gFaUG%jq(<%JTw2<$P9T~s<%vqp=2&>)Kzww~9=@vYe^|m`qUq3+o zQ^uY>%Ygd+_gGz?A!8HswwQPdE~#nXJapzvEP2PZVO|-yw&xad@d$v4NMXRw1=y-1yIttVICe<}2*)}PD_f{1o&b9WG3hVOCVy!#3s z$F#mWT%aQ7$M&b|icC9thryr>?)pkT{}W8n8{sLxw8-kxO{+7tXqR7rJ|>r!-(puy z@!4)9dYcT^Ff;$`BsoV?iex}12qF+QkxY96hY^|GwJ`n8GcddM_9Nr`PnGGFR)hI> zJLr^Fd5G0(TjK>WAf@vN^nA>Ja5S`BQJ5FcMbuftb17vx&5*%!Cr-UQ8&c|WVp3y2 z217|Y+C?+J(Y*zoNIgw+vwdT63=QQ`7uaw7oTD&w@`Ac-v0x|R%Wp3&&=F` zin5Pjq38bbJBCB4EXqJ&FZTM^s0{S8yW75DOu~KvGO+(VXlo+^t;e+O-=!dZuSmsX zLbP~UbbVp)t^3oxooApK6_bGbShW=;AWnV#aT16db#!YRDauDT76;UryUh>2@T5l; zc4;hYgCxg6i$6Xeljw$F+73&3H6J#Y}FA32RIm{gW~*l zSTpd&Bk3$VQeI?xK#eR!)PPCBv@L6pTnL z&)&{AT$t@{m~AEVZ74rA&E>IqvSM#*wh)rGSEJa3!3oMjkUscK2+Um)gvhen`s~Mx zRqM)fb~fRpEsm7?3S*N0+6cRq9&BRuYp$(7tg7ZORroxFkN1kHU=tXV99kO#vf$p4 zQc13#g>27jQ})+MG8g>hD(B**bc)O)`}J1fJR+wfyggTt{p#8B1XA*=+joOlcq3^` zgcgzR1&X{HgpDGc3_#F$3pK23zwzguGR5_KMU|K#iOnpsKVyOn1{q=c5~F8x%}Nb^ z4nI@1g%z<&EzjIVWIdBhami?Hf#K(40CBF8U7Z%Z9VRb_w5oaJJRj1kX6q?UEohaD zoc3&4!1Dq)K7Wxz=DtYr@Ru6ejshWMOvrCHHwZA4K%bh)`Dt5czWZ|b%A&RvmlO%IGDD*uF&zdSKftyjep`|5IAry}wMyxu`LMlw&3mS{2^v+J= zNEt=uMTC6Nn813*_hM*V_tpZ#aodl-Cdd^`{7%4`?qIcrX@C{-*?QKQo;wFE;k__+ zZIFXr3B%;Ld8;A1qKv>KKB#-kWc7IdwM0+ZVbU=Duvf6qCy1|Ku3`NI%^9H#nKnLQ z9ecXSBav}4-;n~_6mfBH4u5sUy)$=Uxoq^=b5Z8p?JS;*dt>tj7 zXN+r;IJ9OT5P5p?z*aH!?(2%YyiLh%7yw0Dr`M(?r7q_A{DZqgf`#U*CmJ_@-{V~* z9-E4@s!HagHcU@n*6!@@HPmc1>zm7Oq`4BQ`6`OTD9yLADL`AjD7zbNrKIfa@m;59*^MR+D#70xQ&crEf`@g4__WK%y+_o;y2qX!*+5N0>wYROrEHPuE zGnG19RxL9^y`|L`N9(*VR05H&li27fcv;t++h6H`)O_G&0n>&p>eT5fi&o?HE@SJ) zkgd%Px5@hM2Rm}-E?=hT-qT5hf-rR#4O}`sc1wj81?sE#Gkiw&FAB!4e5lmC(OaLg z)L`nXHuS5H{bKJ8lUgUfhn{uWyZf0{!Z{LLC&xCNXk81rwAxN-zTFh!kX)@1ICoD@ zm*DN{;9^Z5-Ro&&pP)D<%eh&5V3lLaCXTEt=`-_N^f!!uIDg1t^WTdmCt+wM38ARqd65W;VjfhAkd$^Z54}+)coj;NLy$i zWp7#ciFZA1@Af1tM5`?jTe5F9UX``+_gBv|z(8dt43sORZkjKdOh^R*omulTXWT}k z@9Tq(iNCE)TVf@Viw;uQ#H=U;ZyflZXi(140D+0ZnfHki{tISj>)6)OZmnoHLv&Gf zW4}AQVPHlqe0pY!TO1GjOttwg)(E2=>%soyD{G@V+GWuj@nRaOdknya1_T`MFV>N* zxvWf$l&KW{l)8hG8^pjJDGDy-;>Ylb+WD92 z*e4@q^J^ccbZ?Plnh{H)9${gFm+|Bc#UVH^e&A&S&SV;vW;FOr!F4I}Zc9UhYJ6Sp z1US^Lsw>*7utR4;dY_7xR?j(+g4zuGR=^PMD>3yBLZ+UkHt+?O>fWQ&b6wh##E|0c z*|7a6@Yjc+jK}9Tmp=+}R1?z*zq_E`L_dMbEnB$Rtz=mPQiEp#G@%l^t5WWGl*4RK zP!y*@cE284jR^#P!hSEX1$45hXCMa*&E+>a(=XXZyX=(iwGi7X4X$3$nk^f9Ss+G- zLB@*{KTO}<1}KxXn*mSYy3jao=knfftbQQMA~s8SZ_}TQCBkn95zGNac=eP(V)EDV zf{t2WFop|IeN5&4>p^XD2TX=yYNgxunX*dP*7x^nvH+Ko!_vx95$nDu)RPC$h45sL zVV;|Zw7gD1Qcy_SGu_dCP9*`_?FVl1ta_twJifjZqD>gO>k*L{A3s0+z%4lXn^2Ji z+qz;XgX9#Htd>jSmc|f62Aaz^19#X&He@U31|^UK@9M&!-XO~c#ghB(mMXB6vf!d` znXS03|E@=wnno#*6}zg65p_56*HZX+Q}q5fhIANTr5PpN>qGYfxz6u@8r<54xU?L| zHmTl@e8JpSQP}&CB6IEL*w~#>rHxW?^0y)S@hVcpKAr#ayUZ|50fgzUTPR;0f22Q6mLM;V@sXIo`O~B zq>U1p&{{D{nmltyXZTFe;+OEIijC0#_K$q$JZbZgBSOjhxktJ<7*70>^40Ida<@7d zSDbo#7c6g*W;(p&Qxz_)odzH&B5A1DiZ(~TBn&ht%Pw!_z$vm2iZHBhLOr(}6shpW z@5}_}#+bHc{BoHmrPr5@15?f{L)ud5ELrB;)#4{Vq@dQ9mKaEBDXC`~x`*Nlrod^1 zXMB9TWBYfNasUNa#@hUkw{37vQe2(sP8Hc(41o#`%`vvlKdZ43F)@wJs4IG%aJ0$N zFM&Fi8On*dGj0&0?<#>i6C-)?+QypgfNFIgKyeKOh>1GGoyk!tyhY$)=o%}7F&XGJmTzjV*q-0|VA)4R4O3gf7y zQ@@~iM(NkoxBO3)3`ThNj6vGhz}R1QFZUsRF**uoL7YX}rQ|AnKfcbw$e7XpZdjhycm zRYsg`^s0V{T)+Y%FHy8jqHM;(a(a}nM`MI1dEf9Ge0qBCaT#;5tf*S$YjK1&5{7>Sh4?P{}#Pcx~0Iy3|f-RjP=)LJ9J8ei?%k` z%c8)2sNv*G_@8O4GgcJfac}rW_q6%$bFDgx!tCK#t?IYC&*-aR3?AGL*PhdRyPAVOF6c1l zH-GW2qQH9xqMw>uJD=j$ujlA|NYO1{g_?1X40774&YtDe=N}n!$8f5^%66{(0pcQq zi+1_CiISsWA@@fk@R&|E!v&LxdH!U)n!kE$Kd0!tt@<5QzvO!+B`D>YEb)%-Ts1V{ z_8n&#OUuqumD9K>qK8hIYa1n%oElzqt^4^^n#b?k(5D;yMvz=)M_wkQH7#7Ut@FZw zz-mlle3xB36t(Oc(k*)wsa9?7#>N(L%&Q3(w~{59istnH;ZMM*UfK(JR!N9CB~+_&P-Luv;%f z;m)cr8+pAJr+)9Z&#BWMAvB8ThtCvc1cEfXqtM8>xtrkyK0xXsNw`c#*%YDz8r36F z;E^X#`E-crnr5Kg#o4md7qAOCADp1hA^m8SeYTmwY7iuW+QH@S;2S58WmUR@t;<|S zBy_`qeRn5QGuNqT>WAKNn!)ddZ+<+$ z{`v8emZ-N)`yNj)TRw|9`5F2mB$=PreV9bO2lS2Pu-~qxr-8X}9-N!sT`KuSmibiK z-abggn!B5iPZQOTcTa4z@b^!{&6@+xK5eCxrqBeo?lJvRvOZS<`RgcbBcjYxRF zf*2d8&D|V3o+7CJcVr95y)J7b%L=16Gs9ptYFuh@!dmwa{|Bz5(Xfn#hj0*VSq;|p zd#_8IiiL|Jg`1EmUxtxxn7kVD6}LY(+XA1%BiXhRcw{GA&8`mAP-(*4Sp0Z>gJ9$6 zs)+owD`aHEEnfAhBE3=t?Tw6XxGLsKADz7&-fHDM0${`Zx6}pLnb3qWD>U>C>7vLN z>|Y+g!@!;ksKx741?9)k0~Bm!^2doUrrC@)mb_)XWNP&3shCiIJ%Tne0w|FmI}jcA zOD&22h09DO+0Hw9bJmBP~=^$0aZ>#I9jB^_EPqi0J%aMUqTSB?x(VxY;`c} z27}`qN)h_%e(I(V7z5Lhhx$Q50&P^~zQ9h{(C4xJV|YrtYD-flUosX6pCj-X`cibn z=-CBy?t%?DiyZRBf)Au$JK?51$G0m0hlsfEOu`TVF>qV$-Xar~AR%Bo_$aR|Cm;;# z8rsnfqY^EAFZd&a0WA)tYGXyd6 z$PND?SA!%#MlgBYcTia+8KC=PO*)}Qk~y?u2+_ppoz3M!yJQ5=AXW>D( zaOD8NV`M7vI~*;orzqA^__9f$kVpa0a-$XkxGH6;wg-Qg=kR*=1F$Ox;hA)}gmm!r z>XV7$19bLA>;Rw82n%35=zT9!FqvjApaS2mGZ}9JPbPvzF;)WjcS~HJ%6zs%aLP%( zDCFGkiG9rV)pK((I;sQTMkvb}j4V_GgJ^yw4Fh$^a;%RJo`N(_l|3l19kJ{*T1yCb z6$*gHIub>NyGorF?`IoT3GXgNSFI#FXb|FbFd)O=2LLbtSuhNhI{>}K0`$f+VJ8Lj zp6E4r-haP2UQiov^!MW2++z>#n_2Ny!&~dWl{qqst%etVDx8Hg=4%pI9I`@&5r@E{ z&}xbWs+aU3bgFC9iSP%2F3v9R;Dn5z|D)ZzI|*Cw-f>hA)`HysS86mEGor6<-t+EG zQVAVDfic5@c~~C8otdSje{4`$WiZOl^?D=-PO2v2w#94zdnmp&K}bHFML7fR0%+Xp zPx>Vg&cztSxmG#znW0=FoV|UgFgE05&0w`{zj(o$x13@FfkeuY8VF3Ge7Ht0+>)gZ> zSR~6iboJv&0dQ}K@&?P{YfO>X-0(h?i@tH8#xMY0<3b%Oa`>8yN3UTJAO=y!f$-F7duuf-pLthO{Y96+{DK0W_x6v%A|O&0+4JH^ z<)nl8@avf%f@l!Z{gqyD|P0zez_ELaN6M{1Rh55fH`X| zPC)2|1+$9Ba>T-TeK?0u>8A57V9l|F@Y)tO`oqeBe~kdgnyS;ww~!|e`qT0l=Ml|e zgG+Ill@k_8MVNJexN*t2%!iF2=H1C@KasAD_YuJc2n8L1IkLjIM3qkDT4G^ zBvkeC;S0VKx`N7y-F#868U&`Y9(APDS|xHAl=8y$#f#IRRDwl0Ax$k^4zE+8VHcwQ zuXDvzNLXW_6?o!D?U#{Cf(;1?gx^m#7m*60l2jI2)wuif()tZQOm*pTFEKg+B(&## zIEr+y1F-@+VHI@3yxo_Si(nNqa$S_Xo6E++P*Np^y07o;>4h}X%Z!of@DttywPl%N zh|j@4bs9DdC5Ua@Wb$1)eBmPQ+ya^qHafPitOPz#1JBG)kQj~FiKiIuccJ)e4}5hi zXn*OepY;E==Ucype~J!y2d82C-{M{x@U!{BvKxwt!b0sO8A=OQB$;UEb0WtZ4#gRLO>&O{9vj5G~7?MzeM28Kt)J1 zm`&u;4mA*q&b+N~UQKy<(OHI?8JPwRJx4kcf^UeWJbUv06?N_LOzwZ&WlWvJ55-ZA z=5pkc)7@p6dm{I3#5pudQtRL+_uJ47b)pO9uo#Ig*IaUB4%M{M8EWKG=*YHYa%nVL z{60^0UcddbKepGNJfYzgg4oCuct=MTlJ zZp3o8lEa6u%`(5HNCfGo%YCQr1@7YhWJ0Vh*J?15 zm%#WS=&680DD%Jg7Wd`YXH?JH+HQkiw9;H}FA}+w{$JJCa&~rYFfINtLcEsdVgzH9 zPt!~G)&9-daFw!3d@;*&m^`wIZ zSp?6^e3}b#=s&i*JUjQho)_b{N}3z2zgRu7#v0>n{&Oly}qHC)R94#!wzN znvelB*c*)lK(3C&z6?X$K&);amd^A8Xyl$fwdF0Ud*+9BvD^(@0tk(X_4MyiyOocP zGO>!V;l6JXY*Kut49Ptmh(&yK(Iel{xMv&Z>C>AqHiSj13+}Stsdb3#^FSs~u6D#O z?0MOm1>q2v8&)1a=2JAV4E&Y@HPNyPuc;vR3_|=Ruvu+152vo)SC)oPMdk>vM0;vD zlA(!sydzEe&U9&f_T)_JYLZjV{MBa@P7=UQSsc5N`<4mwM~3gkREBEJf}P4phjXE6 z?Vee`v0W2%1r$@SBPTT8lowi@!asP64w+`!xgdM`Jbkw=)4S-z^2@Q6Yt|69q@hgN z3)4o6ljP|xdB)Ko#_>x5q0r6ifs~o~c^y-@STWHu&a5pR>PsM*{ zWF6m1&%jXr?C@Fgu)N?qw~fTKxXW2TmTC;7B7jSGKeY&MXZV)ZmMb@*t<;rO?NbQ} zz$lHbw6xHd_?^J>0Ar_f((9;4yxQe>ExY?v}h=YIsR|MJ?)8*?o}4t0Id zT$*-}EI+0HXqVOJ{e}jbAM(SLDMc^bK=iXx$D%k_=!71Q@?28EMf}}6bhI z9&M7pB!=IL$iL6+6ZbQ45oZ1A>}7_+KLTxKZRr&b@?r%{;(TDIScg&Gh?4w-3=8GC zsTmQ@Y$Y+BL7&uPK!EU9*J~#D8h==L`Xn~7jhkWi&#FXVlO>R=Z|%&9Yx({=zGnEJ zcGwDGJVN(Q*FGu!Ac?QsdX&}D(9j&(vuPYmRCVjv0zWn|=zWd)r1io5bMGo^jdcQ= z$Uft8B~gNIpH==cCPnltc}^IDy%zZ3mu6>oQzfxVYf2!o7BlJpIXJa3VmgWJu3xv; zC`auCv)&fsA|leSD-@dG%;JA2025yslM1|su01qYuSr?bVR0t5M_P+tpJr*E9AFTg z+9qW`(d1v6XDZ2%R9>?gFII9T@nc&FwJrROysE^QItwc3CFhR5&G--I!0OS+`%070 zV9xalDS5nAtM#a)Wx=nwS#vz>f_QEP=HK323FF|8NOv8+1NRY)l+TF^abRt%b$)65 z&?flMQ{AT|bm}AYKxn74de4^4a{cST2)cG(X>7t}SGzYfScO^Pcl93)9p{+P1}wBhg%U^3~M$Q3kb_;0Duc--d4(V)k;{$c{JLh1rn0 z=vPgC!K2o@J|Sj`|ND*#Ll2(*(#WdS-`*158b#J=LK#_>Ev6bodBkk(UfYGeh(SZ1 zx5U-uw&DV};KfP?zUSUef)eveO8!dO#dg@Yvlc12NL-TIa! ziS@EKG-x}GX4AyjDytqVBy}VfS61!jZfXIi7xNPYVAIDsX%v} z2LZVH?tNc@pOlQ!n%N)0l#O%Gxba-fE~aF1#p`e0+i8RMom9VdK#B1vJ*#pdL5>1T ze`n68Ti4}T45WAb1rMh|>>*(~0t`d4B9xE3zDubYPOIM{DE~2g&hWTDbd8bz*4MLzH$pD2s4kO`G?g&pN7206q+-)E&8x1i z3VZzO(s)>jILs6FKCk{+d5MrePYoJDLloe6=D&wf0tR4Dn!e%2eR#6zg|QlzrO|Ig z_4+Reqx`J16MyUqMOAwS{Iq3@>l)H%P1hb^p-S)0jZgm_4IS%yS$hBG@>w9?L+XIE z<3kgdX$~2b6{=TY6*-^s_cn*uZFO7~x{2G8&yeJl+*CebGgW4xS=hY%Uk`uP_Rx}X zi2PO&y~x;et!X!vTk3K}Ny9Wd*#+ZXkVaU^XJ~m-@E5K+NhF5F=1-a}%MlU9IYrIq zh|m*=$T+kOrvd1ER0j838Q7wwDIt;d=8BVs*c$Y!~NEtf1A6erswBevlA%Dw1GRSjdn zx4nAXzaVJ@ZjPbER<5Ud5i1X1w|k6 z)!qzM)39OhwqNfeV2E&toh!J$2xM1Vvd&}K@!ihLnP20KzufB`R}DggMZLzQY*;|s zQ=KiyuQvp&N1w}9C%2!G>ahbfNIU72@a|L-C-)~Sl4y5G*LvP< zKA$gd#@=lWy!!r`lJEch_EHKOZfTgA2H8a6;0^#Xn6ZIse_u|+&-hXlAe`*@$U&h0 z`rc4TI3Ez%^8S>+bI{w)P{%`Y(=lhoZ#4)PoT?mT5c7Y8+^$+_;`R%zUZeV8tJz2- kTdNPmyusAx;>FLH<|No6a9vK66((c(?1 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 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/dynamic/subcommand.drawio.png b/dim/documentation/source/_static/swa/dynamic/subcommand.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..67c73d97cd223c5319062da62bf9b0b8d840fe66 GIT binary patch literal 35854 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 Y$n9Dcxmuw#aH~kNl1dWg;>Lmh3p_omX#fBK literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/overview/classes.drawio.png b/dim/documentation/source/_static/swa/overview/classes.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..94566ef328547b40646af185cc033b0ed67e2c0c GIT binary patch literal 61406 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

XiMJH=mjB;gc71JFCUV{ZT(^a?%!S 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 j9ODlond78DuG` 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≦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

x?Y(1BHa3O9r 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 z

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 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/change.drawio.png b/dim/documentation/source/_static/swa/usecases/change.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..1906a0ab9f834b1bfab764df91753ae39fe5d1c8 GIT binary patch literal 46253 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 a{86T&SZVex&!87l_(NZ7XCXBA-1lDqQpc45 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/data.drawio.png b/dim/documentation/source/_static/swa/usecases/data.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..f4539a53ef3031904566cde2d0fb00d313b59577 GIT binary patch literal 12888 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 literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/export.drawio.png b/dim/documentation/source/_static/swa/usecases/export.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..2ea0440915398e9d1f46a9ea75d5ad701b54ef4a GIT binary patch literal 37136 zcmaHS2{@GB-#1c7W#=cwM3(FZV=2pwSukeC&RAp2jIl3c8M35Aq9~EQERnTrAxnF9 zA<7c6MYc%D`rf18|Gl2)ectQ2F2?P?&wb8!Ki}`?eCMVy7IpIY>EjFx3?~ir;ie1> zN8k($jEk(tfIDk#p4WjtjQ*x57(;pYnRy0=<2F=;HPthiMDZXph%4*;y%Gm2x_bLl z#g*aWV6c;qkGu=TiR|a(=`Zg^qyo2q=bqj!6cUB#@^=ha5e$}7RF?xo%oWwem7$6d z`iH8#5=6=7?|3IN(d*v{Rpk|d38btjUM}82{=g;H9QaUD1a2$CfGgkuMCI>gFhu17 za0lw+<3Y3{I-@DT>PS^(HF;$Sa9awkZ;mk%2kQaX9u#*X@CQXCxO>xI(R20l_5|)A zl@wLvfvFGIG;<<3`BDDM6m(9AR44LZE_^7K`tIIHYfHQw8sX)vr$RMy|4V%!(a)da z?e!mK<-zi*e;-h3KE%IwU5J4c0DR8jRc zclHLPbSO(NCxFsJSsMdll2iISiJB$VnE>$zBaBs)ygc1WDy|4KyfF=r)7N)0ck>Cs z`FpvW8>&Mv{uDgS6^g_;JBL7M0WgdK#mJwCF*0^nHZ+HZ7@7IQ1E{JRR+L~0*~}Rb zFw9LK1!w?fs0ay$X+TxbLHZDV6{xofo=TUEx&h4$SO8<=Y3K!W3sFU)U5Ri&i!d6@ zOb>0U2r+kew=gxa@iA8mG4QbTRt$l0g3xIx@hLg9ci-jvj9jrkK zG*i=1gL_cjE&TnVuB0Gq6+cfvYe-m#sFEyD2#m71k-5K%icwIY zuZ_CDKLTrQXo`fO&@e-DJuf2-ZzCmFV>dmjpO=llm$SKtpRqHrnu@9+&Dh3A9ZDjH zgn*s=l+=NnK~!raq_LMfRh4Lrf|wh5f^p8udT@k_wI9tLW8-gPspy0c1O~dgV<8@J zMI{6^*c%`V?PW$p8-U%_QNTZXU<4k5qN&@cIvF7Kl!H~3{Phj-)BxZ$;Hhf}P0cMK3swkKt0Z#Cb?2aR#eF&C#bt9y;Ux=GB$xBI(6zmC@G13VI zF)-FZU;!P&+?~-jiouGCU`1~|gdfcrOZ5N;63qx921H*1Rb35>QgTPr$f~OPArM~! ztd*j>4W3H#(nAIX8oN6O;b9O{Lc56wTPpfQXn zBU?BVkS4DF7-PDPTBw3y5HQshqNix$WD552AO(5&p^VkgCVBx*U_)bX4LyHlf`u9x z7)!#qqLk^H5AaZNGKT57hG3LQa34h+a0?0tYiJ(!tk5BFbdWIt3~}|b0tY!^H3CrXHYUNoK}sRM{+0ks zPOh$2cnmHG@1x{rX`~OK;0We$GjlI*vXv{&7sU_46a2Pb! zR4oXLG$iPGL9A_@d<;UAVNgGR7|qqd#hj*xREDbuV4Q=1*b56V2v9|mi zg98m!6^RCZ=B6qTvJyef#m!m67awed0cIx|1sJGe(IM6v{zhgrZ!dKsfeNP)t=(X7 zSBw)3PPS0R!PN9&W)vLG$T4M}=Wehdo5O-%As;a3q+DD0qff}1&O)U{h6iZ4VQpJ;mq!{5S zs32bpy3mP8xK{v)q-3gZ5eTzU_5g(g?W{z@lbx|~?JCcEwl`k6X ztw9I^sPjbzdHMR7dYFc|J3$~+6%dJI-aSm6Uz5hy=k%S5^u;|!6eC_He94RkZc8QExPxH$U)aSNtlq~vev8n^Z=e&TU$_|2&{=0)?Cru+82gU zRCe>#uy*zH^Z}l_0>7%kPO30pzYud=AQW#%@>VodRZOEk&G z(ivl=s^)7>BVqj@!B&AzBp-9QiyJD)ABOY^(NM+t1^HQ7lF)R2u|!+B8hYq!c)9~y zBb_NHf|rvAglcF*LSZR>C<+OQpake)o#>kw2IdXHdYkGa03(7a2huFvTrpniFu0c+ z-dA74&{yA+;;pQ%57k#E7*oiq5DZx*Akc>jhX)4HGZy*};MK_gWIKnc5AgrLX{0g& zB;_;5zyM+}fJ4oL9Tu}#>iFONj=2;4Sn3~L&c!(HkFm!CPj(5L5a1Y<6!^_JZm7w* z;}Fq@O3v&zkvGp0WN*sxdt83QpD4xu7N%xs%q%)~;15aL8GmtQd~ai?wrjC@=aTl1 zrWeZOF@Ms^?rdjgxrvpPmETjG~Bw~5pn$qbCFx(rO5MbR%$m$T)DF4v=)|I7+$tbf#VrzrHqwjSZQ1ahxv zsy#!SPWldyz?AzD0>;O?4_6?$UNw zT=KNQ0)sXp<)6HgVSk+7h30K^*pXuG3-@*MS8!(?BGMreHbZ!u{~H_`>en zEa10^l~*pDJ!A_sA$hrpzRaIUB1Dt+o>p=-JgpH0Or-qy*xzL$xu4nqOl4sc!9rQ5 zzBhh?wHST4x86ZjH)B6sME9i|^sOv4gt6U&8d7RsaWgzEn`J(A{@G)R!x^OH8QqU^ zRehX4CSKJ$zZO^n*(Nq*=Q%#^$QV8p$-@WCrF`&CSfNN_C$g|-wB|JMc4&Nfnzp~& zbvh$gow=Tx(rLhO0yLZqvT`eMBu!n|CPGG^@E!6Ir}xs3PDCJMs|Pi3(X%2gJS{6` zE_LWxA?c8aRvpF#W`KyHV`r;+ht{6g1a1>+vmZHlMGuTxwu&R5&F@F%M(f}3J zT8!^KslrKJE7h-PZjI{L-# zRaLsJff6~G2I-nzVwWQ2E&VbW=I>SLmvE@p-X;=}qm2K$!Hr11s95}*n_bFS6Ck$_ z!|&7QQXwIT>*16_$EU{+DH;{O91W;Z&t3LU>hrCBda<|$68t{w&frUIq_$--y^_7esig9YX#K9d8AHVHKN;UcekiRW$$vg8gaf;WiPAB|DGLM-kGV<|I4%`e9z^}Q>VU0n*aC4 zjrT&{tt;W17X_6`@zrhv#bf&#{gC~h zvzbfgs(_mfv6dLG2%CyMsD9)ohm@5%4fT#T?{IhL{jnT_=d*^XE(GD z{M7cmo3QHNm@7P*jGCky%w=o5z7E?ilfib|Mm14I&-^T?Po&nLU;JSTBjxq4 z&im48Uur=y!*3ARhvuZ#7sDXs;S_K7Uv!Hf-!BOG>sYc^KOHr(tNQ2!hQHF%2v^F@ zeHEb&B}7SehIOT@{sKdBmsa6TAE<1ZZJcT1SD-?>&Lx>X6eG_2GFDYK`yI01Mm(yz zL{Yp|y-8d)R=Re3eGNDGT0z^ytC<+Hzk$S(>B;fjI`X5AvkxDN5}tnzymu1v<#Nr5 zcpW`nO3HLNF{X>vKW24XZde&*7o!kaTbrp0y#eM54!Uvk4W z+|HyKM}*DV6SmFEJdL(Bwuyb$FNpjNYx*EnX!0jn>d%YtS3CpKSzvNAo;RQ^lgn{i z>wL|(qP*L80Z+wtI^>wXMzDB>?_jn6xUA^1ggx#HiY>mN);;6*m`72_^I&13U8W-0 z46A_{wDoSPd@nJe;QokkN>oWw(bD!tgoc~RQLeqp;i7Nh|3)2sx2V<>ylbYg2qP(P zijW332+6%{Z=aPJI85SZ zwbzOKV4%ETxqi{&drm}iY178=T9?{*>&vT0gjmH!wuuENlHx#38>9ZX`d{4_n`Vka z(pGM(*1E_)&;kp7^ZMFA8^6$hPqJ%uXS++0PkZL}{O1s=fd}`8;SXF#*E`guOphJv zmG`EubX4nO{G6zUT0$+byB#AYRkZBe*i^fk1P~i?j96Mj=KC~S6#L@i_75J#2-^hI z8(cC5OkQUsPcUPlqQzm1_Wi8J?@wk;S|LuGoJW<7-tSNJbhRa?o0x@mnp#C@ZF@ZE zKX>mkZ>`Zb(b{yBxn*!C=a!QFa|$^Cfc?w_Yz74Z)rf(+NJchp7ocV=?-*Cp$J z6qmRRRT9B&pQHpe{PL~V5d!wpdo2$8Iqrj)qvVlV&!%{MPqx;SVl?>QBx;Zcr03Ff zYY~!|HW$423os|zHIo@P`MsAF;V0@+I&#kSeOK+s?`XPlLU3}a{+XO!J|yL$IaJxc z;e>H&X$__S{Z6c(HIz5#hEyA2$$i!TXPV7+!TX_VO25mGPfselAS1ynem?(Zc5%8O zKB&uxL$s(mBmq)sbWF-wsKQr~D&L=W z4`z`mdMO>STZ`GN91V&M-<=W(6$E!(ez2H?9}e6YB7a`_trR2L`9MkUeS(nWtGwqO zSrP&p$@M96wuU*{VU11beY4rS>Vw*bnIDD}67(Zx?pwh*9!?x?%Z#kkNxFbH)(*K^ zWl~D$v1phtqRyqzef*r?&9bsuiC%?>Um4@A$~~9*FAElyEq##x>%>6TZOQ}3lW$V- z9W$wp%SvG722y=jUjcfiAl1R`=^3QX)8cXAKWiNdGwc1h&FmM;4GS)BW4XpqW_zLB zRE>o0{2wRQ_BO{?!X8+VD+6wJ1AFRBt8yDv++#og)P}*UMpHLh>Yl7O|R4R(?>wiK0gAs?iYzRCcUfkwF zm3eP04*f>0yX|yo9}|0D?L~+gd?b=>ezjne($sLl0r$exWcI+@{*+5|hx1!Yo2w6i zJk_Rl#JcBOjEKCgXU%;(-*-@%p`cr08 zD`fpASpC%uW&fb!eC+PHxROZNCvcYoOP4Gr4gBunI|Bsn*KF59mC-d8jty*&G!X^t zY`v|n`97paQ{pX~W1$^*a+bKx?l+Dpxw^PMkGWKf2OVYNtREHF*#A|QC$p&l9N&q| z$fE_!r`7MG`#L`eT$41h5R2XY@Dm~t+gYhah>;Iv4`=Rk^j4Ia9`7teZ^zdackK=6 zypyH=?v&PgG#)YJ-=pQOZS%tPk5hOKqU8iZVDq|IBDLky5xLu%Kcr~iq6J%wDuu|f~sGs zJ36q2l+y?hArv_GQidg3NDg+G?1y+2H?xpYv{4GpCIA$;xoYI5bdDjugC)4O1 zTl7;gG$xim*t`h0^ap=S-*lp}8FFZ>c& zOxzI8%_l$l_34?N2YPs~4}pXXXIi!_etq%WDErb7lKBhsUq_9FgLt6HfhqbdC#0j+ zr`7FqAER}$fjV{IdhGB_%jWbwT*`cZVJOS#2YM%{Z5i37YL{O!R5ZE)+gBEr%+ksuuBErUD7(LtfAo@0M*KO@9y$FG})+DjAr`fVed|pNE zvDMo%Z*TI7z^24Bx3uzxuaK2fBrl=(yS};_@u$tdxNr6(~S|ka!gd~ z`*2FtN@ZnIw#c$=;C+F@2Z%;q8=+sZw#+^CXm6w0re02#83@kGy_5UGUM zBH9l|?jc&HlQlx87(4!!UZ)vlfC8?!H}k=#emr151N<2sH373(;S}^CFOOdZg+hnXqL1-1@H5 z!d(pjt}s$K_4-pX5m>rjQFv1LZ&XS8cjW6BfS=u@0@X$F_PgP48mbmkA!P8G~p>y;Vhp`ol~kl z)_hsmR)#2~DSNbW6Ge#lO*A&GL;Kj%zm?A2bC5#fq3R}w?Y4MfCvhsmE&5PB(`?okVjm=6$5sp6F7s;&Ez1wI zJLIl65z#GF@q1~_F-2U5VziUITt+AF>&HqWzvfpKZOD7NM z+u(j`$(bZ>sOIXC7L9#A5cp}f{jP@IEm@NgUxFE3-s`(q%-=*`p0Na|GkfQmuVDb> zq54a?ja>$<(D5;k&i{j408-3isG;y{X7P_$+;WeK4Nt@FepKlHW+eA-a9W^G)OPGb z)yKBAlV%O>=-Fz_dWT|m*`Bb_4#4riGA{cNreJ(=2)86)A&~&)lH#3>CM%fujnzDJ zY_~>Xr?7r`2zS(im4knz^{QZ-?JLPyzj266&%*(x*N=ybSu2e z#w$dAbdU1nYe7SuOE;%Dnm58@XjnmmC?D=Lw~{KYrp^nqLa)8DbFK*|jsQwM7G{{~Ts1FAbU)z`kM z$Znrzk{(po=z`VgRhYWTKSF2v-4xmIu(o8}VO6J(y)6kaeH#GGc6AsxxDj`bjqDUG zq;<{-=l%uXT4fl&GbeQ;=?Nzt?VBBty!pJu|9kh^ubcxro9A9x!S?3HCz#ed=E7^6 z072yLJm5Zb+m~3TZZ^@2N)qmTN0MCrkn9^4(6g1ZsJ(g4iRAkK3q$4O7@*18zlz=A zoE8b4Pgs6dm@U7y{=2I&F#91Hpwp3hZ6NiDd{zn3SkaeLCjWT`;!I+Qk`mPwj?pz| zVjU}DrfHvK$^@q#BmOvyi&te?L9vw&u~~G3I3uPj(XSNaB!4LQ>k^Tm;|bC)gxWwZ zAF|WWFp1$bj09Y_RfLf_>4>)YwTZ}kq7Pz0aSV4*|9KXv3uj`@jb)&n zVKQL@1?O>3|50J}X}3F_jQ+d|6j`kR03u~ph`kRahi$otThqJ0dQwgDkVG=CsvZNA zC70`9XHP7vU#Vq+l-a`YsK?Qkgc81xY9E-E88C>S zx5RpKM(WD5+64?)fSup6)&oW6^u#reZbZgiH|8j*3zbSK9lGa{5BT}t-PK^viZUqS z0xV)Z3PuhNc*1_|!TJL;9_BT}mqz7teYRl4OjA6_?;(pT!-9x@`4w*6pR@fH)yJ7? zxYYp&xxlKz!R3bA(N=$8%_B_d7ecn@3umsf2uB(T($xslJ5c9-drG|+$-@O#jha$o zolcDGo)ixFWU}^(MP&MEfC?L+vbdKiwq6&4#>3QD1bMqRJd1vKBc z+ILjI4pd@Uwg!Ru(|4QLTam&aD+g`d+r(4txUG`vrDIN*l#dz^=(c}eFVctvw!2oa zu{2@@6k3;tfSLQBB-#L&D2y|BclE;zkTs`D=3J@dTq>(gV$F5CN%T1YAR|y=c8J?C zRWotGOb>0cfQK!^qw;3sdLO#)8Q}v}I-j3a_aP_qYQP*r#sI{*`0`?w3^i~0jug46i+UC&QvkI3kehK2+pD=yD%O#z zP(gJ+7jXyV_i`!gVo(Y|>Sso@(ldU*r)-K=PcW~cF3+^z&vneGC@JZ1oO0y?bg#kq zUTDTX64ZX_l8lhg;NCE>C zE^t-%Js{N7XGe;(c^R>3?9mt2Fs!+)tQP=@O6f&zvI~l8vK)FS9Q0D8kM(D9FmJcT z%SlUsVriyEM^3oK(Rfd_aezj@t#2_SB>oM+*pG?=W2u=ZzaIvbIDKHAsMh&9$;hlg zN5m8!Y{kW;W__qeU#69v|31ijp!mKlzVhunA~Vm|Uyz#T3Ol)k z`MFt}W8!Z%#@r3yKa%3|$5fL!&gf8%PqrKzs88r2XVA_cLm94qLS6h~LN`AdtMX(z z#xVKr7P0B~pnoyupIac&W22&+S2%vp_oK2yeq0#SV|$Urh<+V;L73^N#36TfTMJ4f zYG0}M<{rL{NI0!(h`fDf-Y!(J?h<24C)Zg(oLb4viFy!VecJ!i(k&=Rn$?Jn9N@i$Mjxem>OgHHieF)tf!fYF~`9U>29;;=fSXGp0&=N$YWP9bx1ASo-nfBR#}HS!ir0VBc0WeC|XKkK&_5#M)+FqE{i{$k7Zd z0?a1TS4q<6CQRR9h^(T{ASBa%sd2rL@qe`rPu@R9wQa#^wMc*ey?^%9J}(#e za<(QPQd!KX|FR%%aI!YyvuIn)Q5^0mtg>$zb9q?;0x#}?A z6{Bl7*^YW&DlHPt_q_kUJ+&7hUImlBvM$1hE|Bj!e}BhVVf8yzKc94kJ1y&cyV1#5 zalYONIbUXyE-2>EpG{A?Gs#*kf z`#ag6D!o@kzlP-Q#dFdF>U^fsMeBV#QFzhAi8@_{z^ZQ7!aFSpRin=nxQ|R&zgi!6 zJ$21dCH&Iagvg~;@{6$EIaFv!f@Vg6M|CZ6LxnL_FoZ0<(c@hF(8P%#&vz;03#^_{ zdkwI+UvG1iof7LF)e^}bRg%6epNtvzo*#2JmGh7QUUeKlwju3di=g}mWRm{w%}m!pY?;# z6XCsEt5g-H+7CHP8;CrSB?_~NN;qpS^VUq0{(;E|V4vK4D*G~057vXE<5UPP@>+JU z&a|Di^ZUTAu)_5zc*m~ob)7SLxEFqqfIRcR&gMH(u)%QjsL7MOx;??%ht`wPshh0Q zU$rx;U^ACswXOkRKvsJK|H~Y$hM|%1puWYVxU&cQqHi8Q)6#GJxh4!PdEWEey~M(H|sKVGTQ1o z>$bO$edqBcIk!vN^DVvG3cI`kMJk=zH`DgPTtL2 z;wv6RBRcqj=r+ts3D)`lGS^C{#}!dL*IVF2`eR2};;0&r6>w-4EsDk8H5HaU&a&-Y zz0cm_x*M!{nsH>RCvYdX_s)h&l+Wpw0QIU-vT2z*e) z*|)-F;m;K@@UimOSgwnnTR{$4dwtv{Z?dK5mBMMA?Ayqf8(URhn_buQw6f|!=@8F! z;GouQwktytNCZ=Xza2;+&-3;#0`CiJg}~kIkvJY7!K;Nf$Cz(_V8B26d8*UBHnv6N z8{y%ntpA}NvS_Su#IA4s??KxcAh}K!N2ervLV>KAUZwbr`hI9@-dPqZE4ZMId0D`k zQEVxuyIU{FOY06fKcCd-n|FY`#lMA^`q1CY`b9XRc0?c{yt>eg58k75&=^Ghc@L+J zuNes2+4!CP6=)bK4u>qUu+~-IG|S0hSp9B!X9N4t+r)h#IluoAIsk~_$%9_8 z8+i^5PcCg~r4$k0?_FXPP%~*Sxxuh%b+XK3rOP%@%r;%r;O8y?G|!Y)b>GEiX|_cR zILxVtA~)`DNt3*(VU)(%S{HQN?Y z!$cJO^u~yHD*aflyy1s*{bZcXrHkv|%^n*iq2=q}?u2DPJl)>I4$1_xHbMWx9B;Dc z*1b!lly~LEM&9C21|l)Tsz8EcA5Jpqo&GRMpyST1DlT~FO4IY*X-S>c>vym}6NI&F zZg7Y!FZm95^pbPJB(5Dhxn`*dZ{wafj8puu@M7+sipT68y{MK#{k0ugF&Psm?`Lqm zU!;ek=QwU+bS- zg?Sd7mx!e%)N~h#ht2mL9XVwKnz*~6IirS*+^SO0o@}@L@)@iq8~3^;6J+SzHac4G zPyB2jbpMXd{+E+a`EA;EdSHdTt>+KDsq)1Ax6CF$r-7R$rrhSAknK?(+$EDG!p$+< zOYykW*D{=-{Y5seN?70@=hnn?W5V}jDjH220v7n&>wqIj{)a5`Zv%>=!tYK3MHz0! zn_Tq%VldB&4og;w*ga2rB_`!ZqNwXRJWx;HSv@{eTSxh$9 zMSRf}s$KSUNTETJQdTp#c8WYvoWQWsGF-Q6e(B$c`hmUX{@qxR;SW%>AEtUK@~9Ql z@-2ntM92NLR50Ov{4rOxVOKFho$yAFXYcrH5EiY4<@K|thk(QD#ycz93N`4>m?xeC z!<-)dj4WqBE!zVX`LtiN4t%f1y@3VqTC~lUzn{xU+x9Gf z>-gicY4OvP(!^7dT}j>H%HA)QAl_mTPdZ%W*Y`dH4FuMZ_0(b%2fMM*`gv8YOQ5BW zr)6^m${x%=9z!E={ud> zp?7(R-MJ)6hcVKW$?c7_UyVJWYS&&E^~6YxyA>U_n0|SLBYFAjix_DL7c~D`2M{T) zgF&}5Y--$QPEz|DsP*qI6lRJpls$K7leTA57dzE`>6g(Er7)}SwUr}oG^(}wdyLMm zQ&a2OEy1rvrJ^!hJ1x623fWTI0AkX_le;b=_I5oDt=CTUH#`bo`ioe=1>&g6E@XNMAR4S&yFicGj#Iuj|lL^ zhoqfI*nfWfR>Z;1cy_MN{?-(6^6kwrElp*wO8Db!pb?|G*-p+eXCP<(_s;l1bAF`E z{WiAYv%HtWk7?#{^6FHPdmJ$5-*Lm)_$Li_#bZG!xiY`~BgAW5qIY}Lfa4>j9?i>x z0?nuPb+#ssXzVOjHSNh9Id&q^;GTqP!=0I|ps}R9+nR=BSAJmx)qNgro;)kpkwaWP z7(IApviB!OB-}dZ+*+!IC+V@x2PuKBbk`g0IZyih=tW|WL{ly+OsEpUp|ze!?*hz? z`0#q!vp9ulviyC|iWfIBggx~1cAAAUY+KFyT^wI-C=}@V`T3F2XFP0^CbHxO;9{Fg zb$)_*Uyde)D_XF;pg3yQ4Hkq@?0{aIn#_p(Kb1g5)&b<#QzsR7U$@?mEIA)*ZdCNM z_i8c;r~PM|2Ul05|FQJ$GS9`Sc;(Zw7t99ATl&2z|6J__8hSMTOyARb_UNFjXO0h| zm%k}z{q&`6`{O4j_E-VCJ^_h)Qv$Y5i2HG+Ku6Q3kxb+jMA@7BTepV0^K&Xb^mPMagiylnr*s~D7sVy0c{M-GmOP@OS4y0h&4@eE zgdz`BduqOVgzjITHnvay?x_8}r6(tCm0eDULr$;4RPx%7m0k4OE}H50_g8OD?#>kJ z_qW}q_fpQ@$tB&FGks470O%c;r?j^wY+lEZuQ0!EK8SxA4j?v-g?l_qc*X?L#e0?Y zgUuH5?h82{z0Y31j%IHP-vM@^(D6<1Jynz8sT_SaTWs0Vi4+mY{_A1B&9K@LtKud= zl2w`1J_CnL*T;o}=!3!e_9%L*li%b`$#P4h#VA+c9M%u$au{&)?&_Iuy98`%UR^y_ zI}ao959PCdvF8C6Jl+8s3co+1H$5JdH;HmI9=>Tl?fT*xp64K2gb&-m+_gB;`zkq3 zAc36^vR^=UVoqv1MIjloc+OnEqr+oP`IDn_tw4M2mY8QooUUgHiPijVT7&0i;j^B1 z0@-CALJQwT!q$^coYnlK+>~zCVOUf1Nm%qCTktG=4ju`7(IfAN0PB5b6U8?!KREX7 z4jh;2<{xJ?Mr3f@-j2ShUDDG33JdJG=gXn+3lguI&@;?Q!w-+hg!RDxfQp9`skQno z$|@22S1PjG?n!po2YsE9+x&Q^@vdOpcR9}4J+d>JFuK@V5->!(WO?vBS(H`OGY`vP z2ZW@P5(@22g>K(&fuwPAMh8XFG}E5BEwkuE`TPB=c?W%+4a@bP3VgR61{RY@R{^|s zLav~nt!3i;y=9)y1^&|UQ9KWxv5TJ7|6yc53}B#5jlVzNFMqn3<`+2PsYU~OY-IQr z_L>3j6n5>pTYo-QdgcYT>ii>Nnb+TCG?uJyJ~z){eQ#S|@MxGLAo6kQaT}h4TLKDRiQj(W_~$+ZcC9XM zXSUrqtyH07_N-LU#(v4P9CzPlvY6+}ey5?2K^d0Q%@QwZwi{EeGN>KKGFN=U-X=fI zd9V5=UbtjQrNjFgnv@Xc)>01Y6<^zrzoR2lxH$)}tyOz)&Q!P{c)n-v9?FgEGhR@8 z@P%;a_by@B){FA==A{;Ur{N*%w>NIK1dBB{^iku>@43s{r3>~MP`W0)0NCrd!~*xK z)0-PKGM`Fdc;s!|@A#_#P#c2o==wbtxQWCJ%^mzOre` z*K$mOmX$q?crBpnZadN2eqW{l*mRsQ-WJerWwYG$sJ&`|}~k z*9CIQ!}R^KFul~hxz5@@FN)DLmB&InTl+?Hk2Ac6FW+=0pxpuva`qjfv~!mL%?@^DdumUtE?_ zXj(VD)|u#)(EH3mmF4*pslGNzjO7EgOfEKBJ#4$)?;;P;@Vh-ibrZBXM3n zhM>pu)a0}V>ig1B;oOONubBtD$GkP?hD(Dirjt92W6~H_*>nBS*RHL|MqC{D zFtcTDlVW>ezj8T;ey$)1)(l*HP;((+aJ<4%XJvx<1)sBS8K$GG%7Q34*Cq9~65DUVW6=ZLl%^HTq=~ISpb8x-fbw<7`WAE=6KexaL#M_E?$iN@uD~? zE`vwXcz#bnLeFKRKMh(H!6{;Qn#`PZYN9J*!R4BuvHLZP#0PJLPB7Sa7qDb(v5ehk zPQo82wf|JWyL%XvwH2Ly^z_ech8ia%p+-R}wp}i5;Mq9PIrDjfxx;i)yc8t;4y}=5 z!!2+^x&AgLuTk$ttz^gD$bVFh!}iQG%ioJ5jJlb~hfIOFXuO=9iczqX|O~-h;zj zV%vi(650UJpT<)ECFIH6;E`LMy~7P;eVrN8E}$Uv?4R)uNlY0s%NGR_f`#U0ICGM; z#u6*VzQN^f#a3VOb2}|3hgST^KLz2;CcGhSIvJZ==pL!x1>(C4}IdA z-LnGRuxi&#&fDV-Mgz#rO@|}m8zT%#BXDTrU<+>C{!GAr7$#j#{&~LTNG^|R!w1Pl z;atC{Rv)E~p9R4w`H~qa}=TW?rilldCOi@GlV{|ugs^M3? z+SjBh%*x&g*OF^3HL~wsD2z{fP(pfWLY1;-kVMaVC1VEXZc#wS!)czLCe2b#O zboCcw+$t+)MBrAYN7C7FRvV~gE4Jl&O|j`LWN}Af>um1CO-e%6YfCIAMaXceIyBv`QGxy z&tE<+9WN+%JlOs`_Wa5EN})qYb*(&~=b}oz+fuKE$7!KieXj&ntx~C^6G^8Fg>tij z{!zE3((Q124hjTrvF8KhsQY-1+fDPG4RF3t^^)yC`Kl3f^V1kzZP{M4%5`f``^}XD zPy^-cO3T4rR{vnQw&?3}%R0`8?H~h=e_AIAA7`sTAyJueSq~L8rxW!W?>tSP@iQn> z|5YK|PxRk@Hux6kDS*!n59BL+rCR(b`EKxe#QKjsHCFbIaZn|5Y>UgEK~v44T$`eI znw=D;nU#vTB%s{v+tKya&P^bKk&%5Ji<3j5*DH#z%nSbO>oTKz*1~9(q@|YieQ{<{GR*!;>y1sMLHP^;p z7yz91d%N7~+hp(TCubuQ_OE4_vxfcZQUm);=qeDV+k+VTC*Wu2d3@$qDw;)NI7H-u zs!l+QH9u%&tgp;gZ5}vB$sNDY=M74`Bgqn-bX?TF*);|4h71Pkm1h@CaY+L_3BUW= zj_f7t4nikozCx&g<^t=Xi4r02)>~@Q>y)1CG>&3p)W_tzh>- zS$wr?(q=uIkfdma3T5(aRtbx2+AB*cQ!>NVAFL0=od&eteKpj5mni&rVx`4k?Zn`{ zI*=iZcPOyfPBB?9v9G=gn4f5%WB1iX{$3iBhSk(F zBXwvATV4f|N?0$ARP!8EIz!(Z{a4w~ZE!}5w}u&TPpo)PQM-h5A98|YWTpc-OgL`| zS3i7Rl+yowT}2~ou=WVAVSVqQeQB=Bg-sWg+?^vgdIjCs@Y&jYwMQE^ z9LIedsNMjE<9t1lroFPFbAUp<0i!3i{oe-uoLf5oV=Z;)%k%WRT9WgsR_vO%U0@==c$dapWMfaZ&2omFv7e2%$1;`#hH zbF4#p!YYskwl)AA#FvsDi53CS(eKyL9HrOj=R!qNeOhNia>6D1k_$HlP5c4$By^{3Iba9$R4;c+^v6(gSGB?gNt2V;-g_%8V_B{)u>W;`y9J z!oVZFn8Aol3&c8rF7?gDRX&|vXs-hByiG9B(z(L5CvlgQ6(9<_Z#Mh-bb9K}94Box zKVu2BKe}%F(G3hL+2N9Cdsn;MueH+nE7K<1A?`-PicVMdR`i``7q|Syz)?}HQ3}1NO8g2nvQr}pf~ETgEM-xHtm`Ww%J7Z6dc3<5W7gV9z%UR_z;zr zdKLbfmieST*4*^ol!%Y-1^k%0^7YYdoDnISkC9ca{Cfgt@Q+R(k(ws_*G`f|+!tB~ zKs+CZW}Py6N}5fSPpTm0%Y3CKKz@q*^&UPeyKi3$cPcFAfNb)P)`s;FvYUj#bJ;C~ zInbV5dN%ykzyo{f*j@C`YOgBzDX0s%<<>}X_}(^c5}}+j`=h_`&RpM^4Lm9CQMOiS zyBSW)!ZDkqW8tE;`j%&`hZF7_+B>P*$)<8&RPOxcsmPZwBW#-abf$4!QNdjB0VVX1n1$-%>(=O?p zVcz#I7BS1>!@eKRHW{Sb2M!gCsdw>OXeP>i;r7?f&{19oVBU`M7t7K>vCu$W89NJ2 zPTujna!zuTT<_wv7}n#p;H2z) zND%tIwmwi7%w=|d^WStWAyE~VsB{4)L^vMvC9bU_^vz&k zvSxG_5CA1x=0TX$Ba|Dh5qC2*YPvGvg_2#-Kqq26=y*1m++HT3mk<5&<%0jfaZx_E z{SDj$#a9=Ta2-l9sK%|yTiLqOH7yrvu_k)Z+V_qpG0!HsvUvNOyc;T7b1s-pt&8=Y zKGLJTQ`(uM<7ioG{SC87o%;v{zPTW>Vw?yxwADc`swn60M5`#D&U68e?FzD#s@kG=VZf~tqFX{j>5>qnL0UE~9RgC)jUp+M3T}}G zMH-QmP`blFS_A8OTwEM& zRS|QHq?qSa4fuUuicdfr5=?B~FIyXPa)%P#x}yjmBPk|gKH2OuQ2xTmj;Pnis?=8m@AQVfCP%SRHp?KLK{lk1u8k&J zNJ2y=-q>MP@x&QkpOBz#M(oRX1&g#7Fb|rlB=qoJn-++qob6mG2>rGyc9NMqth2+1 ziD#iz_7Zt9@oUo(6G+1(&L#-Eq%Qv$8@obX34l4Dv9Vs3tQr*XA*3E4m~oZaWt@<3 zp`q3eu34?>H{4M0Yj`5djPrm|mXvVe~ZPLES8iTlGDO5*A5!1impNTCgeUhH2(|8!*3mXGIVSV>XJ_kqGBK_?bY z%WzI=%9!{yd6S{5HgRUUEbvB_i>o`dGI0SeGiU?O_*9b_x81yS3@vHM@} ze{FV^9q)Bo?e#!<&#VegY#HC)oc4))|&)eH&B8z6V zG)m&+A1r`8;X^^FsofBkgd+a$h~v>XI-$p4Z4rfso>oEQ$NnO?apKx1#;Cpd_@cLL zR>%M)+0#S-jJTz6R}qIpE`(KjD_FicJRE&~Fb%;bAqcqsF(tjTX;=5BF}nL~hkrg+ z%F{ROf1kw>{lEYzQn$IhoOS>=ewMfn)FkCf=TD#GnGRYjN?3SNF!=Y451)`v=FkNF z2MmSVMe^z9x5B;BaTJ5B>%fJ?C#Xffs16k|tgbr>XrF=0;8^ufTyf;W@o5(#hE!VhclyU&p|ZoOZQM#leugM65LlgU%Ao>GpXe z{EUyq7JK+O*NIk+)Cs-I_&@R7o3)!OVnw zScf<)OYZ)u60;Y0C74s2`FihlmKi-9vRZD~o&0>l*D$j*kBw)iOGT{Y9-e);GPpM7 z^R?3_F@wd=^h=M&xi6IvG8uCVyUl1Ec}t#m{SW{wQMfzrfGCs7xA)mssjW>h_F%_Q z*#BmNiZD2BYCtfHljDVNKThMb3Ka(yqw9;q6kg`j;O(OzkR0Chi%z{% z2^s&;(I;&Evl1I(!try4aJaV0e zD-ckv()(=HEC3-au1}|Rlvs6447)TwfDtZ^Z@t*qZ%@MW&amy5Q6h@^{(IPXF3E>c zG9d6{BmeD{-W+whSsTrU)J4r}Bpxr&xNI^i>uq;e?r|WyE>wk| z23QRi;xl%f$(WjHV4yJyqvDqbcDB*3Fa9SlDd!Q9o=NtaG%P0_n9upO1Dw zu-xECMC!jTy$W*LP=}~XOW0NrOnhU(i_V=GqkO8Eg#~LS*ViEt0|)DonMV$_Wn%XQ za$d8deVu?`=-g#mKD^d>s$N5PcH=x*a-B19iZ)5TdgduQ(m&&&R$HTHhx#{fnkZKp zdKEl(cXtCl^-qF;hVRFZXhFctKy?LnTD@-=0vK@BYy*e+oFZV7x`4`4gEfml2CwWx#r=1ryfUoZ8bi_5%ondt@X=7ak?xj*o1kL4f zGd{`r!>(}5{1=$nS%}_7@7vfN$f37Czxs-BX+Z|1`8Md|iz#~SnQMtf9Ur<{jMkZ( z=z?x-2)Y!`4Oc!(_8j#t`O&aBRcIIN(mft2#T{?zS1k?|yI`AWL7ZJ-{QJubGOR~R zBgE$v(4y!=g@)xZP;nM9V`m+>h=XAGQJeT^Fhw*Y% z2QYiJ=d7V>x0~Q?%nG#LnYOFXu2eeP=_t`y;oI&lu+iS;Y}KT8NaJ(d{1}`%pPPfj zZCG~p1KZnTl8~ZkLEttF(5COaBsH@x_{s2@42K^(a3bIJ<9+QS2eSg}5Lj)2RpqaP zH;TL1%qzw}+hZ7GlbWEKQZK>2Pn6S0#R+N+oT>T}a(V)gxb96_m-Y!p2qUBaq*w0iuEt@XH5qVm$}6zxm1G7;5> zZXhfYOSN=cyvMc+UE)pW%>M&*lv3?F+7-7(a-Y;(-EpNB1gHJF-SM}_%RwZ0Oi(gxnDcZ z7C;~Rk2nr+8WIVB?b0>lg~k(v7xdo=ze|s%3;Z?S(ve`3N@W@tw@=DcBRxB$wVqM_ zVfJ%p-Y@9n85NE}gpPB)cA+8`^g}Rb1NTWaKo$*UMN>{su;2XT2)KXTM)HN`nE(~W zgxoP2YF_g@2Tq-<_D4f)-Oraqt}FeQJHWFbsfkAZgLaR- zBMY6&jEprrcG7&6EjD|)(0>? z%Zb)#b_1Dx)fk+>d4ltA+eVMdRe~#8#!uf)Kx;7ki7UQ+bLq(l=F)#2Ft5Q%`&bJZ z<5eI~iTd0MWND@kpyvolv°W!Bl_S6M}SY+}orPFOyChrf79=jOI!HI^6LNjK@ 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 R91ikNNlpz@bkQv6e*qSlx`F@z literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/import.drawio.png b/dim/documentation/source/_static/swa/usecases/import.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..a49472347c80bec7beb811885f8b7b3325fac605 GIT binary patch literal 64916 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

-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 Qf`2+Yc5lz$YIo}Y0leiEQvd(} literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/legend.drawio.png b/dim/documentation/source/_static/swa/usecases/legend.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..aad6ad70d4603dd7282dfcf31538508f6db730bc GIT binary patch literal 36906 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

C#iu1RfI^G7Q$qBI(v1Ev!y zf0^94f7fv}lfXFC`;{Gg9LcxDP#$GP_Sz4c4k{QsrlPI~DLItBmc}kS6<67-XUht5 ztrL*N-IJG=z$59!A)oJ#phl2<^SkSYm?pUUzV(fc3H#nt^nv;{B#E%B%SzBGowlUK zo-2}x+-;WPCr}N4Zs5TBOR}2fpzU3Uy$Yl|be+lw>JW<63#kRuYs@}KiREj5(=~9Z zFrHe!Y9J?R&Po|`d~qPZR-e(E9QE9s?vk_cv(61P=V1O+L0(;=3I@mbUSgq0uz6&) z%c@F^bw5?f+3ugAc*%vP3de8GPSZAw#BV>eUGwWi^G~2IZN51mFs7)rqEIYhv=J`= zAryY2POd2X-qjd=%gP}%Li!u` zf{IVF`IQ5vSB@bb!@C4`BBk7iwEst8$EV0gNT$MkouoF7qAaSY{!K4n*BrqLxeHJW zqyC1uO!#1AmE<}5V=r3SN`-Fn$IETOPYko}+~u1kxLpRmEU)A5b{QXa@zdz<39u(I z<^8?2T52u!X@%||CqJArj3oNm98}X8)x1GD84$*CEAj<8zaUCrMqK0a5|H0@pkzIw zreQwr&P>~G8+UqxQVuI*%O z-9&Eij$h;#E+8kbttL_zzR0hPnI*j{joPl=s2`Tb{{?x4rph5Z&tE+zlk*y|gHN=jcN#H z*gj3l@31hfnf=R?S$n0J4!?6P4|#LQ(7SdZLUM$vvrZn06#B|3m-F!25aO2b`o5uk z%6iqAijxRIQUpRZT9t>& zr~U^g?`Sqmv<|p9(L)PqsuF5~6c%7^p{Z#Wb%a(!)OVNJ92K1+!}TIMOSK68}e^=W2!<9>n6+&GdK2F#qNxrn!QK z7`cJ%=^}R~WNCH4(S8m|;3V*LLn38?Hi50P;BI6v9FA}=5kUxUoSVCn1MlBqN9z{? zWY3ap$cwU9xl;M^9tq!^372X(i1WAwXxq2+GfD>zc6Pn>Ct5Si*LZ;Yc7=!nSCGK) z8^40hh}4xF5n~ zq3-_0EbWc?c|CEH zH{fm`pWj<<|NR4G1|CZ-PrTsk`#xF&dY&nvudt8f(GshzI`P-lZj$M#sgKH$57~aU zkct+ohB1B`&iImhE5nre%)^N`GL`}+da)^Lm2i%_*3b;ykwP);l#8-LqAXkV-)DAq zc8E`&gDzc4_*S{;(O&bGW+#QWZSsr3oNZRKvY*?2!=p(WY6EbKl6(>B`Z%qy%h|*& zN8q$%wedN$&VPoXdGZA$e_tTfaO;+SYAO^wn=PLzZ~1@EY|NA}G!jByMUbuoLGtUK zqAhWL4CEyF(aC-M`9m=irkEFGarK^;p5jW;>PfzdJQY5K2ISX=55}cgG%~*Kc_f1; z8P>wR4^0eIL!Ppl;nN^Q*`6ZtL#?pL<{5xr*dF-9Lq0@Wge+6gEg@tOhsJNG|zkeRzmS&iO^M^YkhAUH@2) QGw@GcSxc!{!7T890kX5Hp8x;= literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/reading.drawio.png b/dim/documentation/source/_static/swa/usecases/reading.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..46eb6990c0e467b41395535b036b17c389cd0546 GIT binary patch literal 31530 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 J9yRm%e*nbj6F>j} literal 0 HcmV?d00001 diff --git a/dim/documentation/source/_static/swa/usecases/verifier.drawio.png b/dim/documentation/source/_static/swa/usecases/verifier.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..8aeb21049238917885a1314b5d3e02517a7a23f9 GIT binary patch literal 56151 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 D$l{U` literal 0 HcmV?d00001 diff --git a/dim/documentation/source/conf.py b/dim/documentation/source/conf.py new file mode 100644 index 0000000..1cc674c --- /dev/null +++ b/dim/documentation/source/conf.py @@ -0,0 +1,30 @@ +import sys +from pathlib import Path +from datetime import datetime + +EXTENSION_ROOT = Path("../../..") +sys.path = [str(path.resolve()) for path in EXTENSION_ROOT.glob("dox_*")] + sys.path + +project = "Dim" +author = "Accenture" +copyright = ( + f"{datetime.now().year} Accenture. All rights reserved. " + f"Accenture proprietary and confidential material" +) + +html_context = {"document_status_default": "Released", "data_classification_default": None} + +extensions = [ + "sphinxcontrib.jquery", + "dox_style", + "dox_trace", +] + +with open("../../version.txt", "r") as file: + version = file.read().strip() + +exclude_patterns = ["pages/requirements/index*"] + +numfig = True + +dox_style_footer = "footer.yaml" diff --git a/dim/documentation/source/index.rst b/dim/documentation/source/index.rst new file mode 100644 index 0000000..052ebd1 --- /dev/null +++ b/dim/documentation/source/index.rst @@ -0,0 +1,27 @@ +Dim +=== + +Documentation of Dim, the light-weight requirements tool. + +.. toctree:: + :maxdepth: 2 + + pages/introduction + pages/installation + pages/integration + pages/syntax + pages/cli + pages/api + pages/format + pages/version_handling + +.. toctree:: + :maxdepth: 1 + + pages/changelog + +.. toctree:: + :maxdepth: 2 + + pages/architecture + pages/development diff --git a/dim/documentation/source/pages/.gitignore b/dim/documentation/source/pages/.gitignore new file mode 100644 index 0000000..7539f08 --- /dev/null +++ b/dim/documentation/source/pages/.gitignore @@ -0,0 +1 @@ +requirements/ diff --git a/dim/documentation/source/pages/api.rst b/dim/documentation/source/pages/api.rst new file mode 100644 index 0000000..acd9d62 --- /dev/null +++ b/dim/documentation/source/pages/api.rst @@ -0,0 +1,218 @@ +.. _ruby_interface: + +Ruby Interface +============== + +It is possible to access the data via Ruby. All default fields are already evaluated. + +Loading +------- + +Instantiate a loader and call the ``load()`` method. ``load()`` offers three arguments: + +- ``file:`` Either a requirements or a config filename. Mandatory argument. +- ``attributes_file:`` Project specific custom attributes filename, Optional, defaults to empty filepath. +- ``allow_missing`` Ignore unresolved references if set to *true*. Optional, defaults to *false*. +- ``silent`` Suppress logging output while loading files if set to *true*. Optional, defaults to + *true*. +- ``no_check_enclosed`` Skips the enclosed file check. Optional, defaults to *false*. + +Example: + +.. code-block:: ruby + + require 'dim/loader' + + l = Dim::Loader.new + l.load(file: "module.dim", attributes_file: "attributes.dim", allow_missing: true, silent: false) + +.. _data_access: + +Data Access +----------- + +After loading, all data is accessible via the member variable *requirements* of the loader. This +variable is a hash, the keys are the IDs of the requirements, the values the requirement objects. + +A requirements object has the following getters: + +- All **attribute names** from :ref:`requirements_files` to access the data, like *text*, + *review_status*, etc. +- **document**: the document name used in the :ref:`requirements_files` +- **id**: for convenience, same as the key in the *requirements* hash +- **origin**, **category**: from config file +- **filename**, **line_number**: to print error messages, etc. +- **existingRefs**: array of ref-IDs which really exists (useful if `allow_missing` was set to + *true*) +- **backwardRefs**: array of ref-IDs which reference *this* requirement +- **upstreamRefs**: array of IDs from refs to higher category level plus + backward-refs from higher or same category level +- **downstreamRefs**: array of IDs from refs to lower or same category level plus + backward refs from lower category + +The following table shows the return types of the getter methods: + +.. list-table:: + :widths: 50, 50 + :header-rows: 1 + + * - Strings + - Array of Strings + * - asil + - backwardRefs + * - cal + - developer + * - change_request + - downstreamRefs + * - comment + - existingRefs + * - feature + - refs + * - filename + - sources + * - id + - tags + * - miscellaneous + - verification_methods + * - document + - tester + * - origin + - + * - review_status + - + * - status + - + * - text + - + * - type + - + * - verification_criteria + - + +Some examples: + +.. code-block:: ruby + + require 'dim/loader' + + l = Dim::Loader.new + l.load(...) + + requirements_text = l.requirements["myId"].text + modules = l.requirements.values.map {|r| r.document}.uniq + valid_notRejected_Reqs = l.requirements.values.select do |r| + r.type == "requirement" && r.status == "valid" && r.review_status != "rejected" + end + devMyCompany = reqs.select {|r| r.developer.include?("MyCompany")} + reqsWithRefs = reqs.select {|r| !r.refs.empty? } + +The **metadata** is available via the member variable *metadata* of the loader. +This variable is a hash with document name as key and the metadata as string value. + +Example: + +.. code-block:: ruby + + require 'dim/loader' + + l = Dim::Loader.new + l.load(...) + + puts l.metadata["document"] + + +Convenience Methods +------------------- + +String Lists +++++++++++++ + +Dim extends the Ruby String class with the following methods which can be also used by custom +scripts: + +- | ``cleanSplit`` returns an array of the elements without leading and trailing whitespaces + | Example: :code:`"a,a,b ,, c".cleanSplit() == ["a", "a", "b", "", "c"]` + +- | ``cleanArray`` same as cleanSplit, but without empty elements + | Example: :code:`"a,a,b ,, c".cleanArray() == ["a", "a", "b", "c"]` + +- | ``cleanUniqArray`` same as cleanArray, but also removes duplicates + | Example: :code:`"a,a,b ,, c".cleanArray() == ["a", "b", "c"]` + +- | ``cleanString`` removes empty elements, leading and trailing whitespaces + | Example: :code:`"a,a,b ,, c".cleanString() == "a, a, b, c"` + +- | ``cleanUniqString`` same as cleanString but also removes duplicates + | Example: :code:`"a,a,b ,, c".cleanUniqString() == "a, b, c"` + +- | ``addEnum`` adds another element to the list and makes all elements in the list unique + | Example: :code:`"a, b, c, a".addEnum("d") == "a, b, c, d"` + +- | ``removeEnum`` removes all enums with a specific value from the list + | Example: :code:`"a, b, c, a".removeEnum("a") == "b, c"` + +.. _convenience_calculations: + +Calculations +++++++++++++ + +- ``safety_relevant?`` returns + + - *true* if the *asil* in the requirement is neither *QM* nor *not_set*, + - otherwise *false*. + +- ``security_relevant?`` returns + + - *true* if the *cal* in the requirement is neither *QM* nor *not_set*, + - otherwise *false*. + +.. _original_data: + +Original Data (Expert Usage) +---------------------------- + +For special expert usages, the loader also provides a member variable *original_data*. +This is a hash of **filenames** to the **data read from the files** via YAML library. + +Note, that a few things are nevertheless changed and not completely "original": + +- converting short forms to regular forms +- converting non-breaking spaces to regular spaces +- removing duplicate entries from verification_methods and tags +- stripping strings +- adding non-existing attributes of a requirement as empty strings + +Example: + +.. code-block:: yaml + + # filename.dim + document: myModule + + myId: + text: abc + +.. code-block:: ruby + + # script + require 'dim/loader' + + l = Dim::Loader.new + l.load(...) + + l.original_data["filename.dim"]["module"] == "myModule" + l.original_data["filename.dim"]["myId"]["text"] == "abc" + +Use the formatter to write changed data back to the requirements files: + +.. code-block:: ruby + + require 'dim/commands/format' + + l = Dim::Loader.new + l.load(...) + + l.original_data ... + + formatter = Dim::Format.new(l) + formatter.execute diff --git a/dim/documentation/source/pages/architecture.rst b/dim/documentation/source/pages/architecture.rst new file mode 100644 index 0000000..57453dc --- /dev/null +++ b/dim/documentation/source/pages/architecture.rst @@ -0,0 +1,15 @@ +Architecture +============ + +This section is for developers, maintainers and reviewers of the Dim tool. + +.. toctree:: + :maxdepth: 2 + + architecture/inout + architecture/usecases + architecture/classes + architecture/dynamic + architecture/scripting + architecture/fmea + architecture/legend diff --git a/dim/documentation/source/pages/architecture/classes.rst b/dim/documentation/source/pages/architecture/classes.rst new file mode 100644 index 0000000..c205636 --- /dev/null +++ b/dim/documentation/source/pages/architecture/classes.rst @@ -0,0 +1,34 @@ +.. _dim_classes: + +Classes +======= + +.. figure:: ../../_static/swa/overview/classes.drawio.png + :scale: 100% + :align: center + + Class overview + +The classes of Dim can be divided into six groups: + +- **Main:** the entry point of this tool, it ties options, loader and subcommands together, see + :ref:`main workflow `. +- **Options:** loads the :ref:`options ` from the command line and makes them + globally available. +- **Loading and data storage:** These classes are responsible to :ref:`load ` the + requirements files and to provide the data to the subcommands. +- **Subcommands:** These :ref:`commands ` represent the central + features of Dim: + + - Checking Dim files for :ref:`consistency `. + - :ref:`Exporting ` data to different formats. + - :ref:`Formatting ` requirements files. + - Printing :ref:`statistics `. +- **Exporters:** :ref:`Export ` is also a subcommand, but it's separated by output + formats, namely :ref:`RST `, :ref:`CSV ` and + :ref:`JSON `. +- **Helper classes:** These classes cover different use cases: + + - Providing convenient methods for string handling (String). + - Helping to generate better error messages when loading the requirements files (Psych). + - Simplifying the unit tests (ThreadOut, ExitHelper). diff --git a/dim/documentation/source/pages/architecture/dynamic.rst b/dim/documentation/source/pages/architecture/dynamic.rst new file mode 100644 index 0000000..27fbc7d --- /dev/null +++ b/dim/documentation/source/pages/architecture/dynamic.rst @@ -0,0 +1,174 @@ +Dynamic Behaviour +================= + +.. _workflow_main: + +Main +---- + +This is the base workflow: + +.. _workflow_main_fig: + +.. figure:: ../../_static/swa/dynamic/main_workflow.drawio.png + :scale: 100% + :align: center + + Main workflow + +Notes: + +- Not all subcommands require to load files, e.g. for printing the version. +- If any action fails, the exit code is set to 1 instead of 0. +- Exceptions are not caught. If a Ruby application terminates abnormally, the exit code is set to + a value != 0 depending on the exception type. + +.. _workflow_parse_options: + +Parse Options +------------- + +.. figure:: ../../_static/swa/dynamic/options.drawio.png + :scale: 100% + :align: center + + Options + +The outcome of this workflow can be either: + + - An option was found which causes the tool to gracefully exit immediately, e.g. after + printing the license. + - Parsing failed, e.g. something is missing, invalid or inconsistent. + - All options successfully loaded and stored globally. + +.. _workflow_loader: + +Load Files +---------- + + +.. figure:: ../../_static/swa/dynamic/loader.drawio.png + :scale: 100% + :align: center + + Loader + +| **Load**: +| If a filename was specified in the options, this *loader* workflow is executed. The file can be + a config file or a requirements file. A config file can refer to one or more requirements files. + +| **Store**: +| Loaded requirements are harmonized, which means not specified attributes will become empty + strings. This makes further processing easier. + The result of this harmonization is called *original data* and stored in the loader instance. + It is used by e.g. the *format* subcommand. Afterwards the default values get resolved and are set + for empty attributes if applicable. + +| **Check:** +| At the end the consistency is always checked, independently from the subcommand. + +.. _workflow_execute_subcommand: + +Execute Subcommand +------------------ + +.. figure:: ../../_static/swa/dynamic/subcommand.drawio.png + :scale: 100% + :align: center + + Subcommands + +This part of the program flow is straight forward. Depending on the command line options, the +appropriate subcommand is executed. Invalid subcommand options were already handled in +:ref:`workflow_parse_options`. + +.. _workflow_check: + +Subcommand "check" +------------------ + +This subcommand is just a dummy and completely empty. The consistency check is always done when +:ref:`loading ` the files. + +.. _workflow_export: + +Subcommand "export" +------------------- + +.. figure:: ../../_static/swa/dynamic/export.drawio.png + :scale: 100% + :align: center + + Exporting requirements + +The files are exported to a specific output **folder** in a specific **type** specified with +command line options. A **filter** can be specified to export only a part of the requirements. +Files like images listed in the `enclosed` attribute of the input file are also copied to the output +folder. + +The algorithm is always the same, but internally different implementations of the ExporterInterface +(see :ref:`dim_classes`) are called depending on the type which can be RST, JSON and CSV. + +.. _workflow_export_rst: + +RST ++++ + +Requirements are exported to Sphinx so that the `dox_trace` extension of Sphinx can understand the +content and generate a nice HTML view. + +This is the only export type where an index file is generated (with the Sphinx `toctree` element). + +.. _workflow_export_json: + +JSON +++++ + + +This exporter simply uses the Ruby JSON library to convert the requirement objects to JSON objects +which can be written to the output folder. + +No index file is written. + +.. _workflow_export_csv: + +CSV ++++ + +The requirements are converted to a CSV format. + +No index file is written. + +.. _workflow_format: + +Subcommand "format" +------------------- + +.. figure:: ../../_static/swa/dynamic/format.drawio.png + :scale: 100% + :align: center + + Formatting input files + +The following types of formatting are possible: + +- ``in-place``: See use case :ref:`use_case_change_requirements`. +- ``check-only``: Executed from the verifier in the :ref:`Version Control System ` use + case. +- ``extra``: A debugging feature to write to separate files instead of changing the input files + directly. +- ``stdout``: similar to `extra`, but writing the output to the console. + +.. _workflow_stats: + +Subcommand "stats" +------------------ + +.. figure:: ../../_static/swa/dynamic/stats.drawio.png + :scale: 100% + :align: center + + Printing statistics + +This subcommand prints generic statistics of the requirements specified in the input files +like number of total number of requirements and number of accepted or rejected requirements. diff --git a/dim/documentation/source/pages/architecture/fmea.rst b/dim/documentation/source/pages/architecture/fmea.rst new file mode 100644 index 0000000..22cd135 --- /dev/null +++ b/dim/documentation/source/pages/architecture/fmea.rst @@ -0,0 +1,107 @@ +FMEA +==== + +The FMEA is done on the "first zoom level" of the architecture, + +- the :ref:`main workflow of the command line ` usage and +- the :ref:`main workflow of the scripting ` usage. + +The relevant elements are annotated by oval labels, see also the :ref:`diagram legend `. + +Fault Model +----------- + +The following analysis is based on this generic *fault model* for activity diagrams: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + :width: 100% + + * - Element Type + - Error ID + - Generic Error Description + * - Data storage + - DS1 + - Stored data changed before read operation + * - + - DS2 + - New data not stored / keeps old data / stuck at specific value + * - Data flow + - DF1 + - Transferred data changed + * - + - DF2 + - Transferred data lost + * - + - DF3 + - Data stored at / read from wrong location in data store + * - + - DF4 + - Data transferred to wrong data store + * - Processing + - PR1 + - Calculates wrong results + * - + - PR2 + - Processing is skipped + * - + - PR3 + - Processing too slow/fast + * - Control flow + - CF1 + - Control flow stops + * - + - CF2 + - Control flow proceeds to wrong process + +If more than one error is identified for the same element with the same error ID, a counter is +added, e.g. `PR1.1`, `PR1.2`, etc. + +In the following sections, references to files are shown which end with ``_spec.rb``. These files +are test files which can be found in the ``spec`` folder of the *Dim* tool, e.g. +``/spec/options_spec.rb``. + +Generalized Errors +------------------ + +The following errors are analyzed generically and not on architectural element level. + +.. csv-table:: + :file: fmea/general.csv + :header-rows: 1 + :widths: 12 30 32 + :width: 100% + :delim: , + +.. _fmea_command_line_workflow: + +Command Line Workflow +--------------------- + +This analysis is done on the :numref:`workflow_main_fig` with the :ref:`use_cases` in mind. + +.. csv-table:: + :file: fmea/dynamic.csv + :header-rows: 1 + :widths: 5 5 25 35 25 + :width: 100% + :delim: , + +.. _fmea_scripting_workflow: + +Scripting Workflow +------------------ + +This analysis is done on the :numref:`scripting_main_fig` with the :ref:`use_cases` in mind. + +The basic idea (loading, processing, writing) is the same as in the +:ref:`fmea_command_line_workflow`. Therefore references to the analysis of that workflow are added +here to avoid unnecessary duplication. + +.. csv-table:: + :file: fmea/scripting.csv + :header-rows: 1 + :widths: 5 5 25 35 25 + :width: 100% + :delim: , diff --git a/dim/documentation/source/pages/architecture/fmea/dynamic.csv b/dim/documentation/source/pages/architecture/fmea/dynamic.csv new file mode 100644 index 0000000..c617959 --- /dev/null +++ b/dim/documentation/source/pages/architecture/fmea/dynamic.csv @@ -0,0 +1,33 @@ +Element ID,Error ID,Specific Error Description,Measures,References +p1,PR1,Incorrectly treated command line arguments will lead to unpredictable behaviour.,"In most cases wrong command line arguments will lead to an error, which means Dim terminates with an exit code != 0. In many cases the user will recognize if Dim is doing unexpected steps like formatting instead of exporting, or using a different export output format. Reviews are mandatory. Tested by unit tests.",":file:`options_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +,PR2,"No options are set, Dim is not executing the intended steps.","Dim requires some arguments to be set. If not written into the options data store, the program will raise an exception when trying to access the `options` data store which leads to an exit code != 0.",:ref:`Workflow Execute Subcommand ` +p2,PR1.1,"Files are loaded incorrectly, not loaded completely or wrong files are loaded.",In most cases syntax and consistency checks within the loader will recognize the errors and Dim will terminate with exit code != 0. Otherwise the data store `data` will get incorrect data. This can often be recognized by the user or latest by the reviewer in a code review tool. Reviews are mandatory. Tested by unit tests.,":file:`loader_spec.rb`, |br|:file:`requirement_spec.rb`, |br|:file:`consistency_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +,PR1.2,Files do not exist.,"If files do not exist, Dim will terminate with an exit code != 0. Tested by unit test.",:file:`loader_spec.rb` +,PR2,"If loading is skipped, no requirements are available for subsequent steps.","This is recognized by the user or latest by the reviewer in a code review tool, e.g. getting empty export files.",":ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +p3,PR1.1,The formatter changes the `Input files` incorrectly or writes incorrect `Separately stored formatted input files`.,In most cases this is recognized by the user or latest by the reviewer in a code review tool. Reviews are mandatory. Tested by unit tests.,":file:`format_spec.rb`, |br|:ref:`Integration Guide Verifier `" +,PR1.2,The exporter produces wrong files or writes them to a wrong location.,"In most cases this is recognized by the user or latest by the reviewer in a code review tool. In a verifier, subsequent steps will fail. Reviews are mandatory. Tested by unit tests.",":file:`export_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +,PR1.3,The built-in stats are incorrect.,In most cases this is recognized by the user by doing sanity checks. Statistics reviews are mandatory. Tested by unit tests.,":file:`stats_spec.rb`, |br|:ref:`Integration Guide Statistics `" +,PR2.1,The formatter does not write the output correctly or the format options are not processed correctly.,In most cases this is recognized by the user or latest by the reviewer in a code review tool. Reviews are mandatory. Tested by unit tests.,":file:`format_spec.rb`, |br|:ref:`Integration Guide Verifier `" +,PR2.2,The exporter does not write to `Exported files`.,Non-existing `Exported Files` will lead to an error in the verifier. Reviews are mandatory. Tested by unit tests.,":file:`export_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +,PR2.3,The built-in stats are not printed to the console.,Recognized by the user. Statistics reviews are mandatory. Tested by unit tests.,":file:`stats_spec.rb`, |br|:ref:`Integration Guide Statistics `" +p4,PR1,The exit code is set to a value != 0.,An exit code != 0 indicates an error. A verifier will reject the commit. In almost every unit test the exit code is checked.,:ref:`Integration Guide Verifier ` +,PR2,The exit code is not set explicitly. A value != 0 is used by the underlying Ruby or OS framework.,An exit code != 0 indicates an error. A verifier will reject the commit. In almost every unit test the exit code is checked.,:ref:`Integration Guide Verifier ` +p5,PR1,The exit code is set to 0.,In almost every unit test the exit code is checked.,See unit tests. +,PR2,The exit code is not set explicitly. 0 is used by the underlying Ruby or OS framework.,In almost every unit test the exit code is checked.,See unit tests. +s1,DS1,Wrong command line arguments used.,:greyitalic:`same as p1/PR1`,:greyitalic:`n/a` +,DS2,":greyitalic:`n/a, only read access`",:greyitalic:`n/a`,:greyitalic:`n/a` +s2,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Error messages are not visible on console.,"The user might miss the information what went wrong, but the exit code != 0 indicates that something went wrong. A verifer will reject the commit.",:ref:`Integration Guide Verifier ` +,DS2,":greyitalic:`n/a, only read access`",:greyitalic:`n/a`,:greyitalic:`n/a` +s4,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Wrong exit code used.,:greyitalic:`same as p4/PR2 and p5/PR2`,:greyitalic:`n/a` +s5,DS1,Corrupted data leads to incorrect output of Dim.,:greyitalic:`same as p3/PR1.1 to p3/PR1.3`,:greyitalic:`n/a` +,DS2,Requirements are not available for subsequent steps or data is incomplete.,In most cases this is recognized by the user or in a review. Reviews are mandatory. Tested by unit tests.,":file:`export_spec.rb` |br|:file:`format_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `, |br|:ref:`Integration Guide Statistics `" +s6,DS1,Wrong options used.,:greyitalic:`same as p1/PR1`,:greyitalic:`n/a` +,DS2,Command line arguments are ignored.,:greyitalic:`same as p1/PR2`,:greyitalic:`n/a` +s7,DS1,Wrong requirements data is loaded.,:greyitalic:`same as p2/PR1.1`,:greyitalic:`n/a` +,DS2,`Input files` are not formatted.,"When files cannot be written to the file system, an exception will be raised, which leads to an exit code != 0. A verifier will reject unformatted files.",:ref:`Integration Guide Verifier ` +s8,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,`Separately stored formatted input files` not written or stay untouched.,"When files cannot be written to the file system, an exception will be raised. Beside that, these files are only used for previewing the formatting without touching the `Input files`. Changes are not committed, therefore there is no risk.",:greyitalic:`n/a` +s9,DS1,":greyitalic:`n/a, only write access`.",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,`Exported files` are not written or stay untouched.,"When files cannot be written to the file system, an exception will be raised, which leads to an exit code != 0. A verifier will reject the commit. Export reviews are mandatory.",":ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" diff --git a/dim/documentation/source/pages/architecture/fmea/general.csv b/dim/documentation/source/pages/architecture/fmea/general.csv new file mode 100644 index 0000000..5d1638e --- /dev/null +++ b/dim/documentation/source/pages/architecture/fmea/general.csv @@ -0,0 +1,6 @@ +Error ID,General Error Description,Measures +"DF1, DF2, DF3",Data is corrupted or lost during file access or wrong files are accessed.,This tool runs without network access or memory queues. It is assumed that underlying layers like Ruby or the OS are qualified. Potential issues with data are analyzed in "Data storage" and "Processing" elements. +DF4,"Every data store type exists only once in the system, e.g. ""Input files"" cannot be stored in ""Exit code"".",Trying to do something like this will lead to a program exception. Dim will terminate with an exit code != 0. +PR3,"Dim has no strict timing constraints and has no concurrently running threads, so it cannot run too fast. However, a too slow execution might frustrate the user, so that the user removes the mandatory check on the code review tool.",It's mentioned in the integration guideline of Dim that the :ref:`verifier ` from the code review tool is mandatory and must not be removed or skipped. +CF1,A complete stop of the control flow is usually no problem for a tool which runs offline and not on the target hardware. Dim is used for verifying changes on a code review tool. A stopped or terminated Dim check due to timeout must not lead to a merged commit.,"It's mentioned in the integration guideline of Dim that the :ref:`verifier ` from the code review tool must exit successfully, otherwise the commit must be rejected." +CF2,This is a very generic problem and can lead to random errors.,"The likelihood is reduced to a minimum by intensive unit tests. To ensure that enough unit tests are written, the code coverage is 100%." diff --git a/dim/documentation/source/pages/architecture/fmea/scripting.csv b/dim/documentation/source/pages/architecture/fmea/scripting.csv new file mode 100644 index 0000000..241469f --- /dev/null +++ b/dim/documentation/source/pages/architecture/fmea/scripting.csv @@ -0,0 +1,13 @@ +Element ID,Error ID,Specific Error Description,Measures,References +q1,PR1.1,Files are loaded incorrectly or not loaded completely.,In most cases syntax and consistency checks within the loader will recognize the errors and Dim will terminate with exit code != 0. Otherwise the data store `data` will get incorrect data. This can be recognized by the user or latest by the reviewer in a code review tool. Reviews are mandatory. Tested by unit tests.,":file:`loader_spec.rb`, |br|:file:`requirement_spec.rb`, |br|:file:`consistency_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +,PR1.2,Wrong files loaded.,In almost every case random files are neither syntactically correct nor consistent which will lead to loading errors. In most of the remaining cases the wrong data is recognized by a mandatory review. Tested by unit tests.,":file:`loader_spec.rb`, |br|:file:`consistency_spec.rb`, |br|:file:`requirement_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Scripting `" +,PR2,"If loading is skipped, no requirements are available for subsequent steps.","This is recognized by the user or latest by the reviewer in a code review tool, e.g. getting empty export files.",":ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +q2,PR1,The formatter changes the the `Input files` incorrectly.,In most cases this is recognized by the user or latest by the reviewer in a code review tools. Reviews are mandatory. Tested by unit tests.,":file:`format_spec.rb`, |br|:ref:`Integration Guide Verifier `" +,PR2,The formatter does not write to `Input files`.,In most cases this is recognized by the user or latest by the reviewer in a code review tool. Reviews are mandatory. Tested by unit tests.,":file:`export_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Export `" +q3,PR1,"Requirements are not proceseed as intended, statistics are incorrect.","It is mandatory to review scripts and their outcome to ensure correctness. +Inconsistent and syntactically incorrect data written to `Input files` is recognized by the verifier in the version control system. Reviews are mandatory. Tested by unit tests.",":file:`loader_spec.rb`, |br|:file:`consistency_spec.rb`, |br|:file:`requirement_spec.rb`, |br|:ref:`Integration Guide Verifier `, |br|:ref:`Integration Guide Scripting `" +,PR2,"Requirements are not processed, statistics are not created.",It is mandatory to review scripts and their outcome to ensure correctness.,:ref:`Integration Guide Scripting ` +t1,DS1,Wrong requirements data is loaded.,:greyitalic:`same as q1/PR1`,:greyitalic:`n/a` +,DS2,`Input files` are not updated as intended by the script.,:greyitalic:`same as q3/PR2`,:greyitalic:`n/a` +t2,DS1,Corrupted data leads to incorrect output of the script.,:greyitalic:`same as q3/PR1`,:greyitalic:`n/a` +,DS2,Requirements are not available for subsequent steps or data is incomplete.,:greyitalic:`same as q3/PR2`,:greyitalic:`n/a` diff --git a/dim/documentation/source/pages/architecture/inout.rst b/dim/documentation/source/pages/architecture/inout.rst new file mode 100644 index 0000000..65aba66 --- /dev/null +++ b/dim/documentation/source/pages/architecture/inout.rst @@ -0,0 +1,23 @@ +Input / Output +============== + +.. _figuretest: + +.. figure:: ../../_static/swa/overview/inout.drawio.png + :scale: 100% + :align: center + + Input / output + +Dim is a command line tool, so it has + +- **command line arguments** as input and +- **console output** and an **exit code** as output. + +The file system is accessed + +- to read and write the **input files**, +- to write **separately stored formatted input files** and +- to write **exported files**, e.g. in RST and CSV format. + +Dim also provides a Ruby Interface to read and write **data** of the elements. diff --git a/dim/documentation/source/pages/architecture/legend.rst b/dim/documentation/source/pages/architecture/legend.rst new file mode 100644 index 0000000..98a95ab --- /dev/null +++ b/dim/documentation/source/pages/architecture/legend.rst @@ -0,0 +1,12 @@ +.. _legend: + +Diagram Legend +============== + +The following diagram elements are used: + +.. figure:: ../../_static/swa/usecases/legend.drawio.png + :scale: 100% + :align: center + + Legend diff --git a/dim/documentation/source/pages/architecture/scripting.rst b/dim/documentation/source/pages/architecture/scripting.rst new file mode 100644 index 0000000..df3f33a --- /dev/null +++ b/dim/documentation/source/pages/architecture/scripting.rst @@ -0,0 +1,56 @@ +Scripting +========= + +.. _workflow_scripting_main: + + +Main +---- + +This is the generic scripting workflow: + +.. _scripting_main_fig: + + +.. figure:: ../../_static/swa/scripting/main_scripting.drawio.png + :scale: 100% + :align: center + + Generic scripting workflow + +A script + +- loads the input files, +- processes that data, e.g. to create statistics and +- writes the data back to the input files if needed using the Dim::Format class. + +Note, that unexpected exceptions can occur anywhere in the code. These exceptions are not caught by +Dim. It's up to the script to do proper error handling. If the script does not catch the exception, +the Ruby interpreter will terminate the script with an exit code != 0. + +Load Files +---------- + +.. figure:: ../../_static/swa/scripting/load_scripting.drawio.png + :scale: 100% + :align: center + + Load files + +This is basically the same as the :ref:`regular loading workflow `. +The main difference is that the `Dim::Loader` instance needs to be created and called by the script. +Here a simplified version of the `regular loading workflow` is shown. + +Write Files +----------- + +.. figure:: ../../_static/swa/scripting/write_scripting.drawio.png + :scale: 100% + :align: center + + Write files + +This is basically the same as the :ref:`regular format workflow `. +The main difference is that the `Dim::Format` instance needs to be created and called by the script. +It's not intended to use other output-formats than `in-place` in a script. This makes the workflow +easier than the `regular format workflow` diff --git a/dim/documentation/source/pages/architecture/usecases.rst b/dim/documentation/source/pages/architecture/usecases.rst new file mode 100644 index 0000000..b4f3da4 --- /dev/null +++ b/dim/documentation/source/pages/architecture/usecases.rst @@ -0,0 +1,137 @@ +.. _use_cases: + +Use Cases +========= + +This page shows how Dim is used from a black box perspective. + +Import from Customer +-------------------- + +Documents with requirements are received from customers, HW vendors etc. in different formats like +Doors. + +- First, the documents are converted to Dim format, ``temporary input files`` are written. +- Then these ``temporary input files`` are read and merged with the already existing + ``input files``. It must be defined, which attributes are owned by the customer and which + are owned by project and under which conditions the the `review_status` has to be reset + (e.g. when the customer changes the `text` attribute). + In case the ``input files`` don't exist yet, the complete data from the ``temporary input files`` + are taken over. +- The result is written back to the ``input files`` which have to be verified. + +.. figure:: ../../_static/swa/usecases/import.drawio.png + :scale: 100% + :align: center + + Import from customer + +.. _use_case_export_to_customer: + +Export to Customer +------------------ + +To provide changed requirements data to the customer, the data in Dim format is exported to CSV, +which is input for a conversion tool. The output of this tool is then sent to the customer. + +.. figure:: ../../_static/swa/usecases/export.drawio.png + :scale: 100% + :align: center + + Export to customer + +.. _use_case_change_requirements: + +Change Requirements +------------------- + +The following diagram shows the workflow when requirements are changed, e.g. customer requirements +are reviewed, software requirements written and improved, references are set, etc. + +.. figure:: ../../_static/swa/usecases/change.drawio.png + :scale: 100% + :align: center + + Change requirements + +Get Tool Information +-------------------- + +The following information can be printed: + +- Dim version +- Command line usage +- License information + +.. figure:: ../../_static/swa/usecases/data.drawio.png + :scale: 100% + :align: center + + Get tool information + +Printing Built-In Statistics +---------------------------- + +To create (project) specific statistics, see use case :ref:`use_case_read_data`. + +To get a quick overview of the input files without the need of writing a Ruby script, Dim can print +generic statistics like total number of requirements. + +.. figure:: ../../_static/swa/usecases/stats.drawio.png + :scale: 100% + :align: center + + Printing built-in statistics + +.. _use_case_read_data: + +Read Data with Ruby API +----------------------- + +With the Ruby API, the requirements data can be read programmatically and further processed, e.g. to +monitor the progression of the requirements engineering activities by some scripts or to create a +traceability overview. + +.. figure:: ../../_static/swa/usecases/reading.drawio.png + :scale: 100% + :align: center + + Read data with Ruby API + +Write Data with Ruby API +------------------------ + +Requirements data is written programmatically with the Ruby API. + +.. figure:: ../../_static/swa/usecases/writing.drawio.png + :scale: 100% + :align: center + + Write data with Ruby API + +.. _use_case_vcs: + +(Version Control System) +------------------------ + +.. note:: + + **Version Control System** is not a use case by it's own, it's an activity which is performed by + the use cases described above. + +A `Version Control System` is a technical quality gate which must be passed before any changes are +merged into the Git repository. For the `input files` two stages are relevant: + +- ``Automatic Checks``: This stage is also known as the "verifier" and checks the consistency and + formatting of the input files. Additionally the data is exported to RST. +- ``Manual Review``: The RST files are used by Sphinx to build a HTML documentation which is very + convenient in a review. + +Only if everything is correct and the changes are approved by the reviewer, the commit is accepted +and merged to the Git repository. + +.. figure:: ../../_static/swa/usecases/verifier.drawio.png + :scale: 100% + :align: center + + Version control system diff --git a/dim/documentation/source/pages/changelog.rst b/dim/documentation/source/pages/changelog.rst new file mode 100644 index 0000000..f1d68f5 --- /dev/null +++ b/dim/documentation/source/pages/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +2.1.0 +----- + +October 23, 2024 + +- Initial public release. diff --git a/dim/documentation/source/pages/cli.rst b/dim/documentation/source/pages/cli.rst new file mode 100644 index 0000000..a830a85 --- /dev/null +++ b/dim/documentation/source/pages/cli.rst @@ -0,0 +1,178 @@ +.. _command_line_interface: + +Command Line Interface +====================== + +General Arguments +----------------- + +- ``--help`` prints the usage with all available arguments +- ``--version`` prints the version +- ``--license`` prints the license + +Subcommands +----------- + +Dim supports different subcommands: + +.. code-block:: text + + dim + +All available subcommands with the additional parameters are described below. + +check ++++++ + +This checks all input files if they are valid, e.g. if the **refs** can be resolved. + +-i FILENAME, \-\-input FILENAME +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``-i`` specifies a :ref:`requirements file ` or +:ref:`config file `. + +Usually requirements are loaded via a config file which specifies the category and the originator +for the requirements. If a requirements file is loaded directly, the category is set to +*unspecified* and the originator to an empty string. + +Example: + +.. code-block:: text + + dim check -i project/reqs/config.dim + +-a FILENAME, \-\-attributes FILENAME +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``-a`` specifies a :ref:`custom attributes file `. + +An attributes files is usually specified in the :ref:`config file `. Loading a +requirements file with custom attributes directly would lead to an error. To avoid that, the +attributes file can also be specified on the command line. + +If the config file has a reference to custom attributes AND an attributes file is specified using +this command line parameter, then attributes from both references are taken into consideration. +If the same attribute is present in both files, the attributes loaded from config file will be +prioritized. + +If a single requirements file without this parameter is loaded, then Dim searches for a file named +*attributes.dim* recursively, starting from location of the requirements file till the root directory +is reached. If such a file is found, then the custom attributes are loaded from that file. + +\-\-allow-missing +~~~~~~~~~~~~~~~~~ + +When loading only a part of the requirements files, references may not be resolvable, which would +lead to an error. To suppress them, use ``--allow-missing``. This is only for developing +purposes. An official export must be done without this parameter. + +While :ref:`formatting `, this parameter is automatically set. + +\-\-no-check-enclosed +~~~~~~~~~~~~~~~~~~~~~ + +When Dim contains enclosed files, it checks for the presence of those files. A missing file leads +to an error. To skip the enclosed files check, use ``--no-check-enclosed``. + +\-\-silent +~~~~~~~~~~ + +When this option is set, Dim will not print any info logs on the screen. Errors and warnings will +still be printed to inform the user what went wrong during the operations. + +.. _subcommand_format: + +format +++++++ + +This subcommand :ref:`formats ` requirements files. Dim sets the `allow-missing` parameter +automatically when formatting the documents, which means Dim will not warn about missing references. + +``format`` implicitly executes the consistency ``check``. All ``check`` parameters can also be used +for ``format``. + +All existing YAML comments are removed during formatting. + +\-\-output-format FORMAT +~~~~~~~~~~~~~~~~~~~~~~~~ + +- ``in-place``: By default, requirements files are changed in-place. +- ``extra``: To create extra files next to the original files (with the ending *.formatted*) use + this output format. +- ``check-only``: Checks the files without changing them. If the formatting is not correct, + Dim exists with an exit code != 0. +- ``stdout``: This is to support the inline formatting in IDEs. Any IDE which works with STDIN and + STDOUT can use this flag to support code formatting within the IDE. + + +More details about `stdout`: + +It is assumed that the requirements file is valid. As binary input is read from STDIN, this output format +skips the check for enclosed files and refs. The formatted output will be sent to STDOUT, from +where the IDE is supposed to read. + +When output format is set to `stdout`, Dim automatically sets the following parameters: + +- `allow-missing` +- `no-check-enclosed` +- `silent` + +Config files are not supported. + +The following example shows how to use this feature with ``Vim``, assuming that the `vim-autoformat` +plugin is already installed: + +- First, add this to the `.vimrc` file: + + .. code-block:: text + + let g:formatdef_dimtool = '"dim format --output-format stdout"' + let g:formatters_dim = ['dimtool'] + +- After the file has been loaded into Vim, format the file like this: + + .. code-block:: text + + :Autoformat dim + +export +++++++ + +Requirements can be exported to different formats. The output can be made available to +other tools or third-parties. + +``export`` implicitly executes the consistency ``check``. All ``check`` parameters can also be used +for ``export``. + +-o FOLDER \-\-output FOLDER +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Specifies the output folder. Every document with its enclosed files will be exported to a subfolder. +If the folders do not exist, they will be created. Existing files will be overwritten. + +-f FORMAT \-\-format FORMAT +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +FORMAT can be *rst*, *csv* and *json*. + +| *csv* can be used for e.g. exporting to other requirements tools. +| *rst* output is input for a Sphinx documentation build which can create HTML pages. + +\-\-filter FILTER +~~~~~~~~~~~~~~~~~ + +The output can be filtered with quite natural conditions, e.g. + +.. code-block:: text + + # filter entries which are requirements and have CAN in the text. + --filter "type == requirement && text =~ /CAN/" + +stats ++++++ + +This prints some nice stats about requirements, per owner/originator, per document, etc. + +``stats`` implicitly executes the consistency ``check``. All ``check`` parameters can also be used +for ``stats``. diff --git a/dim/documentation/source/pages/development.rst b/dim/documentation/source/pages/development.rst new file mode 100644 index 0000000..eed27f8 --- /dev/null +++ b/dim/documentation/source/pages/development.rst @@ -0,0 +1,58 @@ +.. _development: + +Development of Dim +================== + +Continuous Integration +---------------------- + +Dim is developed on GitHub including a **review** and **verification** process. + +- Every commit must be approved. +- The unit test of Dim covers 100% of the code. Whenever the code changes, the verifier ensures + that all tests are passing. In case of a failing test the commit is rejected. + +.. _bug_tracking: + +Bug Tracking and Feature Planning +--------------------------------- + +Bugs and new features are handled with GitHub issues. +In case you have found a bug or if you have feature request, please open a ticket. + +Release +------- + +Merging a change to GitHub does not mean it's automatically available for the users. A new Dim +version must be released explicitly: + + - Increment the version in ``version.txt``. + - Document the changes in ``documentation/source/pages/changelog.rst``. + - Push these changed files to GitHub. + - After successful merge, build the gem: + + .. code-block:: + + gem build dim.gemspec + - Push the gem to RubyGems, e.g.: + + .. code-block:: + + gem push dim-toolkit-1.2.3.gem --host https://rubygems.org/ --key ... + - Push the documentation to https://esrlabs.github.io/dox/dim. + - Add a new release tag. + +Requirements +------------ + +The requirements for Dim are written in Dim itself, exported to Sphinx and available in this +documentation. There is also an overview of the mapping between requirement IDs and test cases with +additional statistics generated. + +.. toctree:: + + requirements/Dim/Requirements + requirements-generated/mapping + reqSources + requirements-generated/stats + reqConfig diff --git a/dim/documentation/source/pages/format.rst b/dim/documentation/source/pages/format.rst new file mode 100644 index 0000000..8b95e25 --- /dev/null +++ b/dim/documentation/source/pages/format.rst @@ -0,0 +1,95 @@ +.. _format: + +Formatting +========== + +Dim is based on `YAML `_, so technically the only hard constraint is that the +Dim files have to follow the YAML standard. Please have a look at the YAML standard, +especially how to write strings over multiple lines, e.g.: + +.. code-block:: yaml + + text: | + The vertical bar preserves line break in this paragraph. + - line 1 + - line 2 + + text: > + The greater-than sign removes + the line + breaks. + + +Additionally, to improve readability and editing the following formatting rules are highly +recommended. +These formatting rules (and some more) can be applied and checked with the subcommand +:ref:`subcommand_format`. + +Indentation +----------- + +- Do not indent ****, **document**, **enclosed**. +- Indent attribute keys like **text** or **tags** by 2 characters. +- Indent **text** value by 28 characters. +- Indent **verification_criteria** value by 32 characters. + +Example: + +.. code-block:: yaml + + document: My module + + SRS_Feature_Heading: h2 My heading + + SRS_Feature_Req1: + text: Some text. + tags: tested + + SRS_Feature_Req2: + text: | + Some multiline text is + added here. + verification_criteria: To verify do something. + tags: availability + + SRS_Feature_Req3: + text: Again another bla bla. + verification_criteria: To verify do some other stuff. + tags: tested + +Arrays +------ + +| Arrays are **intentionally not supported** to keep the syntax easy. +| For all fields with multiple values, Dim reads the string and splits it at ``,``` characters. + +In most cases it's fine to simply write a comma separated string: + +.. code-block:: yaml + + SRS_Feature_Req: + tags: availability, confidentiality + +In some cases like listing a lot of references, it's recommended to use the character ``>``, +which removes the line breaks and the output is a single-line string again: + +.. code-block:: yaml + + SRS_Feature_Req: + refs: > + SRS_AnotherFeature_Req1, + SRS_AnotherFeature_Req2, + SRS_AnotherFeature_Req3, + SWA_Something_Else + +Empty Lines +----------- + +Add one empty line between requirements. + +Encoding +-------- + +To ensure that special characters such as *µ*, *°* or umlauts are correctly displayed, Dim +files need to be encoded in **utf-8**. Other encodings such as ANSI, Windows1250, ISO8859-1 etc. +are possible but some characters may be automatically converted to *?*. diff --git a/dim/documentation/source/pages/installation.rst b/dim/documentation/source/pages/installation.rst new file mode 100644 index 0000000..51a2cd0 --- /dev/null +++ b/dim/documentation/source/pages/installation.rst @@ -0,0 +1,25 @@ +Installation +============ + +Install the Dim gem. The version argument is optional. If not specified, the latest +available version will be installed. + +.. code-block:: text + + gem install dim-toolkit + # or + gem install dim-toolkit -v 1.2.3 + +Verify the installation. The version is needed you have multiple Dim gems installed +and want to execute a specific version. + +.. code-block:: text + + dim --version + # or + dim _1.2.3_ --version + +.. note:: + + Specifying the version with `-v 1.2.3` or `_1.2.3_` is not a Dim feature, it's provided by Ruby + itself. diff --git a/dim/documentation/source/pages/integration.rst b/dim/documentation/source/pages/integration.rst new file mode 100644 index 0000000..7de7f1c --- /dev/null +++ b/dim/documentation/source/pages/integration.rst @@ -0,0 +1,133 @@ +Integration +=========== + +.. _compatibility: + +Compatibility +------------- + +- Dim requires at least Ruby 2.7. It does not use any special third-party library, the standard + installation is enough. +- The officially supported platforms are Windows, Linux and macOS. + +Folder Structure +---------------- + +| Dim can handle almost any folder structure specified through the :ref:`config_files`. +| One of the few constrains is to place the :ref:`requirements_files` not above the config file. + +Use the following structure as a guidance, tailor it depending on the project specific needs: + +.. code-block:: none + + req + input + customerA + lastenheft1 + Requirements.dim + data + image1.png + image2.png + lastenheft2 + Requirements.dim + data + image3.png + image4.png + srs + feature1 + Requirements.dim + data + image5.png + image6.png + feature2 + Requirements.dim + config.dim + +- Choose a root folder for the requirements, here ``req``. +- Add a config file there, like ``config.dim``. +- Create folders for every category, e.g. ``input`` and ``srs``. +- `Input Requirements` may be originated by different customers, so create subfolders for every + customer, for example ``customerA``. +- Create another level of subfolders for the requirements files, e.g. ``lastenheft1`` or + ``feature1``. +- Place the requirements files into these folders. The ending should be ``*.dim``. +- Put any enclosed file to a ``data`` subfolder. + + +File Structure +-------------- + +The file must be compliant to the specified syntax for the :ref:`config_files` and +:ref:`requirements_files`. + +Some general advices: + +- Use headings and subheadings to make especially large documents more readable. +- Avoid more than four heading levels. +- Don't use YAML comments, they will be removed when using the Dim formatter. + +.. _integration_verifier: + +Verifier +-------- + +The **check** command must be added to a project specific verifier which checks the changes before +they are merged into the repository. If the exit code is not 0, the verifier must reject the commit. +The commit must be also rejected if Dim hangs and is terminated due to a timeout, etc. + +This way it's ensured that always syntactically correct and consistent files are merged to the +repository. This also helps to prevent safety and security issues. + +.. _integration_export: + +Export +------ + +When exporting to another format, e.g. + +- to CSV as input for a requirements exchange with the customer or +- to RST as input for a Sphinx build, + +review the exported data or the result of the tool using the exported data for correctness. + +.. _integration_stats: + +Statistics +---------- + +When using the ``stats`` subcommand, review the results for correctness by doing a sanity check. +This shall avoid that wrong or incomplete files are loaded without recognizing it. + +.. _integration_scripting: + +Scripting +--------- + +When using a script to access the Ruby API, perform at least one of the following reviews: + +- Review the script for correctness. +- Review the outcome of the script for correctness. + +Depending on the complexity of the script, unit tests or a complete tool evaluation / qualification +might be necessary. + +Bugs +---- + +Bugs must be tracked on regular basis, see also :ref:`bug_tracking`. Check whether the reported +bugs have an impact on the project and take appropriate actions like updating Dim in that project. + +Version +------- + +It must be ensured that only the correct (qualified) version of this tool is used. + +- Log the version of Dim in the official CI-jobs and +- compare this version with the version specified for the project. + +Training +-------- + +| All users of Dim must read this documentation. +| They have to be trained in the usage of this tool to fully understand all features which are needed + for their work. diff --git a/dim/documentation/source/pages/introduction.rst b/dim/documentation/source/pages/introduction.rst new file mode 100644 index 0000000..48542cb --- /dev/null +++ b/dim/documentation/source/pages/introduction.rst @@ -0,0 +1,83 @@ +Introduction +============ + +Dim is a requirements tool to manually and automatically read, process and write requirements. +It was designed to simplify the work with requirements as much as possible. + +Dim is written in Ruby and runs on :ref:`multiple platforms `. + +Features +-------- + +- The data is represented by YAML files, a human-readable format which can be easily parsed by all + common scripting languages. +- This format allows to read, change and write the files by any editor, whatever the author prefers. + There is no restriction to any IDE. The files can be edited directly on local machines without + having a (slow) VPN connection to a centralized server. +- The changes can be easily reviewed with an existing code review system. +- YAML files can be edited by several authors at the same time and merged as every regular text + file when committing. +- The requirements can be maintained and baselined in the source code repository. +- Dim requires no license. +- The requirements can be structured in different files as well as in sections and subsections + within a single file. Most of the attributes are very natural like the requirements `text`, + `review_status`, `comment`, `refs` and so on. + +Example requirements file: + +.. code-block:: yaml + + SRS_memory_heading: h1 Memory Usage + + SRS_memory_RAM: + text: The ECU shall use a maximum of 80% of the available RAM in the first SOP. + verification_criteria: | + The map-file includes information about the free RAM. + This value must be >= 1 MB. + tags: performance + refs: SWA_memory_layout + + SRS_memory_ROM: + text: The ECU ... + + +Dim is command line tool. The most important :ref:`subcommands ` are: + +- **check**: Checks the YAML files for syntactical correctness and consistency, e.g. whether all + `refs` link to existing requirements. +- **format**: Formats files to have a standardized look and feel of the YAML files. Dim can also + check whether the formatting is correct. +- **export** Exports the data to other formats, currently CSV, JSON and RST. The latter one is the + import for a Sphinx build which generates a nice HTML representation of the requirements including + clickable links etc. + +Instead of providing a proprietary scripting language like DXL, Dim provides a +:ref:`Ruby interface ` to make it very easy to process requirements automatically. +Typical use cases are: + +- Creating project specific statistics, e.g. how many `Input Requirements` are not reviewed yet or + which `Software Requirements` are security relevant. +- Changing a large set of requirements by a script, e.g. adding the development responsible for all + requirements in a specific scope. +- Updating the requirements files with a new version of the customer requirement specification. + +Harmonization +------------- + +The attributes of Dim are predefined to simplify the requirement processes and to ease the reuse of +tools working with requirements. This does not only apply to self-written requirements, but also to +requirements provided by customers. + +Customer requirements are often inconsistent in their attribute usage. They might be +delivered in different formats like ReqIf or PDF. Sometimes only meeting minutes from workshops +exist which much serve as input. Not everything is provided directly by the customer, often +third-party requirements like safety manuals from the HW vendor or ISO specifications must be +handled. + +To avoid that every project member has to deal with these difficulties, the `Requirements Manager` +converts the `Input Requirements` into the Dim format and vice versa. All subsequent tasks are done +with the Dim files. + +.. image:: ../_static/conversion.drawio.png + :scale: 100% + :align: center diff --git a/dim/documentation/source/pages/reqConfig.rst b/dim/documentation/source/pages/reqConfig.rst new file mode 100644 index 0000000..ff171d5 --- /dev/null +++ b/dim/documentation/source/pages/reqConfig.rst @@ -0,0 +1,16 @@ +Configuration +============= + +Settings +-------- + +.. dox_trace_config:: + +Preview +------- + +A tool requirement without any explicit value set: + +.. requirement:: Tool_Config_Preview + :category: software + :tags: tool diff --git a/dim/documentation/source/pages/reqSources.rst b/dim/documentation/source/pages/reqSources.rst new file mode 100644 index 0000000..5885eec --- /dev/null +++ b/dim/documentation/source/pages/reqSources.rst @@ -0,0 +1,4 @@ +Source Code Mapping +=================== + +.. traceability_report:: source diff --git a/dim/documentation/source/pages/syntax.rst b/dim/documentation/source/pages/syntax.rst new file mode 100644 index 0000000..c536de1 --- /dev/null +++ b/dim/documentation/source/pages/syntax.rst @@ -0,0 +1,15 @@ +.. _syntax: + +Syntax +====== + +.. toctree:: + :maxdepth: 2 + + syntax/requirement + syntax/config + syntax/property + syntax/attributes + syntax/html + syntax/issues + syntax/backward diff --git a/dim/documentation/source/pages/syntax/attributes.rst b/dim/documentation/source/pages/syntax/attributes.rst new file mode 100644 index 0000000..ce297c0 --- /dev/null +++ b/dim/documentation/source/pages/syntax/attributes.rst @@ -0,0 +1,67 @@ +.. _attributes_file: + +Attributes File +=============== + +An attributes file is used to define project specific custom attributes which are not part +of standard Dim attributes. +Overwriting existing standard attributes is not allowed. + +Syntax +------ + +.. code-block:: yaml + + attribute: + type: + default: + allowed: + +Custom attributes have three parameters: `type`, `default` and `allowed` + +type +++++ + +`type` defines the way the attributes are formatted and exported to RST. Allowed type values are + +- text - The attribute information will be rendered as a text block in exported files. +- split - Comma separated values, split with newlines when rendered or exported. +- list - Comma separated values, split with spaces when rendered or exported. +- single - Attribute can have a single value from the list of allowed values. +- multi - Attribute can have multiple values from the list of allowed values, rendered like + ``list``. + +If `type` is set to `single` or `multi`, it is mandatory to provide the `allowed` list. + +default ++++++++ + +Specifies the default value for the attributes. +For `single` and `multi` format type, the default value must be included in the list of allowed +values. All custom attributes should have a default value. +If no default value is provided, Dim adds a blank string as a default value. + +Custom attributes must not have `auto` as a default value, Dim will throw an error in that case. + +allowed ++++++++ + +Specifies the list of values a custom attribute can take. +Custom attributes with type `single` and `multi` must provide the allowed list of values. + +Example +------- + +.. code-block:: yaml + + cluster: + type: text + default: '' + color: + type: single + default: 'red' + allowed: + - 'red' + - 'green' + - 'yellow' + - 'blue' diff --git a/dim/documentation/source/pages/syntax/backward.rst b/dim/documentation/source/pages/syntax/backward.rst new file mode 100644 index 0000000..42576ab --- /dev/null +++ b/dim/documentation/source/pages/syntax/backward.rst @@ -0,0 +1,13 @@ +.. _backward_compatibility: + +Backward Compatibility +====================== + +test_setups +----------- + +``test_setups`` is deprecated and replaced by ``verification_methods``. +This deprecation is currently backward compatible. + +Dim will automatically replace ``test_setups`` with +:ref:`verification_methods ` while formatting and exporting files. diff --git a/dim/documentation/source/pages/syntax/config.rst b/dim/documentation/source/pages/syntax/config.rst new file mode 100644 index 0000000..acc9d6c --- /dev/null +++ b/dim/documentation/source/pages/syntax/config.rst @@ -0,0 +1,147 @@ +.. _config_files: + +Config Files +============ + +Dim config files are used + +- to load a set of multiple files, +- to define the originators and categories of the files and +- to specify a properties file which influences the :ref:`asil ` and + :ref:`cal ` values. +- to specify an :ref:`attributes ` file which accepts project specific custom attributes. + +Syntax +------ + +.. code-block:: yaml + + Config: + - originator: + category: + files: + - originator: + category: + files: + - + - + - ... + Properties: File + Attributes: File + + +originator +++++++++++ + +The originator is typically the company name. + +category +++++++++ + +Category must be one of *input*, *system*, *software*, *architecture* and *module*. + +They are interpreted in the following top-down order when calculating *upstreamRefs* and +*downstreamRefs*, see :ref:`data_access`: + +.. list-table:: + :header-rows: 1 + + * - Level + - Category + - Full Name + * - 5 + - input + - Input Requirement + * - 4 + - system + - System Requirement + * - 3 + - software + - Software Requirement + * - 2 + - architecture + - Architecture Specification + * - 1 + - module + - Module / Component Specification + +It's important to understand that the requirements within the *module* category are based on those +in the *architecture* category, which in turn are derived from the *software* category, and so on. +This means that *module* is the lowest in the category hierarchy, while *input* holds a higher +position. + +files ++++++ + +Files can be defined as a string or as an array of strings containing glob patterns with relative +path names. The patterns must not include ``..``. Use forward slashes ``/``, not backslashes ``\``. + +Properties +++++++++++ + +Defines the :ref:`property_files`. + +Attributes +++++++++++ + +Defines the :ref:`attributes_file`. + +Example +------- + +.. code-block:: yaml + + Config: + - originator: Accenture + files: + - "modules/**/*.dim" + - "safety_modules/**/*.dim" + category: module + - originator: CustomerA + files: "input//**/*.dim" + category: input + Properties: "properties.yaml" + Attributes: "attributes.dim" + +Software Requirements +--------------------- + +Whenever `category` in the config file is set to ``software``, Dim checks the following naming +conventions: + +- IDs and the document name must start with ``SRS``. +- IDs must be named ``SRS__``. They must have exactly two underscores. +- Document must be named ``SRS_``. It must have exactly one underscore. +- ** and ** must only contain alphanumeric characters and hyphens (-). + +In case of violation, Dim will report an error exit the process. + +For legacy software requirements, you can disable this check by setting the option +``disable_naming_convention_check`` to `yes` for the respective originator in +the config file. Default for ``disable_naming_convention_check`` is `no`. + +Example: + +.. code-block:: yaml + + Config: + - originator: Accenture + files: + - sample_module.dim + - testing_module.dim + disable_naming_convention_check: yes # Dim will skip the SRS naming convention checks for all files from this originator + category: software + - originator: Customer + files: # Dim will check for SRS naming conventions + - software_sample.dim + - hardware_sample.dim + category: software + +Example requirements file with valid document name and ID: + +.. code-block:: yaml + + document: SRS_display + + SRS_display_refresh-rate: + text: Refresh rate shall be 90 Hz. diff --git a/dim/documentation/source/pages/syntax/html.rst b/dim/documentation/source/pages/syntax/html.rst new file mode 100644 index 0000000..b18df5d --- /dev/null +++ b/dim/documentation/source/pages/syntax/html.rst @@ -0,0 +1,48 @@ +.. _html_support: + +HTML Support +============ + +Dim is based on YAML, which initially means that requirements are described textually. When +exporting to RST, Dim interprets text between ```` and ```` as HTML. + +External files (e.g. referenced in ````) need to be added to the *enclosed* attribute +so that they are exported/copied correctly. + +The following sections show some examples how to specify HTML elements. + +Text Formatting +--------------- + +.. code-block:: yaml + + SRS_Feature_A1: + text: Bold and italic text with an extra
newline. + +Images +------ + +.. code-block:: yaml + + enclosed: + - images/overview.png + + SRS_Feature_A2: + text: Look at this:
+ +Tables +------ + +.. code-block:: yaml + + SRS_Feature_A3: + text: + + + + + + + + +
VoltageAmp
12 V100 mA
diff --git a/dim/documentation/source/pages/syntax/issues.rst b/dim/documentation/source/pages/syntax/issues.rst new file mode 100644 index 0000000..886ced3 --- /dev/null +++ b/dim/documentation/source/pages/syntax/issues.rst @@ -0,0 +1,29 @@ +.. _common_warnings: + +Common Issues +============= + +Parsing YAML +------------ + +| In some situations, the Ruby YAML parser does not print the correct line and column numbers. +| Example: + +.. code-block:: yaml + + ID_ABC_xy: + text: ... + status: valid + tags: memory + asil: ASIL_B + +A space before *tags* is missing, but the following error message is printed: + +.. code-block:: none + + ... did not find expected key while parsing a block mapping at line 1 column 1 + +This error message usually means you have too much or too less spaces *somewhere* in +the YAML file. + +This is a known issue, see https://github.com/ruby/psych/issues/190. diff --git a/dim/documentation/source/pages/syntax/property.rst b/dim/documentation/source/pages/syntax/property.rst new file mode 100644 index 0000000..8bb10b4 --- /dev/null +++ b/dim/documentation/source/pages/syntax/property.rst @@ -0,0 +1,114 @@ +.. _property_files: + +Properties File +=============== + +A properties file is a YAML file that consists of key-value pairs. Dim uses the properties file for +**replacing attributes in requirements which are not explicitly set**. +The properties are specified on document level. + +Any unknown attributes in the properties file are ignored. + +Syntax +------ + +.. code-block:: yaml + + : + : value 1 + : value 2 + : value n + + # can be also written like this: + + : { : value 1, : value 2, : value n } + +Example +------- + +.. code-block:: yaml + + # properties.yaml + SRS_featureX: + asil: ASIL_A + text: | + Multi-line + example text. + other_key: other value + + SRS_featureY: + verification_methods: on_target + asil: ASIL_C + +.. code-block:: yaml + + # config.dim + Config: + - originator: MyCompany + files: + - featureX.dim + - featureY.dim + category: software + + Properties: properties.yaml + +.. code-block:: yaml + + # featureX.dim + document: SRS_featureX + + SRS_featureX_0001: + text: text example + + SRS_featureX_0002: + asil: not_set + +.. code-block:: yaml + + # featureY.dim + document: SRS_featureY + + SRS_featureY_0001: + asil: ASIL_A + + SRS_featureY_0002: + +The following changes will be applied: + +- ``asil`` value for requirement ID **SRS_featureX_0001** will be replaced with + ``ASIL_A``, because requirements file is missing a value for asil attribute. +- ``asil`` value for requirement ID **SRS_featureX_0002** will not be replaced with + ``ASIL_A``, because value **not_set** is explicitly set for asil attribute +- ``verification_methods`` attribute will be replaced with ``on_target`` for requirement + ID **SRS_featureY_0001** as ``verification_methods`` is missing. +- Requirement with ID **SRS_featureY_0002** will have ``asil`` value ``ASIL_C``, + as value for attribute ``asil`` was empty, and ``verification_methods`` will be replaced + with ``on_target``. +- ``other_key`` will be ignored without raising an error. + +Internally in Dim, the requirements are treated as if they were written that way: + +.. code-block:: yaml + + # featureX.dim + document: SRS_featureX + + SRS_featureX_0001: + text: text example + asil: ASIL_A + + SRS_featureX_0002: + asil: not_set + +.. code-block:: yaml + + # featureY.dim + document: SRS_featureY + + SRS_featureY_0001: + asil: ASIL_A + verification_methods: on_target + + SRS_featureY_0002: + asil: ASIL_C + verification_methods: on_target diff --git a/dim/documentation/source/pages/syntax/requirement.rst b/dim/documentation/source/pages/syntax/requirement.rst new file mode 100644 index 0000000..a2abafd --- /dev/null +++ b/dim/documentation/source/pages/syntax/requirement.rst @@ -0,0 +1,428 @@ +.. _requirements_files: + +Requirements Files +================== + +Overview +-------- + +The Dim requirements files are written in YAML format, so they can be processed by every YAML parser. +Dim prints warning message and skips loading of requirements file, if the requirements file is +empty. + +Dim expects the following syntax: + +.. code-block:: yaml + + document: # required, string describing the group or domain of requirements + + metadata: # optional string to describe origin, date, version, history, etc. + + enclosed: # optional, all those files will be copied when exporting + - + - + - <...> + + : # must be unique + - text: # any string, default: "" + - verification_criteria: # any string, default: "" + - feature: # any string, default: "" + - change_request: # any string, default: "" + - type: # one of: requirement (default), information, heading_0, ... heading_100 + - status: # one of: draft, valid, invalid + # default: see below + - tags: # any string, comma separated, default: "", + - developer: # any string, default: "" + - tester: # any string, default: "" + - verification_methods: # one or more of : none, off_target, on_target, manual + # default: see below + - asil: # one of: not_set (default), QM, QM(A), QM(B), QM(C), QM(D), + # ASIL_A, ASIL_A(A), ASIL_A(B), ASIL_A(C), ASIL_A(D), + # ASIL_B, ASIL_B(B), ASIL_B(C), ASIL_B(D), + # ASIL_C, ASIL_C(C), ASIL_C(D), + # ASIL_D, ASIL_D(D) + - cal: # one of: not_set (default), QM, CAL_1, CAL_2, CAL_3, CAL_4 + - review_status: # one of: accepted, unclear, rejected, not_reviewed, not_relevant + # default: see below + - comment: # any string, default: "" + - miscellaneous: # any string, default: "" + - sources: # any string, default: "" + - refs: # any string, default: "" + +Attributes +---------- + +.. _document: + +document +++++++++ + +The **document** name is mandatory and the first hierarchy level for the requirements. + +It is valid to specify the same **document** name in different files. +The requirements will be merged into one chapter. + +metadata +++++++++ + +| An optional string to describe the origin of the document, date, version, history, etc. +| If input requirements are converted from a customer format to Dim, the metadata can be added here. + +Example: + +.. code-block:: none + + metadata: | + Lastenheft ABC 1.2 + Exported from xy/db/projectX/ABC on Jan 1, 2000 + +enclosed +++++++++ + +An optional array to specify all files, which shall be copied when the requirements are exported. +Usually the files are referred in the text section of the requirement with HTML tags: + +.. code-block:: yaml + + + +The files must be specified with relative paths. They must not include ``..``. +Use forward slashes ``/``, not backslashes ``\``. + +Example: + +.. code-block:: yaml + + enclosed: + - images/overview.png # ok + - ../somewhere/else/main.png # not ok, Dim will report an error + +.. _id: + + +++++ + +Every requirement must have a unique ID. + +type +++++ + +Allowed values are ``requirement`` (default), ``information``, ``heading``, ``heading_0``, ..., +``heading_100``. + +text +++++ + +This is the requirements **text**. Use regular YAML syntax, e.g. for preserving line breaks: + +.. code-block:: yaml + + SRS_Feature_Aspect1: + text: | + This is a multiline requirement + with preserved line breaks. + +HTML tags are allowed, but they must be surrounded with ...: + +.. code-block:: yaml + + SRS_Feature_Aspect2: + text: | + Now a HTML table follows: + + + + + + + + + + + + + + + + + +
FirstnameLastnameAge
JohnSmith40
JaneDoe30
+ + Now a picture: + + +verification_criteria ++++++++++++++++++++++ + +Can be empty. Describes what is needed to pass a test. + +If you have multiple :ref:`verification_methods` defined, list what you expect from which method: + +.. code-block:: yaml + + SRS_Abc_Def: + verification_criteria: | + off_target: ... + on_target: ... + verification_methods: off_target, on_target + +feature ++++++++ + +| Can be empty. Describes to what feature the requirement belongs. +| It can be a feature name, ticket ID or any other project specific string. + +change_request +++++++++++++++ + +Can be empty. Describes which change requests are associated with this requirement. + +status +++++++ + +Allowed values are ``draft``, ``valid``, ``invalid``. + +Default: + +- ``draft`` if **type** is *requirement* or *information* +- ``valid`` if **type** is a heading + +tags +++++ + +Tags are used to specify attributes of the *current* requirement, similar to hashtags on +`X `_. + +Some suggested tags: + +- **covered**: the requirement is fully derived, the references are complete +- **tested**: the requirement is fully tested, no aspect is missing +- **cybersecurity_control**: countermeasure to detect, prevent, reduce, or counteract security risks +- **functional_safety_mechanism**: detect and correct the malfunctions according ISO-26262 +- **confidentiality**, **integrity**, **availability**, **authenticity**, **authority**: a specific + aspects of security +- **legal**: the requirement covers legal interests (compliance) +- **performance**, **memory**: resource restrictions, response and cycle times, + these requirements are good candidates for stress testing +- **structural**: the requirement specifies how to set up the files, modules and workspace +- **configuration**, **calibration**: requirements which focus on setting up the software +- **established**: proven-in-use feature (may lower the priority for e.g. testing) +- **sys**: used as input for system requirements, this means the input requirement defines system + behavior and shall link directly to the derived system requirements (only for input requirements) +- **srs**: used as input for software requirements, this means the input requirement is on a black + box level and shall link to derived software requirements (only for input requirements) +- **swa**: used as input for software architectural specifications, this means the input requirement + defines specific aspects of the software architecture and shall link directly to the derived + software architecture specifications (only for input requirements) +- **smd**: used as input for software module designs, this means the input requirement already + defines specific characteristics of a software module design and shall link directly to the + derived software module designs (only for input requirements) +- **process**, **test**: used as input for (test) processes, this means the input requirement + defines a development/project process rather than system/software behavior and shall link directly + to a (test) process document (only for input requirements) +- **obd**: this means the input requirement has an impact on the onboard diagnosis of the car +- **emission_doc**: the requirement impacts the emission strategy of the car +- **emission_tailpipe**: the requirement has an impact on either the range, consumption, or the + emission of the car +- **emission_performance**: the requirement has an impact on the cars performance values which are + specified in the homologation of the car +- **unit**, **interface**: unit specification or architectural interface +- **tool**: the requirement does not specify target software but a tool +- **non_functional**: marks a non-functional requirement + +developer ++++++++++ + +Used to assign the development responsible. It can be any string. + +Default: + +- ``""`` if **type** is not *requirement* OR **category** is *input* OR a single file is loaded + without config. +- ```` from the config file otherwise. + +tester +++++++ + +Used to assign the testing responsible. It can be any string. + +Default: + +- ``""`` if **type** is not *requirement* OR **category** is *input* OR a single file is loaded + without config OR *process* is in **tags**. +- ```` from the config file otherwise. + +.. _verification_methods: + +verification_methods +++++++++++++++++++++ + +| The verification methods can be: ``none``, ``off_target``, ``on_target``, ``manual``. +| Multiple values are allowed, comma separated. + +- ``off_target`` is used if a requirement is tested without target hardware on a PC, written in e.g. + rspec, gtest, etc. +- ``on_target`` is used if a requirement is tested on the target hardware +- ``manual`` is used if a requirement is tested with a manual tests e.g. code review etc. +- ``none`` is used if a requirement can/shall not be tested directly. + +Default: + +- ``none`` if **type** is not *requirement* OR **category** is *input* OR a single file is loaded + without config OR *process* is in **tags**. +- ``off_target`` if **category** is *module* or **tags** include *tool*. +- ``on_target`` otherwise. + +.. _asil: + +asil +++++ + +| The **asil** level. Possible values see above. +| Default is ``not_set``. + +.. _cal: + +cal ++++ + +| Specifies the *Cybersecurity Assistance Level*, can be ``QM``, ``CAL_1``, ``CAL_2``, ``CAL_3``, + ``CAL_4`` and ``not_set``. +| Default is ``not_set``. + +review_status ++++++++++++++ + +Can be ``accepted``, ``unclear``, ``rejected``, ``not_reviewed``, ``not_relevant``. + +Default: + +- ``not_reviewed`` if **category** is *input* OR a single file is loaded without config. +- ``accepted`` otherwise. It is assumed that files are reviewed in a source control system. + +comment ++++++++ + +Add comments here inclusive name of the commenter and the date. + +miscellaneous ++++++++++++++ + +Can be used to store project specific information. Usually left empty. + +sources ++++++++ + +A comma separated list of source code files. No check for existence. + +refs +++++ + +A comma separated list of all references to other *requirements*. All these references must exist! + +A requirement can refer to other requirements from different categories, e.g. a requirement +in `software` category can refer to requirements from `input` or `module` category. +When references occur within the same category, they are understood as flowing from the broader +or more general level (the parent) to the more specific or detailed ones (the derived child). +This means that within a given category, any references are typically understood in terms of how the +overarching requirements relate to the more specialized ones within that same category. + +Considering the following requirements from different categories and references shown in the +sample config: + +.. code-block:: yaml + + # category system + + SYS_Requirement_1: + refs: SRS_Requirement_1 + + ------------------ + + # category software + + SRS_Requirement_1: + refs: SWA_Architecture_1 + + SRS_Requirement_2: + refs: SRS_Requirement_1 + + ------------------ + + # category architecture + + SWA_Architecture_1: + refs: SYS_Requirement_1, SRS_Requirement_2 + +It looks like there is a cycle in above example, but + +.. code-block:: none + + SRS_Requirement_1 -> SWA_Architecture_1 -> SRS_Requirement_1 -> SRS_Requirement_1 + +is not considered a circular dependency, because + +.. code-block:: none + + SWA_Architecture_1 -> SRS_Requirement_2 + +is an upstream reference. Circular dependency can only occur at same category level. + +.. note:: + + Following *refs* in a Ruby script might end up in an endless loop, it is recommended + to follow *upstreamRefs* or *downstreamRefs*, see :ref:`data_access`. + +Other Languages +--------------- + +The attributes ``text``, ``verification_criteria`` and ``comment`` can be added in other languages +with the following syntax: + +.. code-block:: yaml + + _: ... + +For example: + +.. code-block:: yaml + + SRS_Feature_Aspect: + text: This is a requirement. + text_german: Das ist eine Anforderung. + comment: This is a comment. + comment_german: Das ist ein Kommentar. + comment_french: C'est un commentaire. + +Once used, a language attribute is valid for all requirements. When using the export feature +or the Ruby API the value will be an empty string if not specified otherwise. + +Short Forms +----------- + +Short forms are possible for *headings* and *information*. Instead of defining the **type** +*heading_0* to *heading_100* and *information*, the strings *h0* to *h100* and *info* can be +prepended to the **text**. + +Example: + +.. code-block:: yaml + + Module_Abc_Xy1: + text: Long form + type: heading_1 + + Module_Abc_Xy2: + text: h1 Shorter form + +Usually headings and information have no additional attributes. In this case, they can be written +even shorter: + +.. code-block:: yaml + + Module_Abc_Xy3: h1 Even shorter + + Module_Abc_Xy4: info Multi-line information + is demonstrated here. + +The whitespaces before and after the type are ignored in both short forms. diff --git a/dim/documentation/source/pages/version_handling.rst b/dim/documentation/source/pages/version_handling.rst new file mode 100644 index 0000000..7740d81 --- /dev/null +++ b/dim/documentation/source/pages/version_handling.rst @@ -0,0 +1,52 @@ +.. _version_handling: + +Version Handling +================ + +This page describes two ways how multiple versions of requirements can be managed: + +1. Postfixing requirement IDs with the version. +2. Separating requirements based on version. + + +Postfixing Requirement IDs +-------------------------- + +A version number can be appended to any requirement ID. +For example, the requirement ID ``SRS_Req_Abc`` for version 1 could be represented as +``SRS_Req_Abc-v1``. This approach ensures that each version of a requirement is uniquely +identifiable. + +When the requirement changes, a new version can be created in same requirements file, adjacent to +the original requirement, e.g. ``SRS_Req_Abc-v2``. + +.. code-block:: text + + SRS_Req_Abc-v1: + text: All software modules shall implement the security features. + + SRS_Req_Abc-v2: + text: All software modules shall implement the security features + along with the safety measures. + +If there is no change in a requirement, then creating new version for requirement can be skipped. + +A single requirements file contains all versions of the requirement and can be used for reviews +and other workflows. + +To export a specific version of the requirements to a different location, a filter script can be +applied. This script can select only the desired version of each requirement, remove the version +postfixes, and export the filtered requirements. + +Separating Requirements In Different Files +------------------------------------------ + +Whenever a requirement changes, a new requirements file can be created with the version specified in +the filename. + +E.g., if requirements in ``featureX.dim`` need to be changed, the file is copied to +``featureX_v2.dim`` and the changes are made in the new file. + +This method will result in duplicate requirements across multiple requirements files. +To manage these duplicates, all files can be loaded in a script, a filter applied and finally only +specific versions of the requirements are selected. diff --git a/dim/examples/scripting/excelImport/excel_export.csv b/dim/examples/scripting/excelImport/excel_export.csv new file mode 100644 index 0000000..8a45c11 --- /dev/null +++ b/dim/examples/scripting/excelImport/excel_export.csv @@ -0,0 +1,22 @@ +SSR ID;TSR Link;Object Type;Text;Topic;Comments Person1;Comments Person2;Comments Person3;Status +SR_1;;Heading;Generic SSRs;;;;; +SSR_1;;Information;"This document presents the Software Safety Requirements (SSR) defined per ISO26262 part 6 Functional Safety standard.";Generic SSRs;;Fine for me;; +SSR_2;;Information;"Abbreviations: +SSR - Safety Software Requirements +TSC - +TSR - Technical Safety Requirements";Generic SSRs;;Fine for me;;Approved +SSR_3;;Information;"The Software Safety Requirements are defined for an ECU. + +The Functional Safety requirements and the Safety Goals are provided by Customer.";Generic SSRs;;Fine for me;;Approved +SSR_4;TSR_1;Requirement;"The relevant functional blocks for this safety function are the following: +- FB1 +- FB2 +- FB3 +- FB4 +- FB5 +- FB6 +";Generic SSRs;Ready for review;Fine for me;;Approved +SSR_5;"TSR_2, TSR_3";Requirement;"The following functions will not be used in the safety context: +- FB7 +- FB8 +";Generic SSRs;Ready for review;Fine for me;;Approved diff --git a/dim/examples/scripting/excelImport/import.rb b/dim/examples/scripting/excelImport/import.rb new file mode 100644 index 0000000..cbfa296 --- /dev/null +++ b/dim/examples/scripting/excelImport/import.rb @@ -0,0 +1,65 @@ +require_relative '../../../lib/dim/loader' +require '../../../lib/dim/requirement' +require '../../../lib/dim/commands/format' +require 'csv' + +import_file_name = 'excel_export.csv' +export_file_name = 'SSR.dim' +module_name = 'CCP SSR' + +mapping = { + id: 'SSR ID', + type: 'Object Type', + text: 'Text', + feature: 'Topic' +} + +comments = ['Comments Person1', 'Comments Person2', 'Comments Person3'] + +file = File.read(import_file_name, encoding: 'bom|utf-8').encode(universal_newline: true) +table = CSV.parse(file, headers: true, col_sep: ';') + +loader = Dim::Loader.new +loader.original_data[export_file_name] = {} +loader.original_data[export_file_name]['document'] = module_name + +table.each do |row| + data = { 'asil': 'ASIL_B' } + + if row['Object Type'] == 'Requirement' + if row['Status']&.strip == 'Approved' + data['status'] = 'valid' + data['review_status'] = 'accepted' + else + data['status'] = 'draft' + data['review_status'] = 'not_reviewed' + end + end + + data['comment'] = '' + comments.each do |comment| + next if row[comment].nil? || row[comment].empty? + + person = comment.sub('Comments ', '') + data['comment'] = "#{data['comment']}#{person}: #{row[comment]}\n" + end + + if row['Object Type'] == 'Heading' + number = row['SSR ID'].scan(/[0-9]/).size + row['Object Type'] = "#{row['Object Type']}_#{number}" + end + + mapping.each do |key, value| + next if key == :id + next if row[value].nil? + + key == :type && row[value] && row[value].downcase! + data[key.to_s] = row[value] + end + + loader.original_data[export_file_name][row[mapping[:id]]] = data +end + +formatter = Dim::Format.new(loader) + +formatter.execute diff --git a/dim/examples/scripting/generationStatus/status.rb b/dim/examples/scripting/generationStatus/status.rb new file mode 100644 index 0000000..79a4fa5 --- /dev/null +++ b/dim/examples/scripting/generationStatus/status.rb @@ -0,0 +1,20 @@ +require 'dim/loader' + +l = Dim::Loader.new +l.load(input_filenames: "#{File.dirname(__FILE__)}/test/config.dim") + +mods = l.requirements.values.map(&:document).uniq +reqs = l.requirements.values.select do |r| + r.review_status != 'rejected' && r.type == 'requirement' +end + +puts "Number of requirements: #{reqs.length}" + +puts "\nNumber requirements with (developer == CompanyName) and (outgoing references and/or verification_methods) per module:" +reqs_company = reqs.select { |r| r.developer.include?('CompanyName') } +mods.each do |m| + reqs_company_module = reqs_company.select { |r| r.document == m } + reqs_matching = reqs_company_module.select { |r| r.verification_methods != ['none'] } + puts "#{m}: #{reqs_matching.length} of #{reqs_company_module.length}" + puts reqs_matching.map { |r| "- #{r.id}" } +end diff --git a/dim/examples/scripting/generationStatus/test/CRS_SafeRTE.dim b/dim/examples/scripting/generationStatus/test/CRS_SafeRTE.dim new file mode 100644 index 0000000..69bb0cc --- /dev/null +++ b/dim/examples/scripting/generationStatus/test/CRS_SafeRTE.dim @@ -0,0 +1,27 @@ +document: LH_SafeRTE + +Customer_0: info This information is useless. + +Customer_1: + text: Implement SafeRTE. + review_status: rejected + +Customer_2: + text: Implement tests for SafeRTE + refs: > + SRS_SafeRTE_0005, + SRS_SafeRTE_0733 + +CollectRefs: + text: Collect all refs and calculate implementation status. + refs: > + CollectRefsSub1, + CollectRefsSub2 + +CollectRefsSub1: + text: Sub1 + tags: covered + +CollectRefsSub2: + text: Sub2 + tags: covered diff --git a/dim/examples/scripting/generationStatus/test/SRS_General.dim b/dim/examples/scripting/generationStatus/test/SRS_General.dim new file mode 100644 index 0000000..5e77528 --- /dev/null +++ b/dim/examples/scripting/generationStatus/test/SRS_General.dim @@ -0,0 +1,8 @@ +document: SRS_General + +SRS_General_1111: + text: The Architecture shall be very good. + +SRS_General_1112: + text: SafeRTE shall be also very good. + refs: SRS_SafeRTE_0005 diff --git a/dim/examples/scripting/generationStatus/test/SRS_SafeRTE.dim b/dim/examples/scripting/generationStatus/test/SRS_SafeRTE.dim new file mode 100644 index 0000000..c03eb9a --- /dev/null +++ b/dim/examples/scripting/generationStatus/test/SRS_SafeRTE.dim @@ -0,0 +1,70 @@ +document: SRS_SafeRTE + +SRS_SafeRTE_0017: h1 General + +SRS_SafeRTE_0000: + text: | + The SafeRTE shall work. + Really. + tags: confidentiality, configuration + developer: CompanyName + tester: other + refs: > + SRS_SafeRTE_0005, + SRS_SafeRTE_0001 + +SRS_SafeRTE_0018: h1 Details + +SRS_SafeRTE_0019: h2 Init + +SRS_SafeRTE_0001: + text: | + You have to follow: + + And that's
it! + + + + + + + + + + + + + + + + + +
FirstnameLastnameAge
JohnSmith40
JaneDoe30
+ + refs: SRS_SafeRTE_0005 + +SRS_SafeRTE_0005: + text: All assembly connections shall be uni-directional. + verification_criteria: Take A and check B and see C. + tags: covered + verification_methods: none + review_status: accepted + comment: I like this requirement, can be implemented. + +SRS_SafeRTE_0020: h3 Run + +SRS_SafeRTE_0021: h3 Away + +SRS_SafeRTE_0733: + text: The ECU shall not run away. + verification_criteria: + tags: + asil: ASIL_D + developer: CompanyName + tester: CompanyName + verification_methods: off_target + status: valid + review_status: not_reviewed + refs: + +enclosed: images/*.jpeg diff --git a/dim/examples/scripting/generationStatus/test/config.dim b/dim/examples/scripting/generationStatus/test/config.dim new file mode 100644 index 0000000..3a9638e --- /dev/null +++ b/dim/examples/scripting/generationStatus/test/config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: CRS_* + category: input + - originator: CompanyName + files: SRS_* + category: software diff --git a/dim/examples/scripting/generationStatus/test/images/test.jpeg b/dim/examples/scripting/generationStatus/test/images/test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/examples/scripting/reimport/merge.rb b/dim/examples/scripting/reimport/merge.rb new file mode 100644 index 0000000..9404bfe --- /dev/null +++ b/dim/examples/scripting/reimport/merge.rb @@ -0,0 +1,43 @@ +$stdout.sync = true + +require 'dim/loader' +require 'dim/commands/format' + +# optional for testing, in real script the following line should be deleted +OPTIONS[:output_format] = 'extra' + +puts 'Loading old...' +old_loader = Dim::Loader.new +old_loader.load(input_filenames: "#{File.dirname(__FILE__)}/old/config.dim", allow_missing: true) + +puts 'Loading new...' +new_loader = Dim::Loader.new +new_loader.load(input_filenames: "#{File.dirname(__FILE__)}/new/config.dim", allow_missing: true) + +if new_loader.requirements.any? { |_id, r| r.category != 'input' } + puts 'Error: requirements with category != "input" loaded' + exit(-1) +end + +owned_by_us = %w[feature tags review_status comment] + +new_loader.requirements.each do |id, r| + next unless old_loader.requirements.key?(id) + + new_req = new_loader.original_data[r.filename] + old_req = old_loader.original_data[old_loader.requirements[id].filename] + + owned_by_us.each do |elem| + if old_req[id][elem] == '' # in original_data this means element was not specified + new_req[id].delete(elem) + else + new_req[id][elem] = old_req[id][elem] + end + end + + # reset review_status if relevant customer field has been updated + new_req[id]['review_status'] = 'auto' if %w[text asil].any? { |elem| old_req[id][elem] != new_req[id][elem] } +end + +formatter = Dim::Format.new(new_loader) +formatter.execute diff --git a/dim/examples/scripting/reimport/new/config.dim b/dim/examples/scripting/reimport/new/config.dim new file mode 100644 index 0000000..d465e00 --- /dev/null +++ b/dim/examples/scripting/reimport/new/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: crs*.dim + category: input diff --git a/dim/examples/scripting/reimport/new/crs1.dim b/dim/examples/scripting/reimport/new/crs1.dim new file mode 100644 index 0000000..485b621 --- /dev/null +++ b/dim/examples/scripting/reimport/new/crs1.dim @@ -0,0 +1,21 @@ +module: CRS1 + +CRS1_0: h1 Changed heading + +CRS1_1: + text: Changed text, review_status must be removed. + tags: srs + review_status: accepted + refs: SRS1_1 + +CRS1_2: + text: review_status must be "accepted". + tags: srs + review_status: accepted + +CRS1_3: + text: review_status must not be added. + tags: srs + +CRS1_5: + text: This requirement is new. diff --git a/dim/examples/scripting/reimport/new/crs2.dim b/dim/examples/scripting/reimport/new/crs2.dim new file mode 100644 index 0000000..53f57fd --- /dev/null +++ b/dim/examples/scripting/reimport/new/crs2.dim @@ -0,0 +1,4 @@ +module: CRS2 + +CRS2_1: + text: Only this text, nothing else changes. diff --git a/dim/examples/scripting/reimport/old/config.dim b/dim/examples/scripting/reimport/old/config.dim new file mode 100644 index 0000000..d465e00 --- /dev/null +++ b/dim/examples/scripting/reimport/old/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: crs*.dim + category: input diff --git a/dim/examples/scripting/reimport/old/crs1.dim b/dim/examples/scripting/reimport/old/crs1.dim new file mode 100644 index 0000000..f60bfc5 --- /dev/null +++ b/dim/examples/scripting/reimport/old/crs1.dim @@ -0,0 +1,21 @@ +module: CRS1 + +CRS1_0: h1 If you see this, merge script is broken + +CRS1_1: + text: If you see this, merge script is broken. + tags: srs + review_status: accepted + refs: SRS1_1 + +CRS1_2: + text: review_status must be "accepted". + tags: srs + review_status: accepted + +CRS1_3: + text: review_status must not be added. + tags: srs + +CRS1_4: + text: If you see this, merge script is broken. diff --git a/dim/examples/scripting/reimport/old/crs3.dim b/dim/examples/scripting/reimport/old/crs3.dim new file mode 100644 index 0000000..c426817 --- /dev/null +++ b/dim/examples/scripting/reimport/old/crs3.dim @@ -0,0 +1,3 @@ +module: CRS3 + +CRS3_0: h1 If you see this, merge script is broken diff --git a/dim/lib/dim.rb b/dim/lib/dim.rb new file mode 100644 index 0000000..c0cc02f --- /dev/null +++ b/dim/lib/dim.rb @@ -0,0 +1 @@ +require 'dim/dimmain' diff --git a/dim/lib/dim/commands/check.rb b/dim/lib/dim/commands/check.rb new file mode 100644 index 0000000..f954e58 --- /dev/null +++ b/dim/lib/dim/commands/check.rb @@ -0,0 +1,13 @@ +require_relative '../globals' + +module Dim + class Check + SUBCOMMANDS['check'] = self + + def initialize(_loader); end + + def execute(silent: true) + # checks are always done after loading, so this is just a placeholder for command line option + end + end +end diff --git a/dim/lib/dim/commands/export.rb b/dim/lib/dim/commands/export.rb new file mode 100644 index 0000000..c747d18 --- /dev/null +++ b/dim/lib/dim/commands/export.rb @@ -0,0 +1,145 @@ +require 'pathname' +require 'digest' + +require_relative '../globals' +require_relative '../exporter/exporterInterface' +require_relative '../exporter/rst' +require_relative '../exporter/csv' +require_relative '../exporter/json' +require_relative 'check' + +module Dim + class Export + SUBCOMMANDS['export'] = self + + attr_accessor :file_list, :export_dir + + def initialize(loader) + @loader = loader + @file_list = [] + @export_dir = nil + end + + def execute(silent: true) + @silent = silent + @loader.filter(OPTIONS[:filter]) unless OPTIONS[:filter].empty? + + puts 'Exporting...' unless @silent + export + clean_destination + puts 'Done.' unless @silent + end + + def copy_files(mod) + @loader.module_data[mod][:files].each do |f, list| + d = File.dirname(f) + + list.uniq.each do |l| + src_pattern = File.join(d, l) + Dir.glob(src_pattern).each do |src| + src = Pathname.new(src).cleanpath.to_s + dst = File.join(OPTIONS[:folder], mod.sanitize, Pathname.new(src).relative_path_from(Pathname(d))) + @file_list << dst + FileUtils.mkdir_p(File.dirname(dst)) + + if File.exist?(dst) + md5_src = Digest::MD5.file(src) + md5_dst = Digest::MD5.file(dst) + next if md5_src == md5_dst + end + + puts "Copying #{src} to #{dst}..." unless @silent + FileUtils.cp_r(src, dst) + end + end + end + end + + def write_content(filename, content) + old_content = (File.exist?(filename) ? File.read(filename) : nil) + if content != old_content + File.write(filename, content) + puts ' done' unless @silent + else + puts ' skipped' unless @silent + end + end + + def create_index(requirements_by_module) + return unless @exporter.hasIndex + + files = {} + @loader.module_data.each do |mod, data| + next if requirements_by_module[mod].empty? + + c = data[:category] + o = data[:origin] + files[c] ||= {} + files[c][o] ||= [] + files[c][o] << mod + end + ind = 0 + files.each do |category, data| + data.each do |origin, modules| + ind += 1 + filename = "index_#{format('%03d', ind)}_#{category.downcase}_#{origin.downcase.sanitize}" + filepath = "#{OPTIONS[:folder]}/#{filename}.#{OPTIONS[:type]}" + file_list << filepath + new_content = StringIO.new + print "Creating #{filepath}..." unless @silent + @exporter.index(new_content, category, origin, modules) + write_content(filepath, new_content.string) + end + end + end + + def export + requirements_by_module = {} + module_keys = @loader.module_data.keys + module_keys.each { |um| requirements_by_module[um] = [] } + @loader.requirements.each { |_id, r| requirements_by_module[r.document] << r } + + @exporter = EXPORTER[OPTIONS[:type]].new(@loader) + requirements_by_module.each do |doc, reqs| + next if reqs.empty? + + @export_dir = File.join(OPTIONS[:folder]) + filename = File.join(export_dir, doc.sanitize, "Requirements.#{OPTIONS[:type]}") + file_list << filename + FileUtils.mkdir_p(File.dirname(filename)) + copy_files(doc) + + new_content = StringIO.new + print "Creating #{filename}..." unless @silent + @exporter.header(new_content) + @exporter.document(new_content, doc) + meta = @loader.metadata[doc] + @exporter.metadata(new_content, meta) if meta != '' + reqs.each do |r| + @exporter.requirement(new_content, r) + end + @exporter.footer(new_content) + write_content(filename, new_content.string) + end + + create_index(requirements_by_module) + end + + def clean_destination(dir_path = export_dir) + Dir.new(dir_path).children.each do |file| + dst = File.join(dir_path, file) + path = Pathname.new(dst) + + clean_destination(dst) if path.directory? + + next if file_list.include? dst + + if path.directory? + path.rmdir if path.empty? + else + path.delete + end + end + end + end +end diff --git a/dim/lib/dim/commands/format.rb b/dim/lib/dim/commands/format.rb new file mode 100644 index 0000000..332f006 --- /dev/null +++ b/dim/lib/dim/commands/format.rb @@ -0,0 +1,198 @@ +require 'fileutils' + +require_relative '../globals' + +module Dim + class Format + SUBCOMMANDS['format'] = self + TARGET_WIDTH = 120 + TARGET_WIDTH_ONE_LINER = 150 + WIDTH_MIN = 50 # used when ID in one-liner or language-attr is very long + + def initialize(loader) + @loader = loader + end + + def short_type(type) + return "h#{type[8..]}" if /\Aheading_(\d+)\z/ === type + + 'info' # type == "information" + end + + def create_string_array(val, line_width, line_width_first) + input = val.strip + return ['|'] + input.split("\n") if input.include?("\n") + + if "#,[]{}&*!|>\)\"%@`'?:-".include?(input[0]) || input =~ /(:(\s|\Z)|\s#)/ || (input.length > line_width_first && input =~ /\s\s/) + return ['|', input] if input.length <= line_width_first + + res = ['>'] + else + res = [] + end + until input.empty? + width = (res.empty? ? line_width_first : line_width) + if input.length <= width + res << input + break + end + pos = input[0, width + 2].rindex(/ \w/) + if pos + res << input[0, pos] + input = input[pos + 1..] + else + pos = input.index(/ \w/) + if pos + res << input[0, pos] + input = input[pos + 1..] + else + res << input + break + end + end + end + res + end + + def dump(attr, val, shift, target_width = TARGET_WIDTH) + shift_first = [shift - attr.length, 0].max + + line_width = [target_width - shift, WIDTH_MIN].max + line_width_first = [target_width - [shift, attr.length].max, WIDTH_MIN].max + + array = create_string_array(val, line_width, line_width_first) + array[0] = attr + ' ' * shift_first + array[0] + (1..array.length - 1).each do |i| + array[i] = ' ' * shift + array[i] + end + array + end + + def format_file(data) + io = StringIO.new + + io.puts "document: #{data['document']}\n\n" + + if data.key?('metadata') && !data['metadata'].empty? + io.puts dump('metadata: ', data['metadata'], 10) + io.puts "\n" + end + + data.each do |id, req| + next if %w[module enclosed document].include? id + + # do not write default values + next unless req.is_a?(Hash) + + req.delete_if { |_key, value| value.nil? } + + req.delete('test_setups') + + %w[tags verification_methods refs].each do |e| + req[e] = req[e].cleanUniqString if req.key?(e) && req[e].is_a?(String) + end + + # use oneliner style for headings and information if reasonable + if req.keys.length == 2 && + %w[type text].all? { |e| req.key?(e) } && + (req['type'] =~ /\Aheading_\d+\Z/ || + req['type'] =~ /\Ainformation\Z/) + stripped = req['text'].strip + unless stripped.include?("\n") + one_liner = "#{short_type(req['type'])} #{req['text']}" + str = dump("#{id}: ", one_liner, Requirement::SYNTAX['text'][:format_shift], TARGET_WIDTH_ONE_LINER) + if str.length == 1 + io.puts str + io.puts "\n" + next + end + end + end + + io.puts "#{id}:" + @loader.all_attributes.each_key do |k| + next unless req.key?(k) + + if req[k] && req[k].empty? || req[k].nil? + io.puts " #{k}:" + next + end + shift = [@loader.all_attributes[k][:format_shift], k.length + 4].max + case @loader.all_attributes[k][:format_style] + when :single + shift_str = ' ' * [shift - (k.length + 4), 0].max + io.puts " #{k}: #{shift_str}#{req[k].strip}" + when :multi + shift_str = ' ' * [shift - (k.length + 4), 0].max + io.puts " #{k}: #{shift_str}#{req[k].cleanUniqString}" + when :list + io.puts dump(" #{k}: ", req[k].cleanUniqString, shift) + when :text + io.puts dump(" #{k}: ", req[k], shift) + when :split + arr = req[k].cleanUniqArray + + if arr.length == 1 + io.puts " #{k}: #{shift_str}#{arr[0]}" + else + io.puts " #{k}: #{shift_str}>" + shift_str = ' ' * shift + arr.each_with_index do |a, i| + io.puts "#{shift_str}#{a}#{i < arr.length - 1 ? ',' : ''}" + end + end + else + Dim::ExitHelper.exit(code: 1, msg: 'Invalid format style') + end + end + + io.puts "\n" + end + + if data.key?('enclosed') + a = Array(data['enclosed']) + if a.length == 1 + io.puts "enclosed: #{a[0]}\n\n" + else + io.puts "enclosed:\n" + Array(data['enclosed']).each do |e| + io.puts " - #{e}" + end + io.puts "\n" + end + end + + io.truncate(io.length - 1) # do not print two line breaks at the end + + io + end + + def execute(silent: true) + puts OPTIONS[:output_format] == 'check-only' ? 'Checking format...' : 'Formatting...' unless silent + + incorrect_files = [] + @loader.original_data.each do |filename, data| + formatted_data = format_file(data).string + if OPTIONS[:output_format] == 'check-only' + original_data = File.read(filename).universal_newline + incorrect_files << filename if original_data != formatted_data + elsif OPTIONS[:output_format] == 'stdout' + puts formatted_data + next + else + output_filename = OPTIONS[:output_format] == 'extra' ? "#{filename}.formatted" : filename + File.write(output_filename, formatted_data) + end + end + + unless incorrect_files.empty? + io = StringIO.new + io.puts 'The following files are not formatted correctly:' + io.puts(incorrect_files.map { |f| "- #{f}" }) + Dim::ExitHelper.exit(code: 1, msg: io.string) + end + + puts 'Done.' unless silent + end + end +end diff --git a/dim/lib/dim/commands/stats.rb b/dim/lib/dim/commands/stats.rb new file mode 100644 index 0000000..9fcb037 --- /dev/null +++ b/dim/lib/dim/commands/stats.rb @@ -0,0 +1,64 @@ +module Dim + class Stats + SUBCOMMANDS['stats'] = self + + def initialize(loader) + @loader = loader + end + + def execute(silent: true) + print_stats + end + + def print_owner(type, module_name = nil) + if type == :all + top = 'ALL' + is_owner = proc { |_x| true } + else # :module + is_owner = proc { |x| x.document == module_name } + top = "DOCUMENT: #{module_name}" + end + + puts "\n#{top}\n#{'-' * top.length}" + all_reqs = @loader.requirements.values + reqs_owner = all_reqs.select { |r| is_owner.call(r) } + + num_files = if type == :module + @loader.module_data[module_name][:files].length + else + @loader.module_data.values.map { |e| e[:files].keys }.flatten.length + end + puts "Number of files: #{num_files}" + + if type != :module + mods = reqs_owner.map(&:document).uniq + puts "Number of modules: #{mods.count}" + end + + puts "Number of entries: #{reqs_owner.length}" + real_reqs_owner = reqs_owner.select { |r| r.data['type'] == 'requirement' } + puts "Requirements: #{real_reqs_owner.length}" + valid_reqs = real_reqs_owner.select { |r| r.data['status'] == 'valid' } + puts "Valid requirements: #{valid_reqs.length}" + accepted = valid_reqs.select { |r| r.data['review_status'] == 'accepted' } + puts " Accepted: #{accepted.length}" + covered = accepted.select { |r| r.data['tags'].include?('covered') } + puts " Covered: #{covered.length}" + not_covered_num = accepted.length - covered.length + puts " Not covered: #{not_covered_num}" + rejected = valid_reqs.select { |r| r.data['review_status'] == 'rejected' } + puts " Rejected: #{rejected.length}" + unclear = valid_reqs.select { |r| r.data['review_status'] == 'unclear' } + puts " Unclear: #{unclear.length}" + not_reviewed = valid_reqs.select { |r| r.data['review_status'] == 'not_reviewed' } + puts " Not reviewed: #{not_reviewed.length}" + end + + def print_stats + @loader.requirements.values.map(&:document).uniq.each do |mod| + print_owner(:module, mod) + end + print_owner(:all) + end + end +end diff --git a/dim/lib/dim/consistency.rb b/dim/lib/dim/consistency.rb new file mode 100644 index 0000000..93aa0b1 --- /dev/null +++ b/dim/lib/dim/consistency.rb @@ -0,0 +1,187 @@ +require_relative 'globals' +require_relative 'exit_helper' + +module Dim + class Consistency + def initialize(loader) + @loader = loader + end + + def cyclic_check(ref, previous_ref, checked_ids = {}, list = []) + return if checked_ids[ref.id] + + # Circular dependency can occur only on same category level + return if previous_ref && (ref.category_level != previous_ref.category_level) + + if list.include?(ref.id) + Dim::ExitHelper.exit( + code: 1, + filename: ref.filename, + msg: "\"#{ref.id}\" is cyclically referenced: #{list.join(' -> ')} -> #{ref.id}" + ) + end + + list << ref.id + + ref.existingRefs.each do |ref_id| + cyclic_check(@loader.requirements[ref_id], ref, checked_ids, list) + end + + list.pop + + # Any value other than nil and false will work, as this is being used to check + # boolean condition on line#11 + checked_ids[ref.id] = 1 if list.empty? + end + private :cyclic_check + + def insert_default_values(req) + req.all_attributes.each do |key, config| + next if req.data.key?(key) + + req.data[key] = config[:default] + end + end + + def insert_property_file_definitions(ref) + @loader.property_table.fetch(ref.document, {}).each do |attr, value| + ref.data[attr] = value if ref.data[attr].nil? + + if attr == 'test_setups' && (ref.data['verification_methods'].nil? || ref.data['verification_methods'] == '') + ref.data['verification_methods'] = value + end + end + end + + def merge_test_setups_and_verification_methods(ref) + return if ref.data.key?('verification_methods') && !ref.data['verification_methods'].nil? + + ref.data['verification_methods'] = ref.data['test_setups'].clone + end + + def calculate_test_setups(ref) + return unless ref.data['test_setups'].nil? + + tags = ref.data['tags'].cleanArray + + ref.data['test_setups'] = if ref.data['type'] != 'requirement' || tags.include?('process') + 'none' + elsif ref.category == 'input' || ref.category == 'unspecified' + 'none' + elsif ref.category == 'module' + 'off_target' + elsif tags.include?('tool') + 'off_target' + else + 'on_target' + end + end + + def calculate_verification_methods(ref) + return unless ref.data['verification_methods'].nil? + + tags = ref.data['tags'].cleanArray + + ref.data['verification_methods'] = if ref.data['type'] != 'requirement' || tags.include?('process') + 'none' + elsif ref.category == 'input' || ref.category == 'unspecified' + 'none' + elsif ref.category == 'module' + 'off_target' + elsif tags.include?('tool') + 'off_target' + else + 'on_target' + end + end + + def calculate_review_status(ref) + return unless ref.data['review_status'].nil? + + ref.data['review_status'] = if ref.category == 'input' || ref.category == 'unspecified' + 'not_reviewed' + else + 'accepted' + end + end + + def clean_comma_separated(ref) + %w[tags developer tester refs test_setups verification_methods].each do |var| + ref.data[var] = ref.data[var].cleanString + end + end + + def calculate_developer_tester(ref) + %w[developer tester].each do |t| + next unless ref.data[t].nil? + + ref.data[t] = if ref.data['type'] != 'requirement' + '' + elsif ref.data['tags'].cleanArray.include?('process') && t == 'tester' + '' + elsif ref.category == 'input' || ref.category == 'unspecified' + '' + else + ref.origin + end + end + end + + def calculate_status(ref) + return unless ref.data['status'].nil? + + ref.data['status'] = %w[requirement information].include?(ref.data['type']) ? 'draft' : 'valid' + end + + def check(allow_missing:) + requirements_by_module = {} + @loader.module_data.keys.each { |um| requirements_by_module[um] = [] } + @loader.requirements.each { |_id, r| requirements_by_module[r.document] << r } + + @loader.requirements.each do |_id, r| + insert_property_file_definitions(r) + insert_default_values(r) + merge_test_setups_and_verification_methods(r) + calculate_test_setups(r) + calculate_verification_methods(r) + calculate_review_status(r) + calculate_developer_tester(r) + calculate_status(r) + end + + @loader.requirements.each do |_id, r| + clean_comma_separated(r) + end + + @loader.requirements.each do |id, r| + r.data['refs'].cleanArray.each do |ref| + if !@loader.requirements.has_key?(ref) + unless allow_missing + Dim::ExitHelper.exit( + code: 1, + filename: r.filename, + msg: "\"#{id}\" refers to non-existing \"#{ref}\"" + ) + end + else + # Generate upstream and downstream refs based on category level + if @loader.requirements[id].category_level <= @loader.requirements[ref].category_level + @loader.requirements[id].downstreamRefs |= [ref] + @loader.requirements[ref].upstreamRefs |= [id] + else + @loader.requirements[id].upstreamRefs |= [ref] + @loader.requirements[ref].downstreamRefs |= [id] + end + @loader.requirements[ref].backwardRefs << id + r.existingRefs << ref + end + end + end + + @checked_ids = {} + @loader.requirements.each do |_id, r| + cyclic_check(r, nil, @checked_ids) + end + end + end +end diff --git a/dim/lib/dim/dimmain.rb b/dim/lib/dim/dimmain.rb new file mode 100644 index 0000000..cf4e11a --- /dev/null +++ b/dim/lib/dim/dimmain.rb @@ -0,0 +1,28 @@ +$stdout.sync = true + +require 'yaml' + +require_relative 'globals' +require_relative 'exit_helper' +require_relative 'ext/string' +require_relative 'loader' +require_relative 'ver' +require_relative 'requirement' +require_relative 'commands/stats' +require_relative 'commands/check' +require_relative 'commands/export' +require_relative 'commands/format' +require_relative 'options' + +module Dim + def self.main(args = ARGV) + Dim::Options.parse(args) + loader = Dim::Loader.new + loader.load(file: OPTIONS[:input], + attributes_file: OPTIONS[:attributes], + allow_missing: OPTIONS[:allow_missing], + no_check_enclosed: OPTIONS[:no_check_enclosed] || false, + silent: OPTIONS[:silent] || false) + SUBCOMMANDS[OPTIONS[:subcommand]].new(loader).execute(silent: OPTIONS[:silent] || false) + end +end diff --git a/dim/lib/dim/encoding.rb b/dim/lib/dim/encoding.rb new file mode 100644 index 0000000..1fb498d --- /dev/null +++ b/dim/lib/dim/encoding.rb @@ -0,0 +1,4 @@ +# This overwrites the configuration of local machines, +# Dim shall read, process and write only UTF_8. +Encoding.default_external = Encoding::UTF_8 +Encoding.default_internal = Encoding::UTF_8 diff --git a/dim/lib/dim/exit_helper.rb b/dim/lib/dim/exit_helper.rb new file mode 100644 index 0000000..6432775 --- /dev/null +++ b/dim/lib/dim/exit_helper.rb @@ -0,0 +1,23 @@ +module Dim + class ExitHelper + @exit_code = 0 + + class << self + def exit_code + @exit_code + end + + def reset_exit_code + @exit_code = 0 + end + + def exit(msg:, code: 0, filename: nil) + @exit_code = code + inf = filename ? "in #{filename}: " : '' + pre = code.positive? ? 'Error: ' : '' + warn("#{pre}#{inf}#{msg}") + Kernel.exit(code) + end + end + end +end diff --git a/dim/lib/dim/exporter/csv.rb b/dim/lib/dim/exporter/csv.rb new file mode 100644 index 0000000..f6e82b0 --- /dev/null +++ b/dim/lib/dim/exporter/csv.rb @@ -0,0 +1,25 @@ +require_relative '../globals' +require_relative '../requirement' + +module Dim + class Csv < ExporterInterface + EXPORTER['csv'] = self + + def header(content) + @keys = @loader.all_attributes.keys + @keys.delete('test_setups') + content.puts 'Sep=,' + content.puts "id,document_name,originator,#{@keys.join(',')}" + end + + def requirement(content, req) + vals = [req.id, req.document, req.origin] + @keys.each { |k| vals << req.data[k] } + # These values will never be nil. + # ID cannot be nil in Dim file, so as origin (default is "") and + # document cannot be missing in Dim files. + # Which leaves with data and YAML file cannot define nil value. + content.puts(vals.map { |a| "\"#{a.gsub('"', '""')}\"" }.join(',')) + end + end +end diff --git a/dim/lib/dim/exporter/exporterInterface.rb b/dim/lib/dim/exporter/exporterInterface.rb new file mode 100644 index 0000000..1ae4120 --- /dev/null +++ b/dim/lib/dim/exporter/exporterInterface.rb @@ -0,0 +1,37 @@ +module Dim + # This is how the interface is used by the Dim::Export: + # + # initialize() + # + # for every module: + # header() + # document() + # metadata() + # for every requirement in module: + # requirement() + # footer() + # + # if hasIndex: + # for every originator/category combination: + # index() + class ExporterInterface + attr_reader :hasIndex + + def initialize(loader) + @hasIndex = false + @loader = loader + end + + def header(f); end + + def document(f, name); end + + def metadata(f, metadata); end + + def requirement(f, r); end + + def footer(f); end + + def index(f, category, origin, modules); end + end +end diff --git a/dim/lib/dim/exporter/json.rb b/dim/lib/dim/exporter/json.rb new file mode 100644 index 0000000..4a58ffd --- /dev/null +++ b/dim/lib/dim/exporter/json.rb @@ -0,0 +1,32 @@ +require 'json' + +require_relative '../globals' +require_relative '../requirement' + +module Dim + class Json < ExporterInterface + EXPORTER['json'] = self + + def header(_f) + @content = [] + end + + def requirement(_f, r) + vals = { 'id' => r.id, 'document_name' => r.document, 'originator' => r.origin } + + @loader.all_attributes.keys.each do |k| + next if k == 'test_setups' + + v = r.data[k] + v = v.cleanUniqArray.join(',') if k == 'refs' + vals[k] = v.strip + end + + @content << vals + end + + def footer(f) + f.puts(JSON.pretty_generate(@content)) + end + end +end diff --git a/dim/lib/dim/exporter/rst.rb b/dim/lib/dim/exporter/rst.rb new file mode 100644 index 0000000..a22ccb1 --- /dev/null +++ b/dim/lib/dim/exporter/rst.rb @@ -0,0 +1,142 @@ +require 'json' + +module Dim + class Rst < ExporterInterface + EXPORTER['rst'] = self + + def initialize(loader) + super(loader) + @hasIndex = true + end + + def document(f, name) + raw_html_name = ':raw-html:`' + name + '`' + f.puts raw_html_name + f.puts '=' * raw_html_name.length + @lastHeadingLevel = 0 + @moduleName = name + end + + def metadata(f, meta) + f.puts '' + f.puts html(meta.strip.escape_html, with_space: false) + end + + def level2char(level) + { 0 => '=', + 1 => '-', + 2 => '+', + 3 => '~', + 4 => '^', + 5 => '"' }.fetch(level, '"') + end + + def html(elem, with_space: true) + return if elem.empty? + + with_space ? " :raw-html:`#{elem}`" : ":raw-html:`#{elem}`" + end + + def handle_empty_value(value) + return '' if value.empty? + + ' ' + (value.is_a?(Array) ? value.join(', ') : value) + end + + def createMultiLanguageElement(r, name) + lang_elems = r.data.keys.select { |k| k.start_with?("#{name}_") && !r.data[k].empty? }.sort + if lang_elems.empty? + return r.data[name].empty? ? '' : r.data[name] + end + + str = (r.data[name].empty? ? '-' : r.data[name]) + lang_elems.each do |l| + str << "

#{l.split('_').map(&:capitalize).join(' ')}: " + str << r.data[l] + end + str + end + + def requirement(f, r) + r.data.each { |k, v| r.data[k] = v.strip.escape_html } + + if r.data['type'].start_with?('heading') + (@lastHeadingLevel + 1...r.depth).each do |l| + str = '' + f.puts '' + f.puts str + f.puts level2char(l) * str.length + end + f.puts '' + str = ':raw-html:`' + r.data['text'] + '`' + f.puts str + f.puts level2char(r.depth) * str.length + @lastHeadingLevel = r.depth + return + end + + r.data['tester'].gsub!('
', ' ') + r.data['developer'].gsub!('
', ' ') + text = createMultiLanguageElement(r, 'text') + comment = createMultiLanguageElement(r, 'comment') + refs = r.data['refs'].cleanUniqArray.select do |ref| + !@loader.requirements.has_key?(ref) || !@loader.requirements[ref].type.start_with?('heading') + end + tags = r.data['tags'].cleanUniqString + sources = r.data['sources'].cleanUniqString + + f.puts '' + f.puts ".. #{r.data['type']}:: #{r.id}" + f.puts " :category: #{r.category}" + f.puts " :status: #{r.data['status']}" + f.puts " :review_status: #{r.data['review_status']}" + f.puts " :asil: #{r.data['asil']}" + f.puts " :cal: #{r.data['cal']}" + f.puts " :tags:#{handle_empty_value(tags)}" + f.puts " :comment:#{html(comment)}" + f.puts " :miscellaneous:#{html(r.data['miscellaneous'])}" + f.puts " :refs:#{handle_empty_value(refs)}" + @loader.custom_attributes.each_key do |custom_attribute| + f.puts " :#{custom_attribute}:#{handle_empty_value(r.data[custom_attribute])}" + end + if r.data['type'] == 'requirement' + vc = createMultiLanguageElement(r, 'verification_criteria') + + f.puts " :sources:#{handle_empty_value(sources)}" + f.puts " :feature:#{html(r.data['feature'])}" + f.puts " :change_request:#{html(r.data['change_request'])}" + f.puts " :developer:#{handle_empty_value(r.data['developer'])}" + f.puts " :tester:#{handle_empty_value(r.data['tester'])}" + f.puts " :verification_methods:#{handle_empty_value(r.data['verification_methods'])}" + f.puts " :verification_criteria:#{html(vc)}" + end + + f.puts "\n #{html(text)}" unless text.empty? + end + + def footer(f) + files = @loader.module_data[@moduleName][:files].values.flatten + return if files.empty? + + f.puts '' + f.puts '.. enclosed::' + f.puts '' + files.each do |file| + f.puts " #{file}" + end + end + + def index(f, category, origin, modules) + caption = category.capitalize + ' (' + origin + ')' + f.puts caption + f.puts '=' * caption.length + f.puts '' + f.puts '.. toctree::' + f.puts ' :maxdepth: 1' + f.puts '' + modules.sort.each do |m| + f.puts " #{m.sanitize}/Requirements" + end + end + end +end diff --git a/dim/lib/dim/ext/psych.rb b/dim/lib/dim/ext/psych.rb new file mode 100644 index 0000000..d16ab00 --- /dev/null +++ b/dim/lib/dim/ext/psych.rb @@ -0,0 +1,63 @@ +require_relative '../exit_helper' + +module Dim + module Refinements + refine Psych::Nodes::Document do + def line_numbers + hash = {} + children[0].children.each do |node| + if node.is_a?(Psych::Nodes::Scalar) + hash[node.value] = node.start_line + 1 + end + end + hash + end + end + end +end + +module Psych + module Visitors + class ToRuby + alias revive_hash_org revive_hash + + def patched_revive_hash(hash, o) + test_hash = {} + o.children.each_slice(2) do |k, _v| + key = accept(k) + if test_hash.has_key?(key) + line = "line #{k.start_line + 1}: " + Dim::ExitHelper.exit(code: 1, msg: "#{line}found \"#{key}\" twice which must be unique.") + end + test_hash[key] = k + end + revive_hash_org hash, o + end + + def self.add_patch + alias revive_hash patched_revive_hash + end + + def self.revert_patch + alias revive_hash revive_hash_org + end + end + end + + module Nodes + class Scalar + alias initialize_org initialize + def quoted_initialize(value, anchor = nil, tag = nil, plain = true, _quoted = false, style = ANY) + initialize_org(value, anchor, tag, plain, true, style) + end + + def self.add_patch + alias initialize quoted_initialize + end + + def self.revert_patch + alias initialize initialize_org + end + end + end +end diff --git a/dim/lib/dim/ext/string.rb b/dim/lib/dim/ext/string.rb new file mode 100644 index 0000000..035768d --- /dev/null +++ b/dim/lib/dim/ext/string.rb @@ -0,0 +1,85 @@ +class String + def cleanString + cleanArray.join(', ') + end + + def cleanUniqString + cleanUniqArray.join(', ') + end + + def cleanUniqArray + cleanArray.uniq + end + + def cleanArray + cleanSplit.select { |s| !s.empty? } + end + + def cleanSplit + split(/(?', '>') + .gsub('"', '"') + .gsub("'", ''') + .gsub("\t", ' ') + .gsub("\n", '
') + .gsub('`', '`') + .gsub(/(?<= ) /, ' ') + end + + def escape_html_inside + gsub('`', '`') + .gsub("\t", ' ') + .gsub("\n", ' ') + end + + def get_next_escape_token(pos) + ind = index(%r{<\s*(\/?)\s*html\s*>}, pos) + return [:none, length - pos, -1] if ind.nil? + + type = Regexp.last_match(1).empty? ? :start : :end + [type, ind - pos, ind + Regexp.last_match(0).length] + end + + def escape_html + str = '' + search_pos = 0 + nested = 0 + while true + next_token, token_pos, after_token_pos = get_next_escape_token(search_pos) + if nested == 0 + str << self[search_pos, token_pos].escapeHtmlOutside + nested = 1 if next_token == :start + else + str << self[search_pos, token_pos].escape_html_inside + nested += (next_token == :start ? +1 : -1) + end + break if next_token == :none + + search_pos = after_token_pos + end + str.strip + end + + def sanitize + gsub(/[^a-zA-Z0-9.\-_]/, '_') + end + + def universal_newline + encode(encoding, universal_newline: true) + end +end diff --git a/dim/lib/dim/globals.rb b/dim/lib/dim/globals.rb new file mode 100644 index 0000000..ac07b70 --- /dev/null +++ b/dim/lib/dim/globals.rb @@ -0,0 +1,12 @@ +OPTIONS ||= {} +SUBCOMMANDS ||= {} +EXPORTER ||= {} +CATEGORY_ORDER = { + 'input' => 1, + 'system' => 2, + 'software' => 3, + 'architecture' => 4, + 'module' => 5, +}.freeze +ALLOWED_CATEGORIES = CATEGORY_ORDER.keys.each_with_object({}) { |k, obj| obj[k.to_sym] = k }.freeze +SRS_NAME_REGEX = /[^a-zA-Z0-9-]+/.freeze diff --git a/dim/lib/dim/helpers/attribute_helper.rb b/dim/lib/dim/helpers/attribute_helper.rb new file mode 100644 index 0000000..3892771 --- /dev/null +++ b/dim/lib/dim/helpers/attribute_helper.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require_relative 'file_helper' + +module Dim + module Helpers + module AttributeHelper + include FileHelper + + CHECK_SINGLE_ENUM = :check_single_enum + CHECK_MULTI_ENUM = :check_multi_enum + FORMAT_STYLES = { + 'list' => 'list', + 'multi' => 'multi', + 'single' => 'single', + 'split' => 'split', + 'text' => 'text' + }.freeze + @filepath = '' + + def resolve_attributes(folder:, filename:) + @filepath = "#{folder}/#{filename}" + attributes = open_yml_file(folder, filename, allow_empty_file: true) + unless attributes + puts "Warning: empty file detected; skipped loading of #{filename}" + return + end + + check_for_default_attributes(attributes, filename) + + attributes.each do |attribute, attr_config| + attr_config.transform_keys!(&:to_sym) + + change_type_to_format_style(attr_config) + validate_format_style(attribute, attr_config) + add_check_value(attr_config) + validate_default(attribute, attr_config) + validate_allowed(attribute, attr_config) + validate_allowed_for_enum(attribute, attr_config) + validate_default_for_enum(attribute, attr_config) + + symbolize_values(attr_config) + end + + attributes + end + + def check_for_default_attributes(attributes, filename) + common_values = Requirement::SYNTAX.keys & attributes.keys + return if common_values.empty? + + Dim::ExitHelper.exit( + code: 1, + filename: @filepath, + msg: 'Defining standard attributes as a custom attributes is not allowed; ' \ + "#{common_values.join(',')} in #{filename}" + ) + end + + # TODO: change "format_style" to "type" in requirements syntax and then remove this conversion + def change_type_to_format_style(config) + config[:format_style] = config.delete(:type) + end + + def validate_format_style(attribute, config) + return if FORMAT_STYLES.values.include?(config[:format_style]) + + exit_with_error(config: 'type', config_value: config[:format_style], attribute: attribute) + end + + def add_check_value(config) + config[:check] = CHECK_SINGLE_ENUM if config[:format_style] == FORMAT_STYLES['single'] + config[:check] = CHECK_MULTI_ENUM if config[:format_style] == FORMAT_STYLES['multi'] + end + + def validate_default(attribute, config) + return unless config[:default] == 'auto' + + exit_with_error(config: 'default', config_value: config[:default], attribute: attribute) + end + + def validate_allowed(attribute, config) + return if config[:allowed].nil? || config[:allowed].is_a?(Array) + + exit_with_error(config: 'allowed', config_value: config[:allowed], attribute: attribute) + end + + def validate_allowed_for_enum(attribute, config) + return unless FORMAT_STYLES.fetch_values('single', 'multi').include?(config[:format_style]) + + return if config[:allowed].is_a?(Array) && config[:allowed].map { |val| val.is_a?(String) }.all? + + Dim::ExitHelper.exit( + code: 1, + filename: @filepath, + msg: "Allowed value must be list of strings; invalid allowed value for #{attribute}" + ) + end + + def validate_default_for_enum(attribute, config) + return unless FORMAT_STYLES.fetch_values('single', 'multi').include?(config[:format_style]) + + return if config[:allowed].include?(config[:default]) + + Dim::ExitHelper.exit( + code: 1, + filename: @filepath, + msg: "default value for #{attribute} must be from allowed list of #{config[:allowed]}" + ) + end + + def symbolize_values(config) + config[:format_style] = config[:format_style].to_sym if config[:format_style] + config[:format_shift] = config[:format_shift].to_i + config[:default] = '' unless config[:default] + end + + private + + def exit_with_error(config:, config_value:, attribute:) + msg = "Invalid value \"#{config_value}\" for #{config} detected for attribute #{attribute}" + Dim::ExitHelper.exit(code: 1, filename: @filepath, msg: msg) + end + end + end +end diff --git a/dim/lib/dim/helpers/file_helper.rb b/dim/lib/dim/helpers/file_helper.rb new file mode 100644 index 0000000..46587d0 --- /dev/null +++ b/dim/lib/dim/helpers/file_helper.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require_relative '../exit_helper' + +module Dim::Helpers + module FileHelper + def open_yml_file(folder, filename, allow_empty_file: false) + file_path = Pathname.new(File.join(folder, filename)).cleanpath.to_s + binary_data = File.binread(file_path).chomp + begin + data = YAML.parse( + binary_data.encode('utf-8', invalid: :replace, undef: :replace, replace: '?'), + filename: file_path + ) + rescue Psych::SyntaxError => e + Dim::ExitHelper.exit(code: 1, filename: filename, msg: e.message) + end + + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'not a valid yaml file') unless data || allow_empty_file + return unless data + + data.to_ruby + end + end +end diff --git a/dim/lib/dim/loader.rb b/dim/lib/dim/loader.rb new file mode 100644 index 0000000..d82b23e --- /dev/null +++ b/dim/lib/dim/loader.rb @@ -0,0 +1,581 @@ +require 'yaml' +require 'pathname' + +require_relative 'encoding' +require_relative 'globals' +require_relative 'ext/psych' +require_relative 'requirement' +require_relative 'consistency' +require_relative 'exit_helper' +require_relative 'helpers/attribute_helper' +require_relative 'helpers/file_helper' + +using Dim::Refinements + +module Dim + class Loader + include Helpers::AttributeHelper + + attr_reader :requirements, :config, :property_table, :properties, :original_data, :module_data, :metadata, :dim_file, :all_attributes, :custom_attributes + + # YAML standard: + # invalid C0 control characters: 0x00 - 0x1F (except TAB 0x09, LF 0x0A and CR 0x0D) + # invalid control character DEL 0x7F + # invalid C1 control characters: 0x80 - 0x9F (except NEL 0x85) + # + # in addition NEL will be also replaced which seems to be misused in CRS documents + @@invalid_ccs = { + "\x00" => '[NUL]', "\x01" => '[SOH]', "\x02" => '[STX]', "\x03" => '[ETX]', + "\x04" => '[EOT]', "\x05" => '[ENQ]', "\x06" => '[ACK]', "\x07" => '[BEL]', + "\x08" => '[BS]', "\x0B" => '[VT]', + "\x0C" => '[FF]', "\x0E" => '[SO]', "\x0F" => '[SI]', + "\x10" => '[DLE]', "\x11" => '[DC1]', "\x12" => '[DC2]', "\x13" => '[DC3]', + "\x14" => '[DC4]', "\x15" => '[NAK]', "\x16" => '[SYN]', "\x17" => '[ETB]', + "\x18" => '[CAN]', "\x19" => '[EM]', "\x1A" => '[SUB]', "\x1B" => '[ESC]', + "\x1C" => '[FS]', "\x1D" => '[GS]', "\x1E" => '[RS]', "\x1F" => '[US]', + "\x7F" => '[DEL]', + "\u0080" => '[PAD]', "\u0081" => '[HOP]', "\u0082" => '[BPH]', "\u0083" => '[NBH]', + "\u0084" => '[IND]', "\u0085" => '[NEL]', "\u0086" => '[SSA]', "\u0087" => '[ESA]', + "\u0088" => '[HTS]', "\u0089" => '[HTJ]', "\u008A" => '[VTS]', "\u008B" => '[PLD]', + "\u008C" => '[PLU]', "\u008D" => '[RI]', "\u008E" => '[SS2]', "\u008F" => '[SS3]', + "\u0090" => '[DCS]', "\u0091" => '[PU1]', "\u0092" => '[PU2]', "\u0093" => '[STS]', + "\u0094" => '[CCH]', "\u0095" => '[MW]', "\u0096" => '[SPA]', "\u0097" => '[EPA]', + "\u0098" => '[SOS]', "\u0099" => '[SGCI]', "\u009A" => '[SCI]', "\u009B" => '[CSI]', + "\u009C" => '[ST]', "\u009D" => '[OSC]', "\u009E" => '[PM]', "\u009F" => '[APC]' + } + + def initialize + @requirements = {} + @module_data = {} + @metadata = {} + @config = {} + @properties = {} + @property_table = {} + @original_data = {} + @all_attributes = Requirement::SYNTAX.dup + @custom_attributes = {} + end + + def filter(str) + @requirements.keep_if { |_id, r| r.filter(str) } + end + + def load(file: nil, attributes_file: nil, allow_missing: false, no_check_enclosed: false, silent: true, input_filenames: []) + ::Psych::Nodes::Scalar.add_patch + ::Psych::Visitors::ToRuby.add_patch + + input_filenames = *input_filenames + # If output format is vim then we do not need to read the file, + # content will be read from the stdin and printed out to stdout. This is to enhance the + # formatting in the vim. + unless OPTIONS[:output_format] == 'stdout' + if input_filenames.length > 0 and file + Dim::ExitHelper.exit(code: 1, msg: 'use either file or input_filenames argument (deprecated) for load method') + end + if input_filenames.length > 1 + Dim::ExitHelper.exit(code: 1, + msg: 'input_filenames argument (deprecated) of load method must have at maximum one entry') + end + file = input_filenames[0] if input_filenames.length == 1 + unless file + Dim::ExitHelper.exit(code: 1, + msg: 'neither file nor input_filenames argument (deprecated) argument specified for load method') + end + end + + unless silent + if allow_missing && OPTIONS[:subcommand] != 'format' + puts "Warning: Using 'allow-missing' might influence metrics when some references are ignored!\n" + end + puts 'Start Loading...' + end + + Dim::ExitHelper.exit(code: 1, filename: file, msg: 'does not exist') unless File.exist?(file.to_s) || OPTIONS[:output_format] == 'stdout' + + @dim_file = OPTIONS[:output_format] == 'stdout' ? $stdin.read.chomp : File.binread(file).chomp + + if attributes_file + fetch_attributes!(folder: File.dirname(attributes_file), filename: attributes_file.split('/').last, silent: silent) + elsif !dim_file.match(/^Config:/) + folder = search_attributes_file(file.to_s) + fetch_attributes!(folder: folder, filename: 'attributes.dim', silent: silent) if folder + end + + if dim_file.match(/^Config:/) + load_config(config_filename: file.to_s, silent: silent) + else + load_pattern( + config_filename: nil, + pattern: file.to_s, + origin: '', + silent: silent, + category: 'unspecified', + disable_naming_convention_check: false, + no_check_enclosed: no_check_enclosed + ) + end + + puts 'Checking consistency...' unless silent + checker = Dim::Consistency.new(self) + checker.check(allow_missing: allow_missing) + puts 'Done.' unless silent + ensure + ::Psych::Nodes::Scalar.revert_patch + ::Psych::Visitors::ToRuby.revert_patch + end + + def load_config(config_filename:, silent: true, no_check_enclosed: false) + puts "Loading [config] #{config_filename}..." unless silent + @config = open_yml_file(config_filename, '') + + allowed_attributes = %w[Config Properties Attributes] + + @config.each_key do |k| + next unless allowed_attributes.none? { |a| a == k } + + Dim::ExitHelper.exit(code: 1, filename: config_filename, msg: "top level key in config file must be #{allowed_attributes.map do |a| + "\"#{a}\"" + end.join(', ')}, found \"#{k}\"") + end + + if @config.key?('Attributes') + if @config['Attributes'].is_a?(String) + fetch_attributes!(folder: File.dirname(config_filename), filename: @config['Attributes'], silent: silent) + else + Dim::ExitHelper.exit(code: 1, filename: config_filename, msg: "'Attributes' must be a string") + end + end + + if @config.key?('Properties') + if @config['Properties'].is_a?(String) + resolve_properties(folder: File.dirname(config_filename), properties_filename: @config['Properties']) + else + Dim::ExitHelper.exit(code: 1, filename: config_filename, msg: "'Properties' must be a string") + end + end + + # COP: Move to constants + allowed_keys = %w[files category originator disable_naming_convention_check] + allowed_categories = ALLOWED_CATEGORIES.values + + if @config['Config'].is_a?(Array) + config_values = @config['Config'] + else + Dim::ExitHelper.exit(code: 1, filename: config_filename, msg: "'Config' must be an array") + end + + config_values.each do |value| + validate_and_load_config(value, config_filename) + + unless value.is_a?(Hash) && value.keys.sort_by(&:length).eql?(allowed_keys.sort_by(&:length)) + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "each hash in 'Config' array must have key/value pairs for #{allowed_keys.join(', ')}.") + end + + if value['category'].is_a?(String) + value['category'].strip! + unless allowed_categories.include?(value['category']) + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "attribute \"category\" of '#{value['originator']}' reqs is '#{value['category']}' but must be one of #{allowed_categories.join(', ')}.") + end + else + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "attribute \"category\" of '#{value['originator']}' reqs must be a string") + end + + if value['files'].is_a?(Array) && value['files'].all? { |a| a.is_a?(String) } || value['files'].is_a?(String) + value['files'] = *value['files'] + else + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "attribute \"files\" of '#{value['originator']}' reqs must be a string or an array of strings.") + end + value['files'].each do |pattern| + pattern.gsub!(%r{\A\./}, '') + if pattern.empty? + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "attribute \"files\" of '#{value['originator']}' must not have an empty string") + end + p = Pathname.new(pattern) + if p.absolute? + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "'#{pattern}' must not be an absolute path") + end + if p.each_filename.any? { |e| e == '..' } + Dim::ExitHelper.exit(code: 1, filename: config_filename, + msg: "'#{pattern}' must not include '..'") + end + load_pattern( + config_filename: config_filename, + pattern: pattern, + origin: value['originator'], + silent: silent, + category: value['category'], + disable_naming_convention_check: value['disable_naming_convention_check'], + no_check_enclosed: no_check_enclosed + ) + end + end + puts 'Done.' unless silent + end + + def extract_type(attr) + return {} if attr.empty? + + hscan = attr.scan(/\Ah(\d+)\s.+/) + if hscan.length == 1 + level = hscan[0][0].to_i + return { 'type' => "heading_#{level}", 'text' => attr[2 + hscan[0][0].length..-1].strip } + else + iscan = attr.scan(/\Ainfo\s.+/) + return { 'type' => 'information', 'text' => attr[5..-1].strip } if iscan.length == 1 + end + nil + end + + def load_file(filename:, origin:, silent:, category:, disable_naming_convention_check: false, no_check_enclosed: false) + puts "Loading [#{origin.empty? ? "unknown" : origin}] #{filename}..." unless silent + binary_data = OPTIONS[:output_format] == 'stdout' ? @dim_file : File.binread(filename).force_encoding('UTF-8') + + # this looks expensive but measurement showed it's close to zero + @@invalid_ccs.each { |k, v| binary_data = binary_data.gsub(k, v) } + + if binary_data.valid_encoding? + begin + psych_doc = YAML.parse(binary_data) + rescue Psych::SyntaxError => e + Dim::ExitHelper.exit(code: 1, filename: filename, msg: e.message) + end + else + begin + psych_doc = YAML.parse(binary_data.encode('UTF-8', invalid: :replace, undef: :replace, replace: '?'), + filename: filename) + rescue Psych::SyntaxError => e + Dim::ExitHelper.exit(code: 1, filename: filename, msg: e.message) + end + end + unless psych_doc + puts "Warning: empty file detected; skipped loading of #{filename}" + + return + end + reqs = psych_doc.to_ruby + + unless reqs.is_a?(Hash) + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: 'top level must be a hash with keys "module", "enclosed", "metadata" and/or unique ids' + ) + end + + # TODO: Remove module backward compatibility in future version + if reqs.key?('document') && reqs.key?('module') + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: 'module and document found in the file; please rename module to document' + ) + end + + if reqs.key?('document') + if !reqs['document'].is_a?(String) || reqs['document'].empty? + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'document must be a non-empty string') + end + document = reqs['document'] + # TODO: Remove module backward compatibility in future version + reqs['module'] = document + elsif reqs.key?('module') + if !(reqs['module'].is_a? String) || reqs['module'].empty? + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'module name must be a non-empty string') + end + document = reqs['module'] + reqs['document'] = document + else + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'Document name is missing; please add document name') + end + + validate_srs_name(document, disable_naming_convention_check, category, filename) + + if @module_data.key?(document) + if @module_data[document][:origin] != origin + Dim::ExitHelper.exit(code: 1, filename: filename, msg: + "files of the same module must have the same owner:\n" + + "- #{@module_data[document][:files].first[0]} (#{@module_data[document][:origin]})\n" + + "- #{filename} (#{origin})") + elsif @module_data[document][:category] != category + Dim::ExitHelper.exit(code: 1, filename: filename, msg: + "files of the same module must have the same category:\n" + + "- #{@module_data[document][:files].first[0]} (#{@module_data[document][:category]})\n" + + "- #{filename} (#{category})") + end + else + @module_data[document] = { origin: origin, category: category, files: {} } + end + + if @module_data[document][:files].key?(filename) + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "file #{filename} already loaded") + end + + @module_data[document][:files][filename] = [] + @metadata[document] ||= '' + + if reqs.key?('metadata') + unless reqs['metadata'].is_a?(String) + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'metadata must be a string') + end + unless reqs['metadata'].empty? + unless @metadata[document].empty? + Dim::ExitHelper.exit(code: 1, filename: filename, msg: 'only one metadata per module allowed') + end + @metadata[document] = reqs['metadata'].strip + end + end + + if reqs.key?('enclosed') && !no_check_enclosed + ecl = reqs['enclosed'] + ecl = [ecl] if ecl.is_a?(String) + if !ecl.is_a?(Array) || ecl.empty? || ecl.any? { |s| !s.is_a?(String) || s.empty? } + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: '"enclosed" must be a non-empty string or an array of non-empty strings') + end + # Remove superfluous ./ from path + ecl = ecl.map do |path| + if path.match?(/\\/) + puts "Warning: Backward slashes detected in filepath #{path}. Use '/' over '\\' in filepath" + path.gsub!('\\', '/') + end + Pathname.new(path).cleanpath.to_s + end + dir_file = File.dirname(filename) + ecl.each do |l| + p = Pathname.new(l) + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "'#{l}' must not be an absolute path") if p.absolute? + if p.each_filename.any? do |name| + name == '..' + end + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: "'#{l}' must not include '..'") + end + + src = File.join(dir_file, l) + src_globbed = Dir.glob(src) + if src_globbed.empty? + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: "\"#{l}\" in \"enclosed\" does not refer to any existing file") + end + end + @module_data[document][:files][filename] += ecl + end + + line_numbers = psych_doc.line_numbers + + reqs.each do |id, attr| + next if %w[module enclosed metadata document].include? id + + if @requirements.key?(id) + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "id \"#{id}\" found more than once") + end + + if id.include?(',') + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "Disallowed ',' found in id \"#{id}\"") + end + + validate_srs_name(id, disable_naming_convention_check, category, filename, 'ID') + + if attr.is_a?(String) + attr.strip! + res = extract_type(attr) + if res + attr = res + else + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: "Invalid short-form in requirement \"#{id}\", valid forms are \"h \" or \"info \"") + end + elsif attr.is_a?(Hash) + attr.keys.select do |k| + @all_attributes.key?(k) && %i[multi split].include?(@all_attributes[k][:format_style]) + end.each do |k| + attr[k] = attr[k].cleanUniqString if attr[k].is_a?(String) + end + attr['tags'] = attr['tags'].cleanUniqString if attr['tags'].is_a?(String) + else + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "attributes for id \"#{id}\" must be key-value pairs") + end + unless attr.key?('verification_methods') + attr['verification_methods'] = attr['test_setups'] if attr.key?('test_setups') + end + attr.each do |key, value| + unless value.is_a?(String) + Dim::ExitHelper.exit(code: 1, filename: filename, + msg: "value of attribute \"#{key}\" must be String not #{value.class}") + end + attr[key].gsub!("\u00A0", ' ') + attr[key].strip! + end + + r = Requirement.new(id, document, filename, attr, origin, self, category, line_numbers[id], @all_attributes) + reqs[id] = attr + @requirements[id] = r + end + + @original_data[filename] = Marshal.load(Marshal.dump(reqs)) + end + + def load_pattern(config_filename:, pattern:, origin:, silent:, category:, disable_naming_convention_check: false, no_check_enclosed: false) + if pattern.match?(/\\/) + puts "Warning: Backward slashes detected in pattern #{pattern}. Use '/' over '\\'" + pattern.gsub!('\\', '/') + end + pattern_search = config_filename ? File.join(File.dirname(config_filename), pattern) : pattern + fs = Dir.glob(pattern_search).sort + if fs.empty? && !silent + puts "Info: no matches for \"#{pattern}\" in \"#{config_filename}\"" + end + fs.each do |f| + load_file(filename: f, origin: origin, silent: silent, category: category, disable_naming_convention_check: disable_naming_convention_check, no_check_enclosed: no_check_enclosed) + end + return unless OPTIONS[:output_format] == 'stdout' + + load_file(filename: '', origin: origin, silent: silent, category: category, disable_naming_convention_check: disable_naming_convention_check, no_check_enclosed: no_check_enclosed) + end + + def resolve_properties(folder:, properties_filename:) + @properties = open_yml_file(folder, properties_filename, allow_empty_file: true) + unless @properties + puts "Warning: empty file detected; skipped loading of #{properties_filename}" + return + end + + @properties.each do |document, value| + value.each do |attr, property_value| + next unless @all_attributes.key?(attr) + + unless property_value.is_a?(String) + Dim::ExitHelper.exit(code: 1, filename: properties_filename, + msg: "The value for key #{attr} in properties files must be a string") + end + + if @all_attributes.dig(attr, :allowed).nil? || + !property_value.cleanArray.select do |val| + !@all_attributes[attr][:allowed].include?(val) + end.any? + @property_table[document] ||= {} + @property_table[document][attr] = property_value.strip + else + Dim::ExitHelper.exit(code: 1, filename: properties_filename, + msg: "The properties file includes an invalid #{attr} value '#{property_value}' for module: #{document}.") + end + end + end + end + + def fetch_attributes!(folder:, filename:, silent:) + puts "Loading [attributes] #{File.join(folder, filename)}" unless silent + + @custom_attributes.merge!(resolve_attributes(folder: folder, filename: filename)) + @all_attributes.merge!(@custom_attributes) + end + + def search_attributes_file(file) + path = Pathname.new(file).parent.realpath + if path.root? + nil + else + return path if Dir.new(path).children.include?('attributes.dim') + search_attributes_file(path) + end + end + + def validate_and_load_config(value, config_filename) + disable_naming_convention_check = value['disable_naming_convention_check'] + unless disable_naming_convention_check + value['disable_naming_convention_check'] = false + return + end + + if value['category'] != ALLOWED_CATEGORIES[:software] + warn("Warning: disable_naming_convention_check attribute will only take effect when category is software") + end + + if disable_naming_convention_check == 'yes' + value['disable_naming_convention_check'] = true + return + elsif disable_naming_convention_check == 'no' + value['disable_naming_convention_check'] = false + return + end + + Dim::ExitHelper.exit( + code: 1, + filename: config_filename, + msg: 'disable_naming_convention_check in config must be either boolean value or a string "yes" or "no"' + ) + end + + def validate_srs_name(name, disable_naming_convention_check, category, filename, attr = 'module') + return if category != ALLOWED_CATEGORIES[:software] || disable_naming_convention_check + + # raise error if not starting with SRS_ + unless name.match?(/^(SRS_)/) + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "#{attr} #{name} in software requirement must start with \"SRS_\"" + ) + end + + _srs, feature, aspect, *rest = name.split('_') + + # Raise error if more than two _ detected + unless rest.empty? + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "#{attr} #{name} in software requirement must contain exactly two \"_\"" + ) + end + + if feature.to_s.empty? + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "invalid #{attr} #{name} in software requirement; missing feature after \"SRS_\"" + ) + end + + # Raise error if feature or aspect is non alphanumeric + if feature.match?(SRS_NAME_REGEX) + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "feature in #{attr} #{name} in software requirement contains non-alphanumeric characters" + ) + end + + if attr == 'module' && !aspect.to_s.empty? + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "invalid module #{name} in software requirement; must contain exactly one \"_\"" + ) + end + + # Check naming convention for aspect only in case of IDs + return if attr == 'module' + + if aspect.to_s.empty? + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "invalid ID #{name} in software requirement; missing aspect/ratio after \"SRS_feature\"" + ) + end + + if aspect.match?(SRS_NAME_REGEX) + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "aspect in ID #{name} in software requirement contains non-alphanumeric characters" + ) + end + end + end +end diff --git a/dim/lib/dim/options.rb b/dim/lib/dim/options.rb new file mode 100644 index 0000000..2c8ab45 --- /dev/null +++ b/dim/lib/dim/options.rb @@ -0,0 +1,116 @@ +require 'optparse' + +require_relative 'globals' +require_relative 'exit_helper' + +module Dim + class Options + MAX_COUNT = 10 + + def self.reset + OPTIONS[:filter] = '' + OPTIONS[:title] = 'Requirements - Draft' + OPTIONS[:folder] = nil + OPTIONS[:input] = nil + OPTIONS[:attributes] = nil + OPTIONS[:config] = nil + OPTIONS[:allow_missing] = false + OPTIONS[:output_format] = 'in-place' + OPTIONS[:type] = nil + OPTIONS[:no_check_enclosed] = false + OPTIONS[:silent] = nil + end + reset + + def self.parse(args = ARGV) + op = OptionParser.new do |opts| + opts.banner = "Usage: dim.rb <#{SUBCOMMANDS.keys.join('|')}> [options]" + opts.separator "\nGeneral options:" + opts.on('-h', '--help', 'prints this help') do + Dim::ExitHelper.exit(code: 0, msg: opts) + end + opts.on('-v', '--version', 'prints version') do + Dim::ExitHelper.exit(code: 0, msg: Dim::Ver.sion) + end + opts.on('-l', '--license', 'prints license') do + Dim::ExitHelper.exit(code: 0, msg: File.read(File.dirname(__FILE__) + '/../../license.txt')) + end + + opts.separator "\nFor check, export, stats, format:" + opts.on('-i FILENAME', '--input FILENAME', 'input file or config') do |i| + OPTIONS[:input] = i.gsub('\\', '/') + end + opts.on('-a FILENAME', '--attributes FILENAME', 'file for custom attributes') do |i| + OPTIONS[:attributes] = i.gsub('\\', '/') + end + opts.on('--allow-missing', 'Missing references are ignored') do |_m| + OPTIONS[:allow_missing] = true + end + opts.on('--no-check-enclosed', 'Skip enclosed file check') do |_| + OPTIONS[:no_check_enclosed] = true + end + opts.on('--silent', 'Silent information log') do |_| + OPTIONS[:silent] = true + end + + opts.separator "\nFor export:" + opts.on('--filter FILTER', 'searches for this string in all fields with enums') do |p| + OPTIONS[:filter] = p + end + + opts.separator "\nFor export:" + opts.on('-o FOLDER', '--output FOLDER', 'output folder') do |p| + OPTIONS[:folder] = p + end + opts.on('-f FORMAT', '--format FORMAT', 'output format', + "allowed values: #{EXPORTER.keys.join(', ')}") do |p| + OPTIONS[:type] = + p + end + + opts.separator "\nFor format:" + opts.on('--output-format FORMAT', 'in-place (default): files will be changed if not already formatted correctly', + 'extra: output is written into ".formatted"', + 'check-only: no changes to files', + 'stdout: For IDE format support; will work with STDIN/STDOUT; no file input required') do |p| + OPTIONS[:output_format] = p + end + end + + begin + op.parse!(args) + rescue OptionParser::InvalidOption => e + Dim::ExitHelper.exit(code: 1, msg: e.message) + end + + Dim::ExitHelper.exit(code: 1, msg: op) if args.empty? || !SUBCOMMANDS.keys.include?(args[0]) + OPTIONS[:subcommand] = args[0] + + Dim::ExitHelper.exit(code: 1, msg: 'no input file specified.') if OPTIONS[:input].nil? && OPTIONS[:output_format] != 'stdout' + + if OPTIONS[:subcommand] == 'export' + Dim::ExitHelper.exit(code: 1, msg: 'specify output folder') if OPTIONS[:folder].nil? + if OPTIONS[:type].nil? + Dim::ExitHelper.exit(code: 1, msg: "export format not specified, must be one of: #{EXPORTER.keys.join(', ')}") + end + unless EXPORTER.keys.include?(OPTIONS[:type]) + Dim::ExitHelper.exit(code: 1, msg: "export format must be one of: #{EXPORTER.keys.join(', ')}") + end + end + + if OPTIONS[:output_format] == 'stdout' + OPTIONS[:silent] = true + OPTIONS[:no_check_enclosed] = true + OPTIONS[:allow_missing] = true + end + + if OPTIONS[:subcommand] == 'format' + OPTIONS[:allow_missing] = true + + return if %w[in-place extra check-only stdout].include?(OPTIONS[:output_format]) + + Dim::ExitHelper.exit(code: 1, msg: 'output-format must be in-place, extra or check-only') + end + end + end +end diff --git a/dim/lib/dim/requirement.rb b/dim/lib/dim/requirement.rb new file mode 100644 index 0000000..8dd652f --- /dev/null +++ b/dim/lib/dim/requirement.rb @@ -0,0 +1,236 @@ +require 'set' + +require_relative 'globals' +require_relative 'exit_helper' +require_relative 'ext/string' + +module Dim + class Requirement + attr_accessor :data, :moduleName, :document, :depth, :id, :origin, :loader, :existingRefs, :backwardRefs, :filename, + :category, :line_number, :all_attributes, :upstreamRefs, :downstreamRefs, :category_level + + # rubocop:disable Layout/LineLength, Layout/HashAlignment + SYNTAX = { + 'type' => { check: :check_single_enum, format_style: :single, format_shift: 0, default: 'requirement', + allowed: %w[requirement information heading_] }, + 'text' => { check: nil, format_style: :text, format_shift: 28, default: '', allowed: nil }, + 'verification_criteria' => { check: nil, format_style: :text, format_shift: 32, default: '', allowed: nil }, + 'feature' => { check: nil, format_style: :text, format_shift: 0, default: '', allowed: nil }, + 'change_request' => { check: nil, format_style: :text, format_shift: 0, default: '', allowed: nil }, + 'tags' => { check: nil, format_style: :list, format_shift: 0, default: '', allowed: nil }, + 'asil' => { check: :check_single_enum, format_style: :single, format_shift: 0, default: 'not_set', + allowed: %w[not_set + QM QM(A) QM(B) QM(C) QM(D) + ASIL_A ASIL_A(A) ASIL_A(B) ASIL_A(C) ASIL_A(D) + ASIL_B ASIL_B(B) ASIL_B(C) ASIL_B(D) + ASIL_C ASIL_C(C) ASIL_C(D) + ASIL_D ASIL_D(D)] }, + 'cal' => { check: :check_single_enum, format_style: :single, format_shift: 0, default: 'not_set', + allowed: %w[QM CAL_1 CAL_2 CAL_3 CAL_4 not_set] }, + 'developer' => { check: nil, format_style: :list, format_shift: 0, default: nil, allowed: nil }, + 'tester' => { check: nil, format_style: :list, format_shift: 0, default: nil, allowed: nil }, + 'test_setups' => { check: :check_multi_enum, format_style: :multi, format_shift: 0, default: nil, + allowed: %w[none off_target on_target manual] }, + 'verification_methods' => { check: :check_multi_enum, format_style: :multi, format_shift: 0, default: nil, + allowed: %w[none off_target on_target manual] }, + 'status' => { check: :check_single_enum, format_style: :single, format_shift: 0, default: nil, + allowed: %w[valid draft invalid] }, + 'review_status' => { check: :check_single_enum, format_style: :single, format_shift: 0, default: nil, + allowed: %w[accepted unclear rejected not_reviewed not_relevant] }, + 'comment' => { check: nil, format_style: :text, format_shift: 0, default: '', allowed: nil }, + 'miscellaneous' => { check: nil, format_style: :text, format_shift: 0, default: '', allowed: nil }, + 'sources' => { check: nil, format_style: :split, format_shift: 0, default: '', allowed: nil }, + 'refs' => { check: nil, format_style: :split, format_shift: 0, default: '', allowed: nil } + } + # rubocop:enable Layout/LineLength, Layout/HashAlignment + + # this allows easy access to attribute names + SYNTAX.each_key do |k| + if %i[list multi split].include?(SYNTAX[k][:format_style]) + define_method(k) do + @data[k].cleanUniqArray + end + else + define_method(k) do + @data[k] + end + end + end + + def safety_relevant? + !%w[QM not_set].include?(@data['asil']) + end + + def security_relevant? + !%w[QM not_set].include?(@data['cal']) + end + + # this allows writing enum values without " in filter + alias method_missing_org method_missing + def method_missing(sym, *_args) + str = sym.to_s + return str if /\Aheading_(\d+)\z/ === str + return str if SYNTAX.any? { |_name, attr| attr[:allowed].is_a?(Array) && attr[:allowed].include?(str) } + return str if %w[input software architecture module system].include?(str) + + Dim::ExitHelper.exit(code: 1, msg: "\"#{str}\" is not a requirement attribute") + end + + def filter(str) + eval(str) + end + + def initialize(id, document, filename, attr, origin, loader, category, line_number, all_attributes) + @id = id + @moduleName = document + @document = document + @filename = filename + @data = attr + @origin = origin + @existingRefs = [] # needed later for "missing links" feature + @backwardRefs = [] + @upstreamRefs = [] + @downstreamRefs = [] + @loader = loader + @category = category + @category_level = CATEGORY_ORDER[category] || 0 + @line_number = line_number + @all_attributes = all_attributes + + define_custom_attribute_methods + calc_depth + + check_unknown_keys + check_invalid_values + # TODO: Remove after completely removing test_setups + merge_test_setups_and_verification_methods + check_verification_methods + end + + def define_custom_attribute_methods + new_attributes = @all_attributes.keys - SYNTAX.keys + new_attributes.each do |k| + define_singleton_method(k) do + @data[k] + end + end + end + + def calc_depth + @depth = 1 + hres = @data['type']&.scan(/^heading_(\d+)$/) || '' + return unless hres.length > 0 + + dep = hres[0][0].to_i + return unless dep > 1 + + if dep > 100 + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "heading level above 100 is not allowed and makes absolutely no sense: #{@data['type']}" + ) + end + + @depth = dep + end + + def check_single_enum(elem, key, value) + unless !elem[:allowed].include?(value) && !(elem[:allowed].include?('heading_') && /\Aheading_\d+\Z/ === value) + return + end + + allowed_values = elem[:allowed].reject{ |a| a.nil? || a.empty? }.map { |e| "\"#{e}\"" }.join(', ') + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "attribute \"#{key}\" must not be \"#{value}\" (id: #{@id}). \"#{key}\" must be exactly " \ + "one of #{allowed_values}. #{"Default is \"#{elem[:default]}\"" if elem[:default]}." + ) + end + + def check_multi_enum(element, key, value) + value_array = value.cleanArray + value_array = [''] if value == '' + value_array.each do |v| + next if element[:allowed].include?(v) + + allowed_values = element[:allowed].reject{ |a| a.nil? || a.empty? }.map { |e| "\"#{e}\"" }.join(', ') + Dim::ExitHelper.exit( + code: 1, + filename: filename, + msg: "attribute \"#{key}\" is invalid: \"#{v}\" (id: #{@id}). \"#{key}\" must be one or " \ + "more of #{allowed_values}." + ) + end + end + + def check_unknown_keys + ks = @all_attributes.keys + # sort reverse so that language keys are inserted into Requirement::SYNTAX in alphabetical order + @data.keys.sort.reverse.each do |k| + if /\A(text_|verification_criteria_|comment_)./ === k + unless @all_attributes.include?(k) + reference_key = k.gsub(/(text|verification_criteria|comment).*/, '\\1') + reference_settings = @all_attributes[reference_key] + # rebuild the hash to change the iteration order for later processing like formatting + tmp = @all_attributes.dup + @all_attributes.clear + tmp.each do |key, value| + @all_attributes[key] = value + next unless key == reference_key + + @all_attributes[k] = { + check: nil, + new: '', + default: '', + allowed: nil, + format_style: reference_settings[:format_style], + format_shift: reference_settings[:format_shift] + } + end + loader.requirements.each { |_id, r| r.data[k] = '' } + Dim::Requirement.define_method(k) do + @data[k] + end + end + next + end + + Dim::ExitHelper.exit(code: 1, filename: filename, msg: "attribute #{k} not allowed") unless ks.include?(k) + end + end + + def check_invalid_values + @data.each do |k, v| + if @all_attributes.key?(k) && (@all_attributes[k][:check]) + send(@all_attributes[k][:check], @all_attributes[k], k, v) + end + end + end + + def merge_test_setups_and_verification_methods + # Given verification_methods is empty + # Given test_setups contains None + # Then return None + ts = @data['test_setups']&.cleanArray || [] + vm = @data['verification_methods']&.cleanArray || [] + + return if vm.empty? && ts.empty? + + merged = ts.union(vm).join(', ') + @data['test_setups'] = merged + @data['verification_methods'] = merged + end + + def check_verification_methods + vm = @data['verification_methods']&.cleanArray || [] + return unless vm.include?('none') && vm.length > 1 + + vm.delete('none') + Dim::ExitHelper.exit(code: 1, + filename: filename, + msg: "verification_methods or test_setups for \"#{@id}\" can't include 'none' along with #{vm.join(', ')}.") + end + end +end diff --git a/dim/lib/dim/ver.rb b/dim/lib/dim/ver.rb new file mode 100644 index 0000000..a50353f --- /dev/null +++ b/dim/lib/dim/ver.rb @@ -0,0 +1,7 @@ +module Dim + class Ver + def self.sion + File.read(File.dirname(__FILE__) + '/../../version.txt').strip + end + end +end diff --git a/dim/license.txt b/dim/license.txt new file mode 100644 index 0000000..f50046f --- /dev/null +++ b/dim/license.txt @@ -0,0 +1,205 @@ +Code and documentation Copyright (C) 2024 Accenture. +Code released under the Apache v2 License: + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/dim/req/config.dim b/dim/req/config.dim new file mode 100644 index 0000000..5084cd7 --- /dev/null +++ b/dim/req/config.dim @@ -0,0 +1,7 @@ +Config: + - files: dim.dim + originator: Accenture + disable_naming_convention_check: yes + category: software + +Properties: properties.yaml diff --git a/dim/req/dim.dim b/dim/req/dim.dim new file mode 100644 index 0000000..26849bf --- /dev/null +++ b/dim/req/dim.dim @@ -0,0 +1,1046 @@ +document: Dim + +Dim_CLI_heading: h1 Command Line Interface + +Dim_CLI_info: h2 Information + +Dim_CLI_help: + text: Dim shall provide a command line switch to print the command line usage. + tags: tool, covered, tested + status: valid + sources: lib/dim/options.rb + +Dim_CLI_license: + text: Dim shall provide a command line switch to print the license. + tags: tool, covered, tested + status: valid + sources: lib/dim/options.rb + +Dim_CLI_version: + text: Dim shall provide a command line switch to print the version. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/ver.rb + +Dim_CLI_errors: h2 Errors + +Dim_CLI_exit: + text: On any invalid or missing command line arguments, Dim shall print a meaningful error message + and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/options.rb + +Dim_Syntax_heading: h1 Syntax + +Dim_Syntax_overview: + type: information + text: The following chapter describes each attribute of the different file types. For a complete + overview with additional information please refer to the user documentation. + status: valid + +Dim_Syntax_YAML: + text: All input files shall be in YAML format. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_Syntax_InvalidChars: + text: Invalid characters (according to YAML standard) and in addition non-breaking spaces in + requirements files shall be exchanged on-the-fly during loading by a YAML compatible + replacement. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_Syntax_Values: + text: All literal values (not arrays or hashes) shall be interpreted as strings even if they would + be integers or booleans in standard YAML syntax, e.g. 123 shall be interpreted as "123". + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/psych.rb + +Dim_Syntax_utf8: + text: All files shall be compatible to UTF-8. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ReqFiles_heading: h2 Requirements Files + +Dim_ReqFiles_document: + text: | + A requirements file shall have a "document" name attribute. + Allowed values: any non-unique, non-empty string. The same name shall be usable in different files. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_MissingDocument: + text: If the document name is missing in the requirements file, an error shall be raised. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ReqFiles_enclosed: + text: | + A requirements file shall have an optional "enclosed" attribute which specifies files which are needed for the requirements, e.g. images. + Allowed values: a string or an array of strings. The strings must point to existing files and specified with relative paths without "..". + Default value: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_metadata: + text: | + A requirements file shall have an optional "metadata" attribute which consists of any user specific string, e.g. the origin of the requirements document, history or version. + Allowed values: any string + Default value: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_id: + text: | + A requirements file shall have zero or more requirements objects. These objects shall have strings as ID. + Allowed values for IDs: any string without the letter "," + Default value for IDs: n/a, must be specified explicitly + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_regularHeading: h3 Regular Form + +Dim_ReqFiles_regularYaml: + text: In the regular form, the ID shall be a key of a collection of key/values pairs of strings. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_type: + text: | + A requirements object shall have an optional "type" attribute. + Allowed values: "requirement", "information" and "heading_0" to "heading_100" + Default: "requirement" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_text: + text: | + A requirements object shall have an optional "text" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_verificationCriteria: + text: | + A requirements object shall have an optional "verification_criteria" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_feature: + text: | + A requirements object shall have an optional "feature" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_changeRequest: + text: | + A requirements object shall have an optional "change_request" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_tags: + text: | + A requirements object shall have an optional "tags" attribute. + Allowed values: comma separated list of strings + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_asil: + text: | + A requirements object shall have an optional "asil" attribute. + Allowed values: "not_set", "QM", "QM(A)", ... , "ASIL_D(D)" + Default: "not_set" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + refs: Dim_PropFiles_Property + +Dim_ReqFiles_calString: + text: | + A requirements object shall have an optional "cal" attribute. + Allowed values: "QM", "CAL_1", "CAL_2", "CAL_3", "CAL_4" + Default: "not_set" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + refs: Dim_PropFiles_Property + +Dim_ReqFiles_developer: + text: | + A requirements object shall have an optional "developer" attribute. + Allowed values: any string, + Default resolution: + - originator from the config file, if + - type is "requirement" and + - category is neither "input" nor "unspecified" + - "" otherwise + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_ReqFiles_tester: + text: | + A requirements object shall have an optional "tester" attribute. + Allowed values: any string + Default resolution: if + - originator from the config file if + - type is "requirement" and + - "process" is not in tags and + - category is neither "input" nor "unspecified" + - "" otherwise + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_ReqFiles_testSetups: + text: | + A requirements object shall have an optional "test_setups" attribute. + Allowed values: one or more of "none", "off_target", "on_target", "manual" + If test_setups is missing, it is resolved to: + - "none" if + - type is not "requirement" or + - "process" is in tags or + - category is "input" or "unspecified" + - "off_target" if + - category is "module" or + - tags include "tool" + - "on_target" otherwise + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_ReqFiles_verificationMethods: + text: | + A requirement object shall have an optional 'verification_methods' attribute. + Allowed values: one or more of "none", "off_target", "on_target", "manual" + If verification_methods is missing, it is resolved to: + - "none" if + - type is not "requirement" or + - "process" is in tags or + - category is "input" or "unspecified" + - "off_target" if + - category is "module" or + - tags include "tool" + - "on_target" otherwise + tags: tool, covered, tested + status: valid + sources: lib/dim/requirement.rb lib/dim/loader.rb lib/dim/consistency.rb + +Dim_ReqFiles_verificationMethods_backward: + text: | + "verification_methods" replaces "test_setups". + For backward compatibility, the requirements file can include both "test_setups" and "verification_methods". + During loading, Dim shall merge values from both attributes. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirement.rb lib/dim/consistency.rb lib/dim/loader.rb + +Dim_ReqFiles_status: + text: | + A requirements object shall have an optional "status" attribute. + Allowed values: one of "valid", "draft", "invalid" + If status is missing, it is resolved to: + - "draft" if type is "requirement" or "information" + - "valid" otherwise + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_ReqFiles_reviewStatus: + text: | + A requirements object shall have an optional "review_status" attribute. + Allowed values: one of "accepted", "unclear", "rejected", "not_reviewed", "not_relevant" + If review_status is missing, it is resolved to: + - "not_reviewed" if category is "input" or "unspecified" + - "accepted" otherwise + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_ReqFiles_comment: + text: | + A requirements object shall have an optional "comment" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_miscellaneous: + text: | + A requirements object shall have an optional "miscellaneous" attribute. + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_sources: + text: | + A requirements object shall have an optional "sources" attribute. + Allowed values: comma separated string list + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_refs: + text: | + A requirements object shall have an optional "refs" attribute. + Allowed values: a string with comma separated IDs, which must exist. + A requirement object is also allowed to have reference within + different categories and circular dependency can only occur in the + same category level. + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_language: + text: | + A requirements object shall have an optional language attributes for "text", "verification_criteria" and "comment". + The naming scheme of these attributes shall be "_", e.g. "text_german". + Allowed values: any string + Default: "" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_shortHeading: h3 Short Form + +Dim_ReqFiles_shortYaml: + text: In the short form, the ID shall be the key of a key/value pair of strings. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_shortHeadingForm: + text: If a requirement object has a heading type and only text, it shall be writable in one line + for convenience. The value shall include the heading level and the heading text. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ReqFiles_shortInfoForm: + text: If a requirement object has type "information" and only text, it shall be writable in one + line for convenience. The value shall include the information type and the text. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirement.rb, + lib/dim/loader.rb + +Dim_ConfigFiles_heading: h2 Config Files + +Dim_ConfigFiles_Config: + text: A config file shall have exactly one "Config" attribute which consists of an array of config + entries. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_Files: + text: | + A config entry shall have exactly one "files" entry. + Allowed values: a string or an array of strings of requirements files. The files must be specified with relative paths but without "..". Ruby glob pattern are allowed, e.g. "**", "*" and "?". + If a filename is specified more than once, an error shall be thrown. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_Originator: + text: | + A config entry shall have exactly one "originator" entry. + Allowed values: any non-empty string + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_Category: + text: | + A config entry shall have exactly one "category" entry. + Allowed values: one of "input", "software", "architecture", "module", "system" + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_Property: + text: | + A config file shall have an optional "Property" attribute. + Allowed values: a string which points to an existing properties file. + Default: "" + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_Attribute: + text: | + A config file shall have an optional "Attributes" field. + Allowed values: a string which points to an existing attribute file. + Default: "" + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_disableNameCheck: + text: | + A config file shall have an optional "disable_naming_convention_check" field a config entry. + Allowed values: "yes" and "no" + Default: "no" + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_ConfigFiles_SRS: + text: If the category for a config entry is "software" and "disable_naming_convention_check" value + is not set to "yes", Dim shall check for ID naming conventions. An ID must start with "SRS_" + and must be named in SRS__ fashion including the two underscores. The + document name must start with "SRS_" and must be named in SRS_ fashion including + the underscore. and must be non empty strings with only alphanumeric + characters along with hyphen allowed. If this naming convention is not met, Dim shall throw + a meaningful error message and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_PropFiles_heading: h2 Properties File + +Dim_PropFiles_Property: + text: | + A properties file shall define default values for attributes of requirement elements which are not explicitly set. + The values shall be structured in the properties file using the document name as a key, and the attributes with their respective default values, like this: + "document {'status': 'valid', 'asil': 'ASIL_B', 'text': 'default text'}" + tags: tool, covered, tested + status: valid + sources: > + lib/dim/loader.rb, + lib/dim/consistency.rb + +Dim_AttrFiles_CmdParam: + text: Dim shall be able to accept the attributes file using a command line argument. If the config + file includes the reference to custom attributes and another attributes file is loaded using + command line argument, then Dim shall load the attributes from both files for processing + requirements. In case these attribute files contains duplicate attributes, then attributes + referenced from the config file shall be given priority. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_AttributeLoading_UnitTests: + text: When the attributes file is referenced in Config file or passed using the command line + argument, Dim shall validate the configuration for custom attributes and load them for + processing the requirements. + tags: tool, covered, tested + status: valid + sources: lib/dim/helpers/attributes_helper.rb + +Dim_AttrFiles_Attribute: + text: | + An attributes file shall accept custom attributes for Dim. + The values shall be structured in the attributes file using the attribute name as a key, and the values for those attributes, like this: + "color: {type: single, default: red, allowed: [red, green]}" + type - defines the format type how the attribute is interpreted and exported to RST + default - specifies the default value + allowed - specifies list of allowed values + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_AttrFiles_SearchAttributeFile: + text: If a single requirements file is loaded, then Dim shall automatically search + for "attributes.dim" file recursively in parent directory till root directory is reached. + This does not apply if a config file is loaded instead of single requirements file. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_loading_heading: h1 Loading Files + +Dim_loading_readHeading: h2 Reading Data + +Dim_loading_readGood: + text: Dim shall read the files specified on command line and in the config file. The data shall be + made available to subcommands. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_loading_enclosedCheck: + text: Dim shall skip the enclosed file check when "--no-check-enclosed" flag is passed. + tags: tool, covered, tested + status: valid + sources: /lib/dim/loader.rb + +Dim_loading_readBad: + text: If any error occurs during loading the config, property or requirements files, Dim shall + print a meaningful error message and exit with exit code != 0. Errors can occur due to file + access issues like missing files or the files have invalid syntax. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/loader.rb, + lib/dim/ext/psych.rb + +Dim_loading_checkHeading: h2 Consistency Checks + +Dim_loading_checkCyclic: + text: Requirements can reference other requirements which can reference again other requirements + in same category level. In case of a cyclic reference, Dim shall print a meaningful error + message and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/consistency.rb + +Dim_loading_checkMissing: + text: If a reference cannot be resolved, which means the ID does not exist, Dim shall print a + meaningful error message and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/consistency.rb + +Dim_loading_checkMissingDisable: + text: The command line interface of Dim shall provide an option to disable this + unresolved-references-check, which means Dim shall neither complain about missing references + nor exit Dim. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/consistency.rb + +Dim_loading_checkDocument: + text: If several files share the same document name, the originator and the category must be the + same for all of these files. If not, Dim shall print a meaningful error message and exit + with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_loading_document: + text: Dim shall support "module" as alias for "document". If "module" is specified, "document" + shall be set to the value of "module". If both are specified, an error shall be raised. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/export.rb + +Dim_loading_checkMetadata: + text: If several files share the same document name, "metadata" must not be defined more than + once. Otherwise Dim shall print a meaningful error message and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_loading_checkID: + text: Requirement IDs shall be unique over all files. If the same ID is used for more than one + requirement, Dim shall print a meaningful error message and exit with exit code != 0. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/psych.rb + +Dim_subcommands_heading: h1 Subcommands + +Dim_check_heading: h2 check + +Dim_check_General: + text: The command line interface of Dim shall provide a "check" subcommand which loads the input + files and executes consistency checks. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/check.rb + +Dim_stats_heading: h2 stats + +Dim_stats_General: + text: The command line interface of Dim shall provide a "stats" subcommand which prints basic + metrics to the console. The metrics shall be printed for every loaded document and a summary + over all documents. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/stats.rb + +Dim_stats_Details: + text: | + The metrics shall include at least: + - Number of total elements + - Number of requirements + - Number of valid requirements split by review status + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/stats.rb + +Dim_format_heading: h2 format + +Dim_format_general: + text: The command line interface of Dim shall provide a "format" subcommand which formats the + loaded requirements files. Missing references are allowed by default while formatting. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_whitespaces: + text: The formatter shall adapt the whitespaces in a predefined style. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_order: + text: The formatter shall arrange the attributes in a predefined order. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_form: + text: The formatter shall change requirements from regular to short form if possible. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_default: + text: The formatter shall not remove any attributes, even if the default value is specified. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_duplicated: + text: The formatter shall remove duplicate values in "tags", "verification_methods", "sources" + and "refs". + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/format.rb + +Dim_format_inPlace: + text: By default, the formatter shall change the files in-place. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/requirements.rb, + lib/dim/commands/format.rb + +Dim_format_checkOnly: + text: It shall be possible to only check the formatting without changing the files. In case of + incorrect formatting, an error message shall be printed and Dim shall exit with an exit + code != 0. Different line endings like CRLF and LF shall be ignored. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/format.rb + +Dim_format_extra: + text: It shall be possible to write the formatted data to extra files and not overwrite the + original files. This makes it easier to use third-party compare-tools. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/format.rb + +Dim_format_vim: + text: It shall be possible to read the input from STDIN and to print the formatted output to the + STDOUT. This functionality supports auto-formatting in text editors like Vim. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/format.rb + +Dim_format_verificationMethods: + text: The Dim formatter shall remove the "test_setups" attribute from formatted file and keep + only 'verification_methods'. + tags: tool, covered, tested + status: valid + sources: lib/dim/options.rb lib/dim/commands/format.rb + +Dim_export_heading: h2 export + +Dim_export_general: + text: The command line interface of Dim shall provide an "export" subcommand which exports the + requirements data to other file formats. It shall be possible to specify the output folder. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/export.rb + +Dim_export_documents: + text: Within the output folder, a new folder for every document shall be created with a + requirements file named "/Requirements.", e.g. "myModule/Requirements.json". + The document name shall be sanitized, e.g. "/" shall be converted to "_" to avoid invalid + folder names. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/export.rb + +Dim_export_enclosed: + text: Files specified in the enclosed attributes shall be copied to the appropriate document's + output folder. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/export.rb + +Dim_export_filter: + text: It shall be possible to filter requirements for exports based on their attributes, e.g. that + only input and software requirements are exported. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/commands/export.rb + +Dim_export_cleanup: + text: After exporting is complete, files from exported folder which are no longer referenced in + the exported folder shall be cleaned up. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/export.rb + +Dim_export_verificationMethods: + text: Exported requirements file shall contain "verification_methods" and not "test_setups". + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/export.rb + +Dim_export_jsonHeading: h3 JSON + +Dim_export_json: + text: JSON exports shall have all requirement attributes as key/value pairs plus ID, document name + and originator. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/json.rb + +Dim_export_csvHeading: h3 CSV + +Dim_export_csvSep: + text: CSV exports shall have "Sep=," in the first line to specify the separator character. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/csv.rb + +Dim_export_csvAttributes: + text: CSV exports shall have all requirement attributes plus ID, document name and originator in + the second line. The following lines shall consist of the values of the requirements + according to the attribute names defined in the second line. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/csv.rb + +Dim_export_csvValues: + text: All values shall be wrapped by double quotes. Double quotes in the values shall be escaped. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/csv.rb + +Dim_export_rstHeading: h3 RST + +Dim_export_rst: + text: RST exports shall export the data according to the Sphinx dox_trace extension syntax. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/rst.rb + +Dim_export_rstStrings: + text: In the RST export, literals like "text" or "verification_criteria" shall be exported as + Sphinx raw-html elements to avoid invalid RST files. This means special characters like "<" + or "\n" must be escaped or converted. It shall be possible to mark substrings explicitly to + skip this conversion. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/rst.rb + +Dim_export_rstChange: + text: Existing RST files shall only be overwritten if data has been changed to keep the time stamp + of the files. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/rst.rb + +Dim_export_rstIndex: + text: Additionally to the requirements files, the RST exporter shall create index files for each + originator/category pair to be directly used by Sphinx. + tags: tool, covered, tested + status: valid + sources: lib/dim/commands/exporter/rst.rb + +Dim_format_customAttributes: + text: Before formatting requirements files with custom attributes, Dim shall load the attributes + file first. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/options.rb, + lib/dim/loader.rb, + lib/dim/commands/format.rb + +Dim_api_heading: h1 Ruby API + +Dim_api_readingHeading: h2 Reading + +Dim_api_reading: + text: It shall be possible to load files by using the Dim Ruby API directly. A data structure + shall be provided with resolved default values if the values are not provided explicitly in + the requirements files. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_api_headingConvenience: h3 Convenience Methods for Requirements + +Dim_api_safetyRelevant: + text: A requirements object shall provide a method "safety_relevant?" which returns true if "asil" + is not set to "QM" or "not_set", otherwise false. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_securityRelevant: + text: A requirements object shall provide a method "security_relevant?" which returns true + if "cal" is set to "CAL_4", otherwise false. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_additionalGettersHeading: h3 Additional Getters + +Dim_api_documentName: + text: A requirement shall have a getter for the document name. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_originator: + text: A requirement shall have a getter for the originator. The value shall be taken from the + config file. If a requirements file was loaded directly without a config file, the + originator shall be "". + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_category: + text: A requirement shall have a getter for the category. The value shall be taken from the config + file. If a requirements file was loaded directly without a config file, the category shall + be "unspecified". + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_filename: + text: A requirement shall have a getter for the filename. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_lineNumber: + text: A requirement shall have a getter for the line number. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_backwardRefs: + text: A requirement shall have a getter for the backward references which are calculated + automatically by Dim. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + +Dim_api_existingRefs: + text: A requirement shall have a getter for the existing references. When loading with disabled + missing-reference-check, the list can be shorter than the original list in refs attribute. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirements.rb + refs: Dim_loading_checkMissingDisable + +Dim_api_upstreamRefs: + text: A requirement shall have a getter for upstream references, which means a list of IDs from + refs to higher category level plus backward-refs from higher or same category level IDs. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirement.rb lib/dim/loader.rb lib/dim/consistency.rb + +Dim_api_downstreamRefs: + text: A requirement shall have a getter for downstream references, which means a list of IDs from + refs to lower or same category level plus backward-refs from lower category level IDs. + tags: tool, covered, tested + status: valid + sources: lib/dim/requirement.rb lib/dim/loader.rb lib/dim/consistency.rb + +Dim_api_metadata: + text: The metadata of the documents shall be available via the API. + tags: tool, covered, tested + status: valid + sources: lib/dim/loader.rb + +Dim_api_convenienceStringHeading: h3 Convenience Methods for Attributes With Comma Separated Values + +Dim_api_stringCleanSplit: + text: Dim shall extend the String class with a "cleanSplit" method which returns an array of the + elements without leading and trailing whitespaces. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringCleanArray: + text: Dim shall extend the String class with a "cleanArray" method which returns the same + as "cleanSplit" but same as cleanSplit, but without empty elements. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringCleanUniqArray: + text: Dim shall extend the String class with a "cleanUniqArray" method which returns the same + as "cleanArray" but also removes duplicates. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringCleanString: + text: Dim shall extend the String class with a "cleanString" method which returns a string without + empty elements, leading and trailing whitespaces. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringCleanUniqString: + text: Dim shall extend the String class with a "cleanUniqString" method which returns the same + as "cleanString" but also removes duplicates. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringAddEnum: + text: Dim shall extend the String class with an "addEnum" method which add an enum to the string, + makes the enums unique and returns the result. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_stringRemoveEnum: + text: Dim shall extend the String class with a "removeEnum" method which removes all enums from + the string and returns the result. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/string.rb + +Dim_api_writingHeading: h2 Writing + +Dim_api_changing: + text: It shall be possible to change requirements files by using the Dim Ruby API directly. A data + structure shall be provided without resolved default values to be able to work on the + original data. It shall be possible to write the changed data back to the file system. + tags: tool, covered, tested + status: valid + sources: > + lib/dim/loader.rb, + lib/dim/requirements.rb, + lib/dim/formatter.rb + +Dim_testing_heading: h1 Testing Requirements + +Dim_testing_output: + text: To ease testing, it shall be possible to read the command line output of Dim in unit tests + when calling functions directly. This means stdout and stderr need to be redirected through + string streams. + tags: tool, covered, tested + status: valid + sources: lib/dim/ext/output.rb diff --git a/dim/req/properties.yaml b/dim/req/properties.yaml new file mode 100644 index 0000000..ffe02d1 --- /dev/null +++ b/dim/req/properties.yaml @@ -0,0 +1,3 @@ +Dim: + asil: "QM" + cal: "QM" diff --git a/dim/spec/api_spec.rb b/dim/spec/api_spec.rb new file mode 100644 index 0000000..96957a9 --- /dev/null +++ b/dim/spec/api_spec.rb @@ -0,0 +1,211 @@ +require_relative 'framework/helper' + +module Dim + describe 'Dim API' do + before { loader.load(file: filepath, allow_missing: allow_missing) } + + let(:loader) { Dim::Loader.new } + let(:allow_missing) { false } + let(:filepath) { "#{TEST_INPUT_DIR}/resolved_function_temp/config.dim" } + + context 'in general shall' do + FileUtils.rm_rf("#{TEST_INPUT_DIR}/resolved_function_temp") + FileUtils.cp_r("#{TEST_INPUT_DIR}/resolved_function", "#{TEST_INPUT_DIR}/resolved_function_temp") + let(:filepath) { "#{TEST_INPUT_DIR}/resolved_function_temp/config.dim" } + + it 'provide access to resolved attributes', doc_refs: ['Dim_api_reading'] do + req = loader.requirements['RESOLVE_003'] + expect(req.verification_methods).to match_array(['none']) + end + + it 'provide access to original attributes', doc_refs: ['Dim_api_changing'] do + req = loader.original_data["#{TEST_INPUT_DIR}/resolved_function_temp/modules/Module1.dim"]['RESOLVE_003'] + expect(req['verification_methods']).to be nil + end + + it 'provide functionality to write data back to requirements files', doc_refs: ['Dim_api_changing'] do + req = loader.original_data["#{TEST_INPUT_DIR}/resolved_function_temp/modules/Module1.dim"]['RESOLVE_003'] + req['verification_methods'] = 'manual' + req['comment'] = '' + formatter2 = Dim::Format.new(loader) + formatter2.execute + loader2 = Dim::Loader.new + loader2.load(file: "#{TEST_INPUT_DIR}/resolved_function_temp/config.dim") + req2 = loader2.requirements['RESOLVE_003'] + expect(req2.verification_methods).to match_array('manual') + expect(req2.comment).to eq '' + end + end + + context 'shall provide convenience method' do + # let(:filepath) { "#{TEST_INPUT_DIR}/convenience/module_ok.dim" } + + context 'safety and cal relevant' do + let(:filepath) { "#{TEST_INPUT_DIR}/relevant/module_ok.dim" } + + it 'safety_relevant?', doc_refs: ['Dim_api_safetyRelevant'] do + loader.requirements.each do |id, r| + expect(r.safety_relevant?).to be id.include?('safe') + end + end + + it 'security_relevant?', doc_refs: ['Dim_api_securityRelevant'] do + loader.requirements.each do |id, r| + expect(r.security_relevant?).to be id.include?('cal') + end + end + end + end + + context 'shall provide getter method' do + before { loader_config.load(file: "#{TEST_INPUT_DIR}/resolved_function/config.dim") } + + let(:allow_missing) { true } + let(:filepath) { "#{TEST_INPUT_DIR}/resolved_function/modules/Module1.dim" } + let(:first_req) { loader.requirements['RESOLVE_001'] } + let(:third_req) { loader.requirements['RESOLVE_003'] } + let(:loader_config) { Dim::Loader.new } + let(:first_req_config) { loader_config.requirements[first_req.id] } + let(:line_number) { Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.4') ? 3 : nil } + + it 'document name', doc_refs: ['Dim_api_documentName'] do + expect(first_req.category).to eql('unspecified') + end + + it 'origin, loaded directly', doc_refs: ['Dim_api_originator'] do + expect(first_req.origin).to eql('') + end + + it 'origin, loaded via config file', doc_refs: ['Dim_api_originator'] do + expect(first_req_config.origin).to eql('Customer') + end + + it 'existingRefs', doc_refs: ['Dim_api_existingRefs'] do + expect(first_req.existingRefs).to eq ['RESOLVE_003'] + end + + it 'category, loaded directly', doc_refs: ['Dim_api_category'] do + expect(first_req.category).to eql('unspecified') + end + + it 'category, loaded via config file', doc_refs: ['Dim_api_category'] do + expect(first_req_config.category).to eql('input') + end + + it 'filename', doc_refs: ['Dim_api_filename'] do + expect(first_req.filename).to eql('spec/test_input/resolved_function/modules/Module1.dim') + end + + it 'line_number', doc_refs: ['Dim_api_lineNumber'] do + expect(first_req.line_number).to eq line_number + end + + it 'backwardRefs', doc_refs: ['Dim_api_backwardRefs'] do + expect(third_req.backwardRefs).to eq ['RESOLVE_001'] + end + end + + context 'shall provide convenient string method' do + it 'cleanSplit', doc_refs: ['Dim_api_stringCleanSplit'] do + expect('a,a,b ,, c'.cleanSplit).to eq ['a', 'a', 'b', '', 'c'] + expect(''.cleanSplit).to eq [] + end + + it 'cleanArray', doc_refs: ['Dim_api_stringCleanArray'] do + expect('a,a,b ,, c'.cleanArray).to eq %w[a a b c] + expect(''.cleanArray).to eq [] + end + + it 'cleanUniqArray', doc_refs: ['Dim_api_stringCleanUniqArray'] do + expect('a,a,b ,, c'.cleanUniqArray).to eq %w[a b c] + expect(''.cleanUniqArray).to eq [] + end + + it 'cleanString', doc_refs: ['Dim_api_stringCleanString'] do + expect('a,a,b ,, c'.cleanString).to eq('a, a, b, c') + expect(''.cleanString).to eq('') + end + + it 'cleanUniqString', doc_refs: ['Dim_api_stringCleanUniqString'] do + expect('a,a,b ,, c'.cleanUniqString).to eq('a, b, c') + expect(''.cleanUniqString).to eq('') + end + + it 'addEnum', doc_refs: ['Dim_api_stringAddEnum'] do + expect('REFS_R1, REFS_R2'.addEnum('xy')).to eq('REFS_R1, REFS_R2, xy') + expect('REFS_R1, REFS_R2, xy'.addEnum('REFS_R1')).to eq('REFS_R1, REFS_R2, xy') + expect(''.addEnum('abc')).to eq('abc') + end + + it 'removeEnum', doc_refs: ['Dim_api_stringRemoveEnum'] do + expect('REFS_R1, REFS_R2, xy'.removeEnum('REFS_R1')).to eq('REFS_R2, xy') + expect('REFS_R2, xy'.removeEnum('xy').removeEnum('xy')).to eq('REFS_R2') + expect('REFS_R2'.removeEnum('REFS_R2').removeEnum('REFS_R2')).to eq('') + end + end + + context 'access to non-existing attribute', doc_refs: ['Dim_api_reading'] do + let(:filepath) { "#{TEST_INPUT_DIR}/language/module_ok.dim" } + + it 'shall abort and print a meaningful error message' do + expect { loader.requirements['ESR_Test_1'].doesNotExist }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'Error: "doesNotExist" is not a requirement attribute' + end + end + + context 'shall provide a loading-function,' do + it 'which loads the file when arguments are valid', doc_refs: ['Dim_api_reading'] do + # array length 1, string argument not used + loader = Dim::Loader.new + loader.load(input_filenames: ["#{TEST_INPUT_DIR}/reqs/text/default.dim"], silent: false) + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Loading [unknown] spec/test_input/reqs/text/default.dim...' + + # array argument has string type, string argument not used + loader = Dim::Loader.new + loader.load(input_filenames: "#{TEST_INPUT_DIR}/reqs/text/default.dim", silent: false) + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Loading [unknown] spec/test_input/reqs/text/default.dim...' + + # array is empty, string argument used + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text/default.dim", silent: false) + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Loading [unknown] spec/test_input/reqs/text/default.dim...' + end + + it 'which throws an error with a meaningful error message if arguments are invalid', + doc_refs: ['Dim_api_reading'] do + # both arguments are used at the same time + loader = Dim::Loader.new + expect { loader.load(file: 'abc', input_filenames: 'abc') }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'use either file or input_filenames argument (deprecated) for load method' + + # no argument used + loader = Dim::Loader.new + expect { loader.load }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'neither file nor input_filenames argument (deprecated) ' \ + 'argument specified for load method' + + # array length > 1 + loader = Dim::Loader.new + expect { loader.load(input_filenames: %w[abc def]) }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'input_filenames argument (deprecated) of load method must have at maximum one entry' + end + end + + context 'shall provide the metadata of the modules,' do + let(:filepath) { "#{TEST_INPUT_DIR}/metadata/meta.dim" } + let(:r) { loader.requirements['SRS_X_Y'] } + + it 'as key/value pair', doc_refs: ['Dim_api_metadata'] do + expect(loader.metadata[r.document]).to eq('Test Meta') + expect(loader.original_data[r.filename]['metadata']).to eq('Test Meta') + end + end + end +end diff --git a/dim/spec/attribute_helper_spec.rb b/dim/spec/attribute_helper_spec.rb new file mode 100644 index 0000000..ca97166 --- /dev/null +++ b/dim/spec/attribute_helper_spec.rb @@ -0,0 +1,287 @@ +require 'framework/helper' + +RSpec.describe 'Dim::Helpers::AttributeHelper' do + let(:dummy_class) { Class.new { include Dim::Helpers::AttributeHelper }.new } + + describe '#change_type_to_format_style' do + subject { dummy_class.change_type_to_format_style(config) } + + context "when 'type' is given in the config" do + let(:config) { { type: 'single' } } + + it "replaces 'type' key in the config with the 'format_style' with value", + doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(subject).to eq('single') + expect(config[:format_style]).to eq('single') + expect(config[:type]).to be nil + expect(config.keys).to eq([:format_style]) + end + end + + context "when 'type' is not given" do + let(:config) { { format_shift: 0 } } + + it "returns nil and changes 'type' key to 'format_style'", doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(subject).to be nil + expect(config[:format_style]).to be nil + expect(config[:type]).to be nil + expect(config.keys).to match_array(%i[format_shift format_style]) + end + end + end + + describe '#check_for_default_attributes' do + let(:filename) { 'attributes.dim' } + + context 'when attributes.dim does not redefine default attributes' do + let(:attributes) { { 'cluster' => { format_style: :text, default: '', format_shift: 0 } } } + + it 'returns nil without returning nil', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.check_for_default_attributes(attributes, filename)).to be nil + end + end + + context 'when attributes.dim redefines the default attributes' do + let(:attributes) { { 'type' => { format_style: :text, default: '', format_shift: 0 } } } + let(:err_msg) { "Error: Defining standard attributes as a custom attributes is not allowed" } + + it 'exits process with error message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.check_for_default_attributes(attributes, filename) } + + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include(err_msg) + end + end + end + + describe '#validate_format_style' do + context "when format_style in the config is 'list', 'multi', 'single', 'split' or 'text" do + let(:config) { { format_style: %w[list multi single split text].sample } } + + it 'returns nil without any error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.validate_format_style('custom_attribute', config)).to be nil + end + end + + context 'when format_style is other than valid attribute' do + let(:config) { { format_style: [1, 0.5, nil, true, 'singular', 'multiple'].sample } } + + it 'exits with the error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_format_style('custom_attribute', config) } + + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include('Error: Invalid') + end + end + end + + describe '#add_check_value' do + subject { dummy_class.add_check_value(config) } + + context "when 'format_style' is 'single'" do + let(:config) { { format_style: 'single' } } + + it 'adds check in the config', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + subject + expect(config[:check]).to eq :check_single_enum + end + end + + context "when 'format_style' if 'multi'" do + let(:config) { { format_style: 'multi' } } + + it 'adds check in the config', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + subject + expect(config[:check]).to eq :check_multi_enum + end + end + + context "when 'format_style' is other than 'single' or 'multi'" do + let(:config) { { format_style: %w[list text split].sample } } + + it 'does not set check in the config', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + subject + expect(config[:check]).to be nil + end + end + end + + describe '#validate_default' do + context "when default value is not set to 'auto'" do + let(:config) { { default: ['', 'new'].sample } } + + it 'returns nil without raising an exception', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.validate_default('default', config)).to be nil + end + end + + context "when default value is set to 'auto'" do + let(:config) { { default: 'auto' } } + + it 'exits process with error message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_default('default', config) } + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: Invalid") + end + end + end + + describe '#validate_default_for_enum' do + subject { dummy_class.validate_default_for_enum('default', config) } + + context "when 'format-_style' is not 'single' or 'multi'" do + let(:config) { { format_style: %w[text list split].sample } } + + it 'returns nil', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(subject).to be nil + end + end + + context "when 'format_style' is 'single' or 'multi'" do + let(:config) { { format_style: %w[single multi].sample, allowed: %w[green blue red yellow] } } + + context "when default value is present in list of 'allowed' values provided" do + before { config[:default] = 'green' } + + it 'returns nil without raising any error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(subject).to be nil + end + end + + context "when default value is not present in the list of 'allowed' values provided" do + before { config[:default] = 'black' } + + it 'exits process with a meaningful message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_default_for_enum('default', config) } + + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include("Error: default value for default must be from allowed list") + end + end + end + end + + describe '#validate_allowed' do + context "when allowed is set to 'nil' or an array" do + let(:config) { { allowed: [nil, [1, 2]].sample } } + + it 'returns nil without raising an error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.validate_allowed('custom_attribute', config)).to be nil + end + end + + context "when allowed value is other than 'nil' or array" do + let(:config) { { allowed: [1, 2, 'test'].sample } } + + it 'exits with raising error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_allowed('custom_attribute', config) } + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('Error: Invalid') + end + end + end + + describe '#validate_allowed_for_enum' do + context 'when attribute is not of enum type' do + let(:config) { { format_style: %w[singular multiple].sample } } + + it 'returns nil without raising an error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.validate_allowed_for_enum('custom_attribute', config)).to be nil + end + end + + context 'when attribute is of enum type' do + let(:config) { { format_style: %w[single multi].sample } } + + context 'when array of string values is given as a allowed values' do + before { config[:allowed] = %w[true random] } + + it 'returns nil without raising an error', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(dummy_class.validate_allowed_for_enum('custom_attribute', config)).to be nil + end + end + + context 'when array is not give for allowed attributes' do + before { config[:allowed] = 'dummy_string' } + + it 'exits process with error message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_allowed_for_enum('custom_attribute', config) } + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('Error: Allowed value must be list of strings') + end + end + + context 'when array contains non string value' do + before { config[:allowed] = [true, 'false'] } + + it 'exits process with error message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute { dummy_class.validate_allowed_for_enum('custom_attribute', config) } + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('Error: Allowed value must be list of strings') + end + end + end + end + + describe '#symbolize_values' do + before(:each) { dummy_class.symbolize_values(config) } + + context 'changes format_style to symbol from string' do + context 'when format_style is present' do + let(:config) { { format_style: 'single' } } + + it 'converts string value to symbol', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(config[:format_style]).to eq :single + end + end + + context 'when format_style in missing' do + let(:config) { {} } + + it 'does not update the format_style', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(config[:format_style]).to be nil + end + end + end + + context 'changes format_shift from string to integer' do + context 'when format_shift is given by user' do + let(:config) { { format_shift: '10' } } + + it 'converts string to integer value', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(config[:format_shift]).to eq 10 + end + end + + context 'when format_shift is not given by user' do + let(:config) { {} } + + it 'sets default format_shift to 0', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + expect(config[:format_shift]).to eq 0 + end + end + end + end + + describe '#exit_with_error' do + let(:config) { 'check' } + let(:config_value) { 'invalid_value' } + let(:attribute) { 'custom_attribute' } + + it 'exits the process with error message', doc_refs: ['Dim_AttributeLoading_UnitTests'] do + Dim::Test.execute do + dummy_class.send( + :exit_with_error, + **{ config: config, config_value: config_value, attribute: attribute } + ) + end + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: Invalid value \"#{config_value}\" for #{config} detected for attribute #{attribute}") + end + end +end diff --git a/dim/spec/consistency_spec.rb b/dim/spec/consistency_spec.rb new file mode 100644 index 0000000..fb6bf58 --- /dev/null +++ b/dim/spec/consistency_spec.rb @@ -0,0 +1,94 @@ +require_relative 'framework/helper' + +module Dim + describe 'Consistency check' do + context 'when loading correct input files' do + it 'shall not lead to an error', doc_refs: ['Dim_check_General'] do + Test.main("check -i #{TEST_INPUT_DIR}/export_check/Config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'when loading a file which includes non-unique ids' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkID'] do + Test.main("check -i #{TEST_INPUT_DIR}/same_id_same_file/Config.yml") + expect(@test_stderr).to include('found "SameID" twice which must be unique') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'when loading different files which include non-unique ids' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkID'] do + Test.main("check -i #{TEST_INPUT_DIR}/same_id_different_files/Config.yml") + expect(@test_stderr).to include('Input2.yml: id "SameID" found more than once') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'when loading a single file which include requirements that are cyclically referenced' do + let(:filename) { "#{TEST_INPUT_DIR}/cyclic_reference_same_file/test_module_1.dim" } + + it 'shall throw an error and print the cyclic reference stack', doc_refs: ['Dim_loading_checkCyclic'] do + Test.main("check -i #{filename}") + expect(@test_stderr).to include("Error: in #{filename}: \"test_id_1\" is cyclically referenced") + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'when loading files which include requirements that are cyclically referenced through different files' do + let(:folder) { "#{TEST_INPUT_DIR}/cyclic_reference_different_modules" } + + it 'shall throw an error and print the cyclic reference stack', doc_refs: ['Dim_loading_checkCyclic'] do + Test.main("check -i #{folder}/config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: in #{folder}/test_module_1.dim: \"test_module_1-0000-0001\" is cyclically referenced: test_module_1-0000-0001 -> test_module_2-0000-0001 -> test_module_1-0000-0001") + end + end + + context 'when loading files which include requirements that have unresolved references with check subcommand but without --allow-missing' do + let(:filename) { "#{TEST_INPUT_DIR}/missing_refs/test_module_1.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkMissing'] do + Test.main("check -i #{filename}") + expect(@test_stderr).to include("Error: in #{filename}: \"test_id_3\" refers to non-existing \"non_exist\"") + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'when loading files which include requirements that have unresolved references with check subcommand and --allow-missing' do + it 'shall not lead to an error', doc_refs: ['Dim_loading_checkMissingDisable'] do + Test.main("check -i #{TEST_INPUT_DIR}/missing_refs/test_module_1.dim --allow_missing") + expect(@test_stderr).not_to include('Error: "test_id_3" refers to non-existing "non_exist"') + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'when loading files with same module but different category' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkDocument'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/same_module_different_category.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'Error: in spec/test_input/invalid_input/modules/valid_test_2.dim: files of the same module must have the same category:' + expect(@test_stderr).to include '- spec/test_input/invalid_input/modules/valid_test_1.dim (system)' + expect(@test_stderr).to include '- spec/test_input/invalid_input/modules/valid_test_2.dim (software)' + end + end + + context 'when loading files with same module but different owner' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkDocument'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/same_module_different_owner.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'Error: in spec/test_input/invalid_input/modules/valid_test_2.dim: files of the same module must have the same owner:' + expect(@test_stderr).to include '- spec/test_input/invalid_input/modules/valid_test_1.dim (ABC)' + expect(@test_stderr).to include '- spec/test_input/invalid_input/modules/valid_test_2.dim (DEF)' + end + end + + context 'when loading files with same module but multiple metadata' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_checkMetadata'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/duplicate_metadata.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'invalid_input/modules/duplicate_meta2.dim: only one metadata per module allowed' + end + end + end +end diff --git a/dim/spec/export_spec.rb b/dim/spec/export_spec.rb new file mode 100644 index 0000000..bd579ec --- /dev/null +++ b/dim/spec/export_spec.rb @@ -0,0 +1,388 @@ +require_relative 'framework/helper' + +module Dim + describe 'dim export' do + context 'in general' do + it 'shall write correct (language) attributes in the file format specified by command line option', + doc_refs: %w[Dim_export_general Dim_loading_readGood] do + Test.main("export -i #{TEST_INPUT_DIR}/language/module_ok.dim -o #{TEST_OUTPUT_DIR} -f json") + out_ref = File.read("#{TEST_INPUT_DIR}/language/output/Requirements.json").universal_newline + out_is = File.read("#{TEST_OUTPUT_DIR}/language/Requirements.json").universal_newline + expect(out_is).to eq(out_ref) + end + + it 'shall export to //Requirements.', doc_refs: ['Dim_export_documents'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR}/new_dir -f json") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(File.exist?("#{TEST_OUTPUT_DIR}/new_dir/test_module_1/Requirements.json")).to eq true + expect(File.exist?("#{TEST_OUTPUT_DIR}/new_dir/test_module_2/Requirements.json")).to eq true + end + + it 'shall merge a module which is split in several requirements files', doc_refs: ['Dim_export_documents'] do + Test.main("export -i #{TEST_INPUT_DIR}/one_module_in_several_files/Config.yml -o #{TEST_OUTPUT_DIR} -f json") + j = JSON.load(File.read("#{TEST_OUTPUT_DIR}/TestModule/Requirements.json")) + expect(j.length).to eq 2 # number of entries + expect(j.select { |e| e['document_name'] == 'TestModule' }.length).to eq 2 + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + it 'shall sanitize module names', doc_refs: ['Dim_export_documents'] do + Test.main("export -i #{TEST_INPUT_DIR}/slash_in_modname/test_module_1.dim -o #{TEST_OUTPUT_DIR} -f json --allow-missing") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(File.exist?("#{TEST_OUTPUT_DIR}/test_module/Requirements.json")).to eq true + end + + it 'shall copy enclosed files to the output folder', doc_refs: ['Dim_export_enclosed'] do + Test.main("export -i #{TEST_INPUT_DIR}/enclosed_check/test_module_1_1.dim -o #{TEST_OUTPUT_DIR} -f json") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(File.exist?("#{TEST_OUTPUT_DIR}/test_module/test.txt")).to eq true + end + + it 'shall only export items which match the filter if a filter is given by command line options', + doc_refs: ['Dim_export_filter'] do + Test.main("export -i #{TEST_INPUT_DIR}/filter_check/module.dim --filter \"type == requirement && text =~ /test/\ && category != software\" -o #{TEST_OUTPUT_DIR} -f rst") + h = File.read("#{TEST_OUTPUT_DIR}/test/Requirements.rst") + expect(h).not_to include('test_id_1') + expect(h).to include('test_id_2') + expect(h).not_to include('test_id_3') + expect(h).to include('test_id_4') + end + + it 'shall print info message when silent option is set to false', doc_refs: ['Dim_export_general'] do + Test.main("export -i #{TEST_INPUT_DIR}/language/module_ok.dim -o #{TEST_OUTPUT_DIR} -f json --silent") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).not_to include "Exporting..." + expect(@test_stdout).not_to include "Done." + end + end + + context 'shall throw an error and print a meaningful error message' do + it 'if specified without input files', doc_refs: ['Dim_export_general'] do + Test.main('export') + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include 'no input file specified.' + end + + it 'if specified without output folder', doc_refs: ['Dim_export_general'] do + Test.main("export -i #{TEST_INPUT_DIR}/one_module_in_several_files/Config.yml") + expect(@test_stderr).to include('specify output folder') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + + it 'if specified with invalid file format', doc_refs: %w[Dim_export_general Dim_CLI_exit] do + Test.main("export -i #{TEST_INPUT_DIR}/one_module_in_several_files/Config.yml -o #{TEST_OUTPUT_DIR}/wrong -f wrong") + expect(File.exist?("#{TEST_OUTPUT_DIR}/wrong.txt")).to eq false + expect(@test_stderr).to include('export format must be one of: rst, csv, json') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + + it 'if specified without file format', doc_refs: %w[Dim_export_general Dim_CLI_exit] do + Test.main("export -i #{TEST_INPUT_DIR}/one_module_in_several_files/Config.yml -o #{TEST_OUTPUT_DIR}/wrong") + expect(File.exist?("#{TEST_OUTPUT_DIR}/wrong.txt")).to eq false + expect(@test_stderr).to include('export format not specified, must be one of: rst, csv, json') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'to JSON' do + it 'shall include attributes as key/values pairs plus ID, module name and originator', + doc_refs: ['Dim_export_json'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR}/new_dir -f json") + expect(Dim::ExitHelper.exit_code).to eq 0 + j = JSON.load(File.read("#{TEST_OUTPUT_DIR}/new_dir/test_module_1/Requirements.json")) + expect(j.find { |e| e['id'] == 'test_id_1' } ['text']).to eq 'Another test req' + expect(j.find { |e| e['id'] == 'test_id_1' } ['document_name']).to eq 'test_module_1' + expect(j.find { |e| e['id'] == 'test_id_1' } ['originator']).to eq 'CompanyName' + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'to CSV' do + it 'shall print "Sep=", into the first line', doc_refs: ['Dim_export_csvSep'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_calculated_infos/Input1.yml -o #{TEST_OUTPUT_DIR} -f csv") + csv_content = File.readlines("#{TEST_OUTPUT_DIR}/ABC123/Requirements.csv") + expect(csv_content[0].strip).to eq('Sep=,') + end + it 'shall print all attributes, id, module name, originator', + doc_refs: ['Dim_export_csvAttributes'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_calculated_infos/Input1.yml -o #{TEST_OUTPUT_DIR} -f csv") + exported = File.read("#{TEST_OUTPUT_DIR}/ABC123/Requirements.csv") + expected = File.read("#{TEST_INPUT_DIR}/export_calculated_infos/output/Requirements1.csv") + expect(exported).to eq(expected) + end + it 'shall double quote strings and escape existing double quotes', doc_refs: ['Dim_export_csvValues'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_calculated_infos/Input2.yml -o #{TEST_OUTPUT_DIR} -f csv") + exported = File.read("#{TEST_OUTPUT_DIR}/ABC123/Requirements.csv") + expected = File.read("#{TEST_INPUT_DIR}/export_calculated_infos/output/Requirements2.csv") + expect(exported).to eq(expected) + end + end + + context 'to RST' do + it 'shall write correct Sphinx syntax including index files', + doc_refs: %w[Dim_export_rst Dim_export_rstIndex] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR} -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + #noinspection RubyLiteralArrayInspection + ['index_001_software_companyname', + 'index_002_module_companyname', + 'index_003_module_xy_company', + 'mod01/Requirements', + 'mod02/Requirements', + 'mod03/Requirements', + 'mod04/Requirements', + 'mod05/Requirements', + 'mod06/Requirements', + 'mod07/Requirements', + 'mod08/Requirements', + 'mod09/Requirements', + 'mod10/Requirements', + 'mod11/Requirements', + 'test_module_1/Requirements', + 'test_module_2/Requirements', + 'test_module_3/Requirements', + 'test_module_4/Requirements', + 'test_module_5/Requirements', + 'X-_.test___srs_/Requirements'].each do |f| + out_ref = File.read("#{TEST_INPUT_DIR}/export_check/output/#{f}.rst").universal_newline + out_is = File.read("#{TEST_OUTPUT_DIR}/#{f}.rst").universal_newline + expect(out_is).to eq(out_ref) + end + expect(File.exist?("#{TEST_OUTPUT_DIR}/test_module_2/images/test.jpeg")).to eq true + end + + it 'shall only write to file system if data has been changed', doc_refs: ['Dim_export_rstChange'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR} -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Creating spec/test_output/mod09/Requirements.rst... done' + expect(@test_stdout).to include 'Creating spec/test_output/mod10/Requirements.rst... done' + expect(@test_stdout).to include 'Copying spec/test_input/export_check/images/test.jpeg to spec/test_output/test_module_2/images/test.jpeg...' + + @test_stdout.clear + + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR} -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Creating spec/test_output/mod09/Requirements.rst... skipped' + expect(@test_stdout).to include 'Creating spec/test_output/mod10/Requirements.rst... skipped' + expect(@test_stdout).not_to include 'Copying spec/test_input/export_check/images/test.jpeg to spec/test_output/test_module_2/images/test.jpeg...' + end + + it 'shall only write to file system if data has been changed without logs when silent option given', + doc_refs: ['Dim_export_rstChange'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR} -f rst -s") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).not_to include 'Creating spec/test_output/mod09/Requirements.rst... done' + expect(@test_stdout).not_to include 'Creating spec/test_output/mod10/Requirements.rst... done' + expect(@test_stdout).not_to include 'Copying spec/test_input/export_check/images/test.jpeg to spec/test_output/test_module_2/images/test.jpeg...' + + Test.main("export -i #{TEST_INPUT_DIR}/export_check/Config.dim -o #{TEST_OUTPUT_DIR} -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).not_to include 'Creating spec/test_output/mod09/Requirements.rst... skipped' + expect(@test_stdout).not_to include 'Creating spec/test_output/mod10/Requirements.rst... skipped' + expect(@test_stdout).not_to include 'Copying spec/test_input/export_check/images/test.jpeg to spec/test_output/test_module_2/images/test.jpeg...' + end + + it 'shall be possible with unresolved references when --allow-missing is specified', + doc_refs: ['Dim_export_rst'] do + Test.main("export -i #{TEST_INPUT_DIR}/missing_refs/test_module_1.dim -o #{TEST_OUTPUT_DIR} -f rst --allow-missing") + expect(Dim::ExitHelper.exit_code).to eq 0 + h = File.read("#{TEST_OUTPUT_DIR}/test_module_1/Requirements.rst") + expect(h).to include(':refs: non_exist') + end + + it 'shall converted multiple spaces into correct Sphinx syntax', doc_refs: ['Dim_export_rst'] do + Test.main("export -i #{TEST_INPUT_DIR}/spaces_html/module.dim -o #{TEST_OUTPUT_DIR} -f rst") + out_ref = File.read("#{TEST_INPUT_DIR}/spaces_html/output/Requirements.rst").universal_newline + out_is = File.read("#{TEST_OUTPUT_DIR}/spaces_html/Requirements.rst").universal_newline + expect(out_is).to eq(out_ref) + end + + it 'shall write (nested) html strings correctly', doc_refs: ['Dim_export_rstStrings'] do + Test.main("export -i #{TEST_INPUT_DIR}/nested_html/module.dim -o #{TEST_OUTPUT_DIR} -f rst") + out_ref = File.read("#{TEST_INPUT_DIR}/nested_html/output/Requirements.rst").universal_newline + out_is = File.read("#{TEST_OUTPUT_DIR}/nested_html/Requirements.rst").universal_newline + expect(out_is).to eq(out_ref) + end + end + + context 'to a specified folder' do + it 'cleans up unused files from folder', doc_refs: ['Dim_export_cleanup'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/export_test_12_1.dim -o #{TEST_OUTPUT_DIR} -f csv") + expect(Dir.new(File.join(TEST_OUTPUT_DIR, + 'test_export_12')).children).to match_array %w[images Requirements.csv] + expect(Dir.new(File.join(TEST_OUTPUT_DIR, 'test_export_12', 'images')).children).to eq ['test.jpeg'] + + Test.main("export -i #{TEST_INPUT_DIR}/export_check/export_test_12_2.dim -o #{TEST_OUTPUT_DIR} -f csv") + expect(Dir.new(File.join(TEST_OUTPUT_DIR, 'test_export_12', 'images')).children).to eq ['test_new.jpeg'] + end + + it 'cleans folder for older files when originator changes in Config.dim', doc_refs: ['Dim_export_cleanup'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_check/using_config/Config.dim -o #{TEST_OUTPUT_DIR} -f csv") + expect(Dir.new(File.join(TEST_OUTPUT_DIR)).children).to match_array(%w[test_module_1 test_module_2]) + Test.main("export -i #{TEST_INPUT_DIR}/export_check/using_config/SingleOriginConfig.dim -o #{TEST_OUTPUT_DIR} -f csv") + expect(Dir.new(File.join(TEST_OUTPUT_DIR)).children).to match_array(['test_module_1']) + end + end + + context 'when custom attributes are provided by config file' do + context 'to JSON' do + it 'shall include attributes as key/values pairs plus ID, module name and originator', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_export_json] do + Test.main( + "export -i #{TEST_INPUT_DIR}/export_with_custom_attributes/Config.dim -o #{TEST_OUTPUT_DIR} -f json" + ) + expect(Dim::ExitHelper.exit_code).to eq 0 + expected = JSON.load(File.read("#{TEST_INPUT_DIR}/export_with_custom_attributes/output/Requirements.json")) + actual = JSON.load(File.read("#{TEST_OUTPUT_DIR}/test_module/Requirements.json")) + + expect(expected.to_json).to eq(actual.to_json) + end + end + + context 'to RST' do + it 'should add custom attributes to exported data if attribute is not empty', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_export_rst] do + Test.main("export -i #{TEST_INPUT_DIR}/export_with_custom_attributes/Config.dim -o #{TEST_OUTPUT_DIR} -f rst") + + expect(Dim::ExitHelper.exit_code).to eq 0 + expected_op = File.read("#{TEST_INPUT_DIR}/export_with_custom_attributes/output/Requirements.rst").universal_newline + actual_op = File.read("#{TEST_OUTPUT_DIR}/test_module/Requirements.rst").universal_newline + + expect(actual_op).to eq expected_op + end + end + + context 'to CSV' do + it 'should add custom attributes to exported data if attribute is not empty', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_export_csvAttributes] do + Test.main("export -i #{TEST_INPUT_DIR}/export_with_custom_attributes/Config.dim -o #{TEST_OUTPUT_DIR} -f csv") + expect(Dim::ExitHelper.exit_code).to be 0 + + expected = File.read("#{TEST_INPUT_DIR}/export_with_custom_attributes/output/Requirements.csv") + actual = File.read("#{TEST_OUTPUT_DIR}/test_module/Requirements.csv") + + expect(actual).to eq expected + end + end + end + + context 'verification_methods' do + context 'to json' do + it 'shall not add test_setups in exported format', doc_refs: ['Dim_export_verificationMethods'] do + Test.main("export -i #{TEST_INPUT_DIR}/verification_methods/verification_methods.dim -o #{TEST_OUTPUT_DIR} -f json") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/output/verification_methods/Requirements.json") + actual = File.read("#{TEST_OUTPUT_DIR}/verification_method_test/Requirements.json") + expect(actual).to eq expected + end + end + + context 'to RST' do + it 'shall not add test_setups in exported output', doc_refs: ['Dim_export_verificationMethods'] do + Test.main("export -i #{TEST_INPUT_DIR}/verification_methods/verification_methods.dim -o #{TEST_OUTPUT_DIR} -f rst") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/output/verification_methods/Requirements.rst").universal_newline + actual = File.read("#{TEST_OUTPUT_DIR}/verification_method_test/Requirements.rst").universal_newline + expect(actual).to eq expected + end + end + + context 'to csv' do + it 'shall not add test_setups in exported output', doc_refs: ['Dim_export_verificationMethods'] do + Test.main("export -i #{TEST_INPUT_DIR}/verification_methods/verification_methods.dim -o #{TEST_OUTPUT_DIR} -f csv") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/output/verification_methods/Requirement.csv") + actual = File.read("#{TEST_OUTPUT_DIR}/verification_method_test/Requirements.csv") + expect(actual).to eq expected + end + end + end + + context 'document' do + context 'to json' do + it 'shall replace module with document', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/modulename.dim -o #{TEST_OUTPUT_DIR} -f json") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/json/Requirements.json") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.json") + + expect(actual).to eq(expected) + end + + it 'shall export document dim file', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/document.dim -o #{TEST_OUTPUT_DIR} -f json") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/json/Requirements.json") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.json") + + expect(actual).to eq(expected) + end + end + + context 'to csv' do + it 'shall replace module with document', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/modulename.dim -o #{TEST_OUTPUT_DIR} -f csv") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/csv/Requirements.csv") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.csv") + + expect(actual).to eq(expected) + end + + it 'shall export document dim file', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/document.dim -o #{TEST_OUTPUT_DIR} -f csv") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/csv/Requirements.csv") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.csv") + + expect(actual).to eq(expected) + end + end + + context 'to rst' do + it 'shall replace module with document', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/modulename.dim -o #{TEST_OUTPUT_DIR} -f rst") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/rst/Requirements.rst") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.rst") + + expect(actual).to eq(expected) + end + + it 'shall export document dim file', doc_refs: %w[Dim_loading_document Dim_export_general] do + Test.main("export -i #{TEST_INPUT_DIR}/document/document.dim -o #{TEST_OUTPUT_DIR} -f rst") + + expected = File.read("#{TEST_INPUT_DIR}/document/output/rst/Requirements.rst") + actual = File.read("#{TEST_OUTPUT_DIR}/ABC/Requirements.rst") + + expect(actual).to eq(expected) + end + end + end + + context 'exporting an empty requirements' do + it 'shall not raise an error', doc_refs: ['Dim_export_general'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_empty_requirements/module.dim -o #{TEST_OUTPUT_DIR} -f rst") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).not_to include "Creating" + end + end + + context 'when file is already present in export folder' do + before do + FileUtils.mkdir_p("./spec/test_output/sample_export/export_test") + FileUtils.cp( + "./spec/test_input/export_when_media_file_present/different_sample.txt", + "./spec/test_output/sample_export/export_test/sample.txt" + ) + end + + after do + FileUtils.remove_dir("./spec/test_output/sample_export") + end + + it 'shall not copy the file', doc_refs: ['Dim_export_general'] do + Test.main("export -i #{TEST_INPUT_DIR}/export_when_media_file_present/module.dim -o #{TEST_OUTPUT_DIR}/sample_export -f rst") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include "Copying" + end + end + end +end diff --git a/dim/spec/file_helper_spec.rb b/dim/spec/file_helper_spec.rb new file mode 100644 index 0000000..a4066f2 --- /dev/null +++ b/dim/spec/file_helper_spec.rb @@ -0,0 +1,19 @@ +require_relative 'framework/helper' + +class Dummy + include Dim::Helpers::FileHelper +end + +module Dim + describe 'File helper methods' do + it 'shall print error message when empty file is loaded', doc_refs: ['Dim_loading_readBad'] do + begin + $test_exception = nil + Dummy.new.open_yml_file("./spec/test_input/invalid_input/", "empty_yaml.dim") + rescue Exception => e + $test_exception = e + end + expect(@test_stderr).to include "not a valid yaml file" + end + end +end diff --git a/dim/spec/format_spec.rb b/dim/spec/format_spec.rb new file mode 100644 index 0000000..3d7c5d9 --- /dev/null +++ b/dim/spec/format_spec.rb @@ -0,0 +1,264 @@ +require_relative 'framework/helper' + +module Dim + describe 'dim format' do + def compareFormat(f) + Test.main("format -i #{TEST_INPUT_DIR}/format/#{f} --output-format extra") + expect($test_exception).to be nil + formatted = File.read("#{TEST_INPUT_DIR}/format/#{f}.formatted").universal_newline + expected = File.read("#{TEST_INPUT_DIR}/format/#{f}.expected").universal_newline + expect(formatted).to eq(expected) + end + + context 'shall allow missing references while formatting regardless of output format' do + it 'when output-format is check-only', doc_refs: %w[Dim_format_general] do + Test.main("format -i #{TEST_INPUT_DIR}/missing_refs/test_module_1.dim --output-format check-only") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).not_to include('"test_id_3" refers to non-existing "non_exist"') + expect(@test_stderr).to include('Error: The following files are not formatted correctly') + expect(@test_stdout).not_to include("Using 'allow-missing' might influence metrics when some references are ignored!") + end + + it 'when output-format is extra', doc_refs: %w[Dim_format_general] do + Test.main("format -i #{TEST_INPUT_DIR}/missing_refs/test_module_1.dim --output-format extra") + + formatted = File.read("#{TEST_INPUT_DIR}/missing_refs/test_module_1.dim.formatted") + expected = File.read("#{TEST_INPUT_DIR}/missing_refs/test_module_1.dim.expected") + + expect(formatted).to eq(expected) + end + end + + context 'shall support output-format' do + it '"in-place" by default', doc_refs: %w[Dim_format_general Dim_format_inPlace Dim_loading_readGood] do + path = "#{TEST_INPUT_DIR}/format/inplace" + %w[first second].each { |f| FileUtils.cp_r("#{path}/#{f}.dim", "#{path}/#{f}.inplace.dim") } + Test.main("format -i #{TEST_INPUT_DIR}/format/inplace/complete.conf") + + %w[first second].each do |f| + formatted = File.read("#{path}/#{f}.inplace.dim").universal_newline + expected = File.read("#{path}/#{f}.dim.expected").universal_newline + expect(formatted).to eq(expected) + end + + %w[first second].each { |f| FileUtils.rm_f("#{path}/#{f}.inplace.dim") } + end + + it '"extra" files', doc_refs: ['Dim_format_extra'] do + path = "#{TEST_INPUT_DIR}/format/inplace" + %w[first second].each { |f| FileUtils.cp_r("#{path}/#{f}.dim", "#{path}/#{f}.inplace.dim") } + Test.main("format -i #{TEST_INPUT_DIR}/format/inplace/complete_extra.conf --output-format extra") + + %w[first second].each do |f| + formatted = File.read("#{path}/#{f}.dim.formatted").universal_newline + expected = File.read("#{path}/#{f}.dim.expected").universal_newline + expect(formatted).to eq(expected) + end + + %w[first second].each { |f| FileUtils.rm_f("#{path}/#{f}.dim.formatted") } + end + + it '"check-only", valid files shall not lead to an error', doc_refs: ['Dim_format_checkOnly'] do + Test.main("format -i #{TEST_INPUT_DIR}/format/empty/none.dim --output-format check-only") + expect(@test_stderr).not_to include('Error: The following files are not formatted correctly:') + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + it '"check-only", invalid files shall lead to an error and a meaningful error message shall be printed', + doc_refs: ['Dim_format_checkOnly'] do + Test.main("format -i #{TEST_INPUT_DIR}/format/collection/complete.conf --output-format check-only") + expect(@test_stderr).to include('Error: The following files are not formatted correctly:') + expect(@test_stderr).to include('text.dim') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'with invalid output-format' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_format_general'] do + Test.main("format -i #{TEST_INPUT_DIR}/format/empty/none.dim --output-format wrong") + expect(@test_stderr).to include('output-format must be in-place, extra or check-only') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'use case:' do + it 'empty file', doc_refs: ['Dim_format_general'] do + compareFormat('empty/none.dim') + end + + it 'only module attribute', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/onlyModule.dim') + end + + it 'only metadata metadata', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/metadataEmpty.dim') + compareFormat('collection/metadataString.dim') + end + + it 'only enclosed', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/enclosedArray.dim') + compareFormat('collection/enclosedString.dim') + end + + it 'one liners', doc_refs: ['Dim_format_form'] do + compareFormat('collection/oneLiners.dim') + end + + it 'single enums', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/type.dim') + compareFormat('collection/status.dim') + compareFormat('collection/review_status.dim') + compareFormat('collection/asil.dim') + compareFormat('collection/cal.dim') + end + + it 'multi enums', doc_refs: %w[Dim_format_whitespaces Dim_format_default Dim_format_duplicated] do + compareFormat('collection/tags.dim') + compareFormat('collection/test_setups.dim') + compareFormat('collection/verification_methods.dim') + end + + it 'lists', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/developer.dim') + compareFormat('collection/tester.dim') + end + + it 'refs', doc_refs: %w[Dim_format_whitespaces Dim_format_default Dim_format_duplicated] do + compareFormat('collection/refs.dim') + end + + it 'sources', doc_refs: %w[Dim_format_whitespaces Dim_format_default Dim_format_duplicated] do + compareFormat('collection/sources.dim') + end + + it 'textual fields', doc_refs: %w[Dim_format_whitespaces Dim_format_default] do + compareFormat('collection/text.dim') + compareFormat('collection/verification_criteria.dim') + compareFormat('collection/comment.dim') + compareFormat('collection/miscellaneous.dim') + compareFormat('collection/feature.dim') + compareFormat('collection/change_request.dim') + end + + it 'properties file shall have no influence', doc_refs: ['Dim_format_general'] do + Test.main("format -i #{TEST_INPUT_DIR}/format/collection/asil.conf --output-format extra") + formatted = File.read("#{TEST_INPUT_DIR}/format/collection/asil.dim.formatted").universal_newline + expected = File.read("#{TEST_INPUT_DIR}/format/collection/asil.dim.expected").universal_newline + expect(formatted).to eq(expected) + end + + it 'order', doc_refs: ['Dim_format_order'] do + compareFormat('collection/order.dim') + end + end + + context 'shall not include test_setups' do + it 'shall format the document with verification_methods and not test_setups', + doc_refs: %w[Dim_format_verificationMethods] do + Test.main("format -i #{TEST_INPUT_DIR}/verification_methods/verification_methods.dim --output-format extra") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/verification_methods.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/verification_methods/verification_methods.dim.formatted") + expect(actual).to eq expected + + Test.main("format -i #{TEST_INPUT_DIR}/verification_methods/single_none.dim --output-format extra") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/single_none.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/verification_methods/single_none.dim.formatted") + expect(actual).to eq expected + + Test.main("format -i #{TEST_INPUT_DIR}/verification_methods/all_none.dim --output-format extra") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/all_none.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/verification_methods/all_none.dim.formatted") + expect(actual).to eq expected + + Test.main("format -i #{TEST_INPUT_DIR}/verification_methods/single_none.dim --output-format extra") + expected = File.read("#{TEST_INPUT_DIR}/verification_methods/single_none.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/verification_methods/single_none.dim.formatted") + expect(actual).to eq expected + end + end + + context 'shall ignore different line-endings:' do + it 'LF compared to OS default', doc_refs: ['Dim_format_checkOnly'] do + content = File.read("#{TEST_INPUT_DIR}/format_lineendings/lf.dim", mode: 'rb') + expect(content).not_to include("\r\n") + Test.main("format -i #{TEST_INPUT_DIR}/format_lineendings/lf.dim --output-format check-only") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + it 'CRLF compared to OS default', doc_refs: ['Dim_format_checkOnly'] do + content = File.read("#{TEST_INPUT_DIR}/format_lineendings/crlf.dim", mode: 'rb') + expect(content).to include("\r\n") + Test.main("format -i #{TEST_INPUT_DIR}/format_lineendings/crlf.dim --output-format check-only") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + it 'Mixed compared to OS default', doc_refs: ['Dim_format_checkOnly'] do + content = File.read("#{TEST_INPUT_DIR}/format_lineendings/mixed.dim", mode: 'rb') + expect(content).to include("\r\nSRS_A_B:\n ") + Test.main("format -i #{TEST_INPUT_DIR}/format_lineendings/mixed.dim --output-format check-only") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'when output format is stdout' do + before { allow($stdin).to receive(:read).and_return(content) } + + let(:content) { File.read("#{TEST_INPUT_DIR}/format/collection/order.dim") } + let(:formatted_content) { File.read("#{TEST_INPUT_DIR}/format/collection/order.dim.expected") } + + it 'reads the content from STDIN and prints out content in STDOUT', doc_refs: ['Dim_format_vim'] do + Test.main('format --output-format stdout') + expect(@test_stdout).to include(formatted_content) + end + end + + context 'when custom attributes are given' do + it 'loads the custom attributes and format the requirements', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_format_customAttributes] do + Test.main( + "format -i #{TEST_INPUT_DIR}/format/with_custom_attributes/Config.dim --output-format extra" + ) + + expected = File.read("#{TEST_INPUT_DIR}/format/with_custom_attributes/test_module.dim.expected").universal_newline + actual = File.read("#{TEST_INPUT_DIR}/format/with_custom_attributes/test_module.dim.formatted").universal_newline + + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(actual).to eq(expected) + end + end + + context 'document' do + context 'when present' do + it 'shall format the document', doc_refs: %w[Dim_loading_document Dim_format_general] do + Test.main("format -i #{TEST_INPUT_DIR}/document/document.dim --output-format extra") + + expected = File.read("#{TEST_INPUT_DIR}/document/document.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/document/document.dim.formatted") + + expect(actual).to eq(expected) + end + end + + context 'when module is given' do + it 'shall replace the module with document', doc_refs: %w[Dim_loading_document Dim_format_general] do + Test.main("format -i #{TEST_INPUT_DIR}/document/modulename.dim --output-format extra") + + expected = File.read("#{TEST_INPUT_DIR}/document/modulename.dim.expected") + actual = File.read("#{TEST_INPUT_DIR}/document/modulename.dim.formatted") + + expect(actual).to eq(expected) + end + end + end + + context 'when invalid format style is present' do + before do + Dim::Requirement::SYNTAX['dummy'] = { check: nil, format_style: :dummy, format_shift: 0, default: '', allowed: nil } + end + + it 'shall throw a meaningful error and exit', doc_refs: ['Dim_format_general'] do + Test.main("format -i #{TEST_INPUT_DIR}/invalid_format_style/module.dim --output-format extra") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'Error: Invalid format style' + end + end + end +end diff --git a/dim/spec/framework/helper.rb b/dim/spec/framework/helper.rb new file mode 100644 index 0000000..593cdc0 --- /dev/null +++ b/dim/spec/framework/helper.rb @@ -0,0 +1,114 @@ +require 'json' +require 'fileutils' + +begin + gem 'simplecov', '=0.22.0' + require 'simplecov' + SimpleCov.start do + add_filter '/spec/' + enable_coverage :branch + end +rescue Exception + # Ignored +end + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../../lib") +require 'dim/dimmain' +require_relative './output' + +TEST_OUTPUT_DIR = 'spec/test_output' +TEST_INPUT_DIR = 'spec/test_input' + +module Dim + module Test + def self.main(args_str) + args = args_str.split(/\s(?=(?:[^"]|"[^"]*")*$)/).map { |s| s.strip.delete('\"') } + begin + $test_exception = nil + Dim.main(args) + rescue Exception => e + $test_exception = e + end + end + + def self.execute(&block) + begin + $test_exception = nil + yield block + rescue Exception => e + $test_exception = e + end + end + + def self.clean_testdata + Options.reset + FileUtils.rm_rf(TEST_OUTPUT_DIR) + Dir.glob("#{TEST_INPUT_DIR}/**/*.dim.formatted").each do |f| + FileUtils.rm_f(f) + end + end + end +end + +class Summary + def dump_summary(res) + table = { '' => [] } + res.examples.each do |e| + e.metadata.fetch(:doc_refs, ['']).each do |id| + next if id == 'IGNORE' + + table[id] ||= [] + table[id] << { + 'location' => e.location.gsub('./', ''), + 'description' => e.full_description + } + end + end + folder = "#{File.dirname(__FILE__)}/../../documentation/source/pages/requirements-generated" + FileUtils.mkdir_p(folder) + File.write("#{folder}/mapping.json", JSON.pretty_generate(table)) + end +end + +RSpec.configure do |config| + config.reporter.register_listener(Summary.new, :dump_summary) + + config.before(:all) do |the_test| + $stdout.write "Testing #{the_test.class}:\n" + end + + config.after(:all) do |_the_test| + puts "\nDONE" + end + + $org_keys = Dim::Requirement::SYNTAX.keys + config.before(:each) do |_the_test| + Dim::Test.clean_testdata + Dim::Requirement::SYNTAX.delete_if { |k| !$org_keys.include? k } + Dim::Requirement.instance_methods.each do |k| + Dim::Requirement.remove_method(k) if %w[text_ verification_criteria_ comment_].any? { |lang| k.start_with?(lang) } + end + + $stdout_backup = Thread.current[:stdout] + @test_stdout = '' + Thread.current[:stdout] = StringIO.open(@test_stdout, 'w+') + + $stderr_backup = Thread.current[:stderr] + @test_stderr = '' + Thread.current[:stderr] = StringIO.open(@test_stderr, 'w+') + end + + config.after(:each) do |the_test| + Thread.current[:stdout] = $stdout_backup + Thread.current[:stderr] = $stderr_backup + + Dim::ExitHelper.reset_exit_code + + Dim::Test.clean_testdata + + unless the_test.instance_variable_get(:@exception).nil? + puts @test_stdout + puts @test_stderr + end + end +end diff --git a/dim/spec/framework/output.rb b/dim/spec/framework/output.rb new file mode 100644 index 0000000..9e1eac0 --- /dev/null +++ b/dim/spec/framework/output.rb @@ -0,0 +1,41 @@ +require 'stringio' + +class ThreadOut < IO + def initialize(out, sym) + @out = out + @sym = sym + end + + def out(stuff, method) + if Thread.current[@sym] + Thread.current[@sym].send(method, stuff) + else + @out.send(method, stuff) + end + end + + def write(stuff = '') + out(stuff, __method__) + end + + def puts(stuff = '') + out(stuff, __method__) + end + + def flush + if Thread.current[@sym] + Thread.current[@sym].flush + else + begin + @out.flush + rescue Exception + self + end + end + end +end + +STDOUT.sync = true +STDERR.sync = true +$stdout = ThreadOut.new(STDOUT, :stdout) +$stderr = ThreadOut.new(STDERR, :stderr) diff --git a/dim/spec/framework/testmain.rb b/dim/spec/framework/testmain.rb new file mode 100644 index 0000000..d39dced --- /dev/null +++ b/dim/spec/framework/testmain.rb @@ -0,0 +1,23 @@ +$LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib') + +module Kernel + alias __at_exit at_exit + def at_exit(&block) + __at_exit do + exit_status = $ERROR_INFO.status if $ERROR_INFO.is_a?(SystemExit) + block.call + exit exit_status if exit_status + end + end +end + +require 'rspec/core/rake_task' +SPEC_PATTERN = 'spec/**/*_spec.rb' + +namespace :test do + desc 'Run specs' + RSpec::Core::RakeTask.new do |t| + t.pattern = SPEC_PATTERN + t.rspec_opts = '--dry-run' if $dry_run + end +end diff --git a/dim/spec/loader_attribute_spec.rb b/dim/spec/loader_attribute_spec.rb new file mode 100644 index 0000000..cd6a16d --- /dev/null +++ b/dim/spec/loader_attribute_spec.rb @@ -0,0 +1,252 @@ +require_relative 'framework/helper' + +module Dim + describe 'Loading attributes file' do + let(:loader) { Dim::Loader.new } + + context 'loading attributes in general' do + context 'when type is not valid' do + let(:attr_file) { "#{TEST_INPUT_DIR}/invalid_attributes/invalid_type.dim" } + let(:err_msg) { "Error: in #{attr_file}: Invalid value \"multiple\" for type detected" } + + it 'aborts and prints meaningful message', + doc_refs: %w[Dim_AttrFiles_Attribute Dim_ConfigFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_attributes/test_module.dim -a #{attr_file}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include(err_msg) + end + end + + context 'when default value is auto' do + let(:attr_file) { "#{TEST_INPUT_DIR}/invalid_attributes/default_auto.dim" } + let(:err_msg) { "Error: in #{attr_file}: Invalid value \"auto\" for default detected" } + + it 'exits process and prints meaningful message', + doc_refs: %w[Dim_AttrFiles_Attribute Dim_ConfigFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_attributes/test_module.dim -a #{attr_file}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include(err_msg) + end + end + + context 'when default is not from allowed list of values' do + let(:attr_file) { "#{TEST_INPUT_DIR}/invalid_attributes/invalid_default.dim" } + let(:err_msg) { "Error: in #{attr_file}: default value for necessary must be from allowed list" } + + it 'exits process and prints meaningful message', + doc_refs: %w[Dim_AttrFiles_Attribute Dim_ConfigFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_attributes/test_module.dim -a #{attr_file}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include(err_msg) + end + end + + context 'when allowed is not passed as an array list' do + let(:attr_file) { "#{TEST_INPUT_DIR}/invalid_attributes/invalid_allowed.dim" } + let(:err_msg) { "Error: in #{attr_file}: Invalid value \"red, green\" for allowed detected" } + + it 'exits process and prints meaningful message', + doc_refs: %w[Dim_AttrFiles_Attribute Dim_ConfigFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_attributes/test_module.dim -a #{attr_file}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include(err_msg) + end + end + + context 'when valid attributes file passed' do + it 'loads custom attributes and prints the message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/Config.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include('Loading [attributes] spec/test_input/with_custom_attributes/attributes.dim') + end + end + + context 'when valid attributes file passed along with silent option' do + before { OPTIONS[:silent] = true } + + it 'does not print the attribute loading message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/Config.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).not_to include('Loading [attributes] spec/test_input/with_custom_attributes/attributes.dim') + end + end + end + + context 'loading custom attributes via config file' do + context 'when valid custom attributes are defined' do + let(:file) { "#{TEST_INPUT_DIR}/with_custom_attributes/Config.dim"} + let(:requirement) { loader.requirements['test_id_1'] } + + it 'accepts the custom attributes provided by dim file', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + loader.load(file: file, allow_missing: false) + expect(requirement.cluster).to eq('1.6.5') + expect(requirement.necessary).to eq("false") + end + end + + context 'when attributes have invalid value for custom attributes' do + let(:folder) { "#{TEST_INPUT_DIR}/with_custom_attributes/invalid_requirements" } + let(:file) { "#{folder}/Config.dim" } + + it 'exits with error message', doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + expect { loader.load(file: file, silent: false) }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{folder}/test_module.dim: attribute \"necessary\" must not be \"lorem\"" + end + end + + context "when 'default' value for custom attributes is not from the 'allowed' list provided" do + let(:file) { "#{TEST_INPUT_DIR}/with_custom_attributes/default_not_from_allowed_values/Config.dim" } + + it 'exits process with a meaningful message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + expect { loader.load(file: file, silent: false) }.to raise_exception(SystemExit) + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "attributes.dim: default value for necessary must be from allowed list" + end + end + + context "when 'standard' attribute is added as a custom attribute" do + it 'exits process with the meaningful message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/attributes_file_with_standard_attributes/Config.dim") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('attributes.dim: Defining standard attributes as a custom attributes is not allowed') + end + end + + context "when empty attributes file is referenced" do + it 'prints warning and skips the loading', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute] do + Test.main("check -i #{TEST_INPUT_DIR}/empty_custom_attributes_file/Config.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include('Warning: empty file detected; skipped loading of attributes.dim') + end + end + + context 'when another attribute file is also passed using command line parameter' do + context 'and both attributes file have unique attributes defined' do + it 'loads custom attributes from both files and validates the requirements', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_CmdParam] do + Test.main( + "check -i #{TEST_INPUT_DIR}/with_custom_attributes/multiple_attribute_files/Config.dim " \ + "-a #{TEST_INPUT_DIR}/with_custom_attributes/multiple_attribute_files/custom_attributes.dim" + ) + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include("Done.\nChecking consistency...\nDone.") + end + end + + context 'and there is common attribute present in both attributes file' do + let(:folder) { "#{TEST_INPUT_DIR}/with_custom_attributes/duplicate_attributes" } + + it 'loads custom attributes, but attributes from config file will be given priority', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_CmdParam] do + Test.main( + "check -i #{folder}/Config.dim " \ + "-a #{TEST_INPUT_DIR}/with_custom_attributes/duplicate_attributes/custom_attributes.dim" + ) + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: in #{folder}/test_module.dim: attribute \"necessary\" must not be \"red\"") + end + end + end + + context 'when attributes file is not referenced in Config' do + let(:filename) { 'spec/test_input/custom_attributes_without_attributes_file/test_module.dim' } + + it 'does not search for attributes file till root director', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_SearchAttributeFile] do + Test.main("check -i #{TEST_INPUT_DIR}/custom_attributes_without_attributes_file/Config.dim") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: in #{filename}: attribute necessary not allowed") + end + end + end + + context 'when loading without config file' do + subject { loader.load(file: file, attributes_file: attributes_file) } + context "when custom attributes file is passed using '-a' param with invalid filepath" do + let(:file) { "#{TEST_INPUT_DIR}/with_custom_attributes/test_module.dim" } + let(:attributes_file) { "#{TEST_INPUT_DIR}/with_custom_attribute/attributes.dim" } + + it 'raises file not found error', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_CmdParam] do + expect { subject }.to raise_exception(Errno::ENOENT) + end + end + + context "when custom attributes file is passed using '-a' param with valid filepath" do + let(:file) { "#{TEST_INPUT_DIR}/with_custom_attributes/test_module.dim" } + let(:attributes_file) { "#{TEST_INPUT_DIR}/with_custom_attributes/attributes.dim" } + + it 'loads the dim file', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_CmdParam] do + subject + expect(loader.requirements['test_id_1'].cluster).to eq '1.6.5' + expect(loader.requirements['test_id_1'].necessary).to eq 'false' + end + end + + context 'when custom attributes file not passed' do + context 'when attributes file is present at same level as a requirements file' do + it 'loads the attributes before processing the requirements', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_SearchAttributeFile] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/test_module.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include("Checking consistency...\nDone.") + end + end + + context 'when attributes file is present one or more level above requirements file' do + it 'searches for attributes file till root directory and loads attributes if file present', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_SearchAttributeFile] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/reference_from_parent/test_module.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include("Checking consistency...\nDone.") + end + end + + context 'when attributes file is not present on same level or till root level' do + let(:filename) { "#{TEST_INPUT_DIR}/custom_attributes_without_attributes_file/test_module.dim" } + + it 'exits process with a meaningful message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_SearchAttributeFile] do + Test.main("check -i #{filename}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: in #{filename}: attribute necessary not allowed") + end + end + + context "when attributes file is present but not named as 'attributes.dim'" do + let(:filename) { "#{TEST_INPUT_DIR}/custom_attributes_without_attributes_file/test_module.dim" } + + it 'exits process with a meaningful message', + doc_refs: %w[Dim_ConfigFiles_Attribute Dim_AttrFiles_Attribute Dim_AttrFiles_SearchAttributeFile] do + Test.main("check -i #{filename}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("Error: in #{filename}: attribute necessary not allowed") + end + end + end + end + end +end diff --git a/dim/spec/loader_config_spec.rb b/dim/spec/loader_config_spec.rb new file mode 100644 index 0000000..558c20d --- /dev/null +++ b/dim/spec/loader_config_spec.rb @@ -0,0 +1,485 @@ +require_relative 'framework/helper' + +module Dim + describe 'Loading a config file' do + context 'which is not empty but has invalid yaml syntax' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/yaml_syntax_invalid.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'mapping values are not allowed in this context at line 3 column 23' + expect(@test_stderr).to include filename + end + end + + context 'with int as originator' do + it 'shall interpret the int as string', doc_refs: ['Dim_Syntax_Values'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/invalid_originator.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include 'Loading [334]' + end + end + + context 'with invalid top-level attribute' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/invalid_config_toplevel_attribute.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Config'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'top level key in config file must be "Config", "Properties", "Attributes", found "Test"' + expect(@test_stderr).to include filename + end + end + + context 'with a valid array of config entries' do + it 'shall annotate requirements accordingly', + doc_refs: %w[Dim_ConfigFiles_Config Dim_ConfigFiles_Files Dim_ConfigFiles_Originator + Dim_ConfigFiles_Category] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/export_check/Config.dim") + req = loader.requirements['test_id_2'] + expect(req.origin).to eql('XY_Company') + expect(req.category).to eql('module') + end + end + + context 'with invalid attribute in config entry' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/invalid_config_entry_attribute.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Config'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "each hash in 'Config' array must have key/value pairs for files, category, originator, disable_naming_convention_check." + expect(@test_stderr).to include filename + end + end + + context 'with missing attribute in config entry' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/missing_config_entry_attribute.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Config'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "each hash in 'Config' array must have key/value pairs for files, category, originator, disable_naming_convention_check." + expect(@test_stderr).to include "#{filename}" + end + end + + context 'with file pattern that does not match' do + it 'shall not lead to an error but print a warning output', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/no_match_pattern.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include 'no matches for "test*.dim' + end + end + + context 'with empty files attribute' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/files_key_invalid_string.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "attribute \"files\" of 'CompanyName' must not have an empty string" + expect(@test_stderr).to include filename + end + end + + context 'where files is a hash not a string or array' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/hash_in_files.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include " attribute \"files\" of 'bla' reqs must be a string or an array of strings." + expect(@test_stderr).to include filename + end + end + + context 'where files are specified twice' do + it 'shall throw an error and display the correct error message', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/duplicate_files.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'file spec/test_input/invalid_input/modules/duplicate_module.dim already loaded' + end + end + + context 'where category has an invalid value' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/invalid_types.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Category'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "attribute \"category\" of 'Customer' reqs is 'test' but must be one of input, system, software, architecture, module." + expect(@test_stderr).to include filename + end + end + + context 'with category as array instead of string' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/category_array.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Category'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "attribute \"category\" of 'CompanyName' reqs must be a string" + expect(@test_stderr).to include filename + end + end + + context 'where Properties is not a string' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/properties_array.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Property'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "'Properties' must be a string" + expect(@test_stderr).to include filename + end + end + + context 'with config as a simple string instead of an array of config entries' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/config_string.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Config'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "'Config' must be an array" + expect(@test_stderr).to include filename + end + end + + context 'when backward slashes are detected in the filepath' do + let(:pattern) { '.\modules\duplicate_module.dim' } + + it 'warns user about backward slashes' do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/backward_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include "Warning: Backward slashes detected in pattern #{pattern}. Use '/' over '\\'" + end + end + + context 'when absolute path is given' do + let(:filepath) { "#{TEST_INPUT_DIR}/invalid_input/absolute_file_path.dim"} + let(:pattern) { '/modules/test_module_1.dim' } + + it 'shall throw an error and print error message', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{filepath}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filepath}: '#{pattern}' must not be an absolute path" + end + end + + context 'when parent dir path is added in filepath' do + let(:filepath) { "#{TEST_INPUT_DIR}/invalid_input/parent_dir_in_path.dim" } + let(:pattern) { 'modules/../test_module_1.dim' } + + it 'shall throw an error and show a message on console', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{filepath}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filepath}: '#{pattern}' must not include '..'" + end + end + + context 'when custom attributes are provided' do + context "when 'Attributes' is of type string" do + it 'loads config file along with custom attributes given', doc_refs: ['Dim_ConfigFiles_Attribute'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/with_custom_attributes/Config.dim") + req_with_custom_attribute = loader.requirements['test_id_1'] + expect(req_with_custom_attribute.text).to eq('First Test Requirement') + expect(req_with_custom_attribute.cluster).to eq('1.6.5') + expect(req_with_custom_attribute.necessary).to eq('false') + + req_without_custom_attribute = loader.requirements['test_id_2'] + expect(req_without_custom_attribute.text).to eq('Second Test Requirement') + expect(req_without_custom_attribute.cluster).to eq('') + expect(req_without_custom_attribute.necessary).to eq('') + end + end + + context "when 'Attributes' is other than string" do + let(:filepath) { "#{TEST_INPUT_DIR}/invalid_input/custom_attributes.dim" } + let(:err_msg) { "Error: in #{filepath}: 'Attributes' must be a string" } + + it 'throws and exits with meaningful error message', doc_refs: ['Dim_ConfigFiles_Attribute'] do + Test.main("check -i #{filepath}") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include err_msg + end + end + + context 'with dependencies within the categories even if circularly referenced' do + it 'does not error out even if there is circular dependency within different levels', + doc_refs: %w[Dim_api_upstreamRefs Dim_api_downstreamRefs Dim_loading_checkCyclic] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/backward_reference_within_category/config.dim") + + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['SRS_requirement_1'].upstreamRefs).to match_array %w[SYS_requirement1 SRS_requirement_2] + expect(loader.requirements['SRS_requirement_1'].downstreamRefs).to match_array ['SWA_requirement1'] + + expect(loader.requirements['SRS_requirement_2'].upstreamRefs).to match_array [] + expect(loader.requirements['SRS_requirement_2'].downstreamRefs).to match_array %w[SRS_requirement_1 SWA_requirement1] + + expect(loader.requirements['SWA_requirement1'].upstreamRefs).to match_array %w[SRS_requirement_1 SRS_requirement_2 SYS_requirement1] + expect(loader.requirements['SWA_requirement1'].downstreamRefs).to match_array [] + + expect(loader.requirements['SWA_requirement2'].upstreamRefs).to match_array [] + expect(loader.requirements['SWA_requirement2'].downstreamRefs).to match_array [] + + expect(loader.requirements['SMD_requirement1'].upstreamRefs).to match_array [] + expect(loader.requirements['SMD_requirement1'].downstreamRefs).to match_array [] + + expect(loader.requirements['SMD_requirement2'].upstreamRefs).to match_array [] + expect(loader.requirements['SMD_requirement2'].downstreamRefs).to match_array [] + + expect(loader.requirements['IN_requirement1'].upstreamRefs).to match_array [] + expect(loader.requirements['IN_requirement1'].downstreamRefs).to match_array [] + + expect(loader.requirements['IN_requirement2'].upstreamRefs).to match_array [] + expect(loader.requirements['IN_requirement2'].downstreamRefs).to match_array [] + + expect(loader.requirements['SYS_requirement1'].upstreamRefs).to match_array [] + expect(loader.requirements['SYS_requirement1'].downstreamRefs).to match_array %w[SRS_requirement_1 SWA_requirement1] + + expect(loader.requirements['SYS_requirement2'].upstreamRefs).to match_array [] + expect(loader.requirements['SYS_requirement2'].downstreamRefs).to match_array [] + end + end + + context 'with dependencies within the same categories' do + it 'when circularly referenced raises error with meaningful message', doc_refs: ['Dim_loading_checkCyclic'] do + Test.main("check -i #{TEST_INPUT_DIR}/backward_reference_same_category/circular/config.dim") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include '"SRS_req_1" is cyclically referenced: SRS_req_1 -> SRS_req_2 -> SRS_req_3 -> SRS_req_1' + expect(@test_stderr).to include 'backward_reference_same_category/circular/module1.dim' + end + + it 'loads requirements with correctly referenced', doc_refs: ['Dim_ReqFiles_refs'] do + Test.main("check -i #{TEST_INPUT_DIR}/backward_reference_same_category/non_circular/config.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + end + end + end + + context 'when software files mentioned' do + let(:warning) { "Warning: disable_naming_convention_check attribute will only take effect when category is software" } + + context 'when category is software' do + it 'does not put a warning or error out the execution', doc_refs: ['Dim_ConfigFiles_disableNameCheck'] do + Test.main("check -i #{TEST_INPUT_DIR}/software_configs/with_category_software/config.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stderr).not_to include(warning) + expect(@test_stdout).to include('Done') + end + end + + context 'when category is other than software' do + it 'loads Dim files with a warning', doc_refs: ['Dim_ConfigFiles_disableNameCheck'] do + Test.main("check -i #{TEST_INPUT_DIR}/software_configs/config.dim") + + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stderr).to include(warning) + expect(@test_stdout).to include('Done') + end + end + + context 'when category is software but legacy is not set' do + let(:filepath) { "#{TEST_INPUT_DIR}/software_configs/with_category_software" } + + it 'sets legacy to false as default', doc_refs: ['Dim_ConfigFiles_disableNameCheck'] do + Test.main("check -i #{filepath}/without_name_check_config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('ID ESR-0001 in software requirement must start with "SRS_"') + expect(@test_stderr).to include("#{filepath}/test_module.dim") + end + end + + context 'when category is software and legacy is no' do + let(:filepath) { "#{TEST_INPUT_DIR}/software_configs/with_category_software" } + + it 'throws an error and exits', doc_refs: ['Dim_ConfigFiles_disableNameCheck'] do + Test.main("check -i #{filepath}/with_name_check_no_config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).not_to include('Legacy in config must be either boolean value or a string "yes" or "no"') + expect(@test_stderr).to include('ID ESR-0001 in software requirement must start with "SRS_"') + expect(@test_stderr).to include("#{filepath}/test_module.dim") + end + end + + context 'when category is software but legacy is other than "yes" or "no"' do + let(:filepath) { "#{TEST_INPUT_DIR}/software_configs/with_category_software/invalid_name_check_config.dim" } + + it 'throws error and exits', doc_refs: ['Dim_ConfigFiles_disableNameCheck'] do + Test.main("check -i #{filepath}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('disable_naming_convention_check in config must be either boolean value or a string "yes" or "no"') + expect(@test_stderr).to include(filepath) + end + end + end + + context 'with software requirements' do + subject { Test.main("check -i #{TEST_INPUT_DIR}/software_requirements/#{filepath}/config.dim") } + + context 'when category is not software' do + let(:filepath) { 'without_software_category' } + + it 'does not throw error and loads the requirements', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include('Done') + end + end + + context 'when legacy is set to "yes"' do + let(:filepath) { 'legacy' } + + it 'does not throws error and loads requirements', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include('Done') + end + end + + context 'when requirement does not start with "SRS"' do + let(:filepath) { 'start_without_srs' } + + it 'throws meaningful error and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'ID feature-1_aspect-1 in software requirement must start with "SRS_"' + ) + end + end + + context 'when more than two underscores are present' do + let(:filepath) { 'multiple_underscores' } + + it 'throws error and aborts loading', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'ID SRS_feature-1_aspect-1_wrong in software requirement must contain exactly two "_"' + ) + end + end + + context 'when aspect is missing or empty' do + let(:filepath) { 'missing_aspect' } + + it 'throws error and aborts loading', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'invalid ID SRS_feature_ in software requirement; missing aspect/ratio after "SRS_feature' + ) + end + end + + context 'when feature is missing' do + let(:filepath) { 'missing_feature' } + + it 'throws error and exit the process', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'invalid ID SRS__aspect in software requirement; missing feature after "SRS_"' + ) + end + end + + context 'when ID only contains "SRS"' do + let(:filepath) { 'only_srs' } + + it 'throws error with meaningful message and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'invalid ID SRS_ in software requirement; missing feature after "SRS_"' + ) + end + end + + context 'when module contains multiple underscores' do + let(:filepath) { 'module_with_multiple_underscores' } + + it 'throws error with meaningful message and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include( + 'module SRS_feature_aspect in software requirement; must contain exactly one "_"' + ) + end + end + + context 'when module is missing feature' do + let(:filepath) { 'module_without_feature' } + + it 'throws error with meaningful message and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include( + 'module SRSFeature in software requirement must start with "SRS_"' + ) + end + end + + context 'when module does not start with SRS' do + let(:filepath) { 'module_without_srs' } + + it 'throws error with meaningful message and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include( + 'module SRSFeature_feature in software requirement must start with "SRS_"' + ) + end + end + + context 'when non-alphanumeric characters are present' do + context 'in feature' do + let(:filepath) { 'non_alphanumeric_in_feature' } + + it 'throws error and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'feature in ID SRS_feature@-1_aspect-1 in software requirement ' \ + 'contains non-alphanumeric characters' + ) + end + end + + context 'in aspect' do + let(:filepath) { 'non_alphanumeric_in_aspect' } + + it 'throws meaningful error and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'aspect in ID SRS_feature-1_aspect#-1 in software requirement ' \ + 'contains non-alphanumeric characters' + ) + end + end + + context 'in module' do + let(:filepath) { 'module_with_invalid_chars' } + + it 'throws meaningful error and exits', doc_refs: ['Dim_ConfigFiles_SRS'] do + subject + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include( + 'feature in module SRS_feature#1 in software requirement contains non-alphanumeric characters' + ) + end + end + end + end + end +end diff --git a/dim/spec/loader_general_spec.rb b/dim/spec/loader_general_spec.rb new file mode 100644 index 0000000..4e67090 --- /dev/null +++ b/dim/spec/loader_general_spec.rb @@ -0,0 +1,101 @@ +require_relative 'framework/helper' + +module Dim + describe 'Loading a file' do + context 'which does not exist' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/non_exist.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'does not exist' + end + end + + context 'which is empty and therefore invalid YAML' do + let(:filepath) { "#{TEST_INPUT_DIR}/invalid_input/no_yaml.dim" } + + it 'shall print warning message and skip loading of file', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{filepath}") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include("Warning: empty file detected; skipped loading of #{filepath}") + end + end + + context 'which has invalid yaml syntax' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/modules/yaml_syntax_invalid.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'mapping values are not allowed in this context at line 4 column 18' + expect(@test_stderr).to include filename + end + end + + context 'when enclosed file check is not skipped', doc_refs: ['Dim_loading_enclosedCheck'] do + it 'returns error code with message when file is missing' do + Test.main("check -i #{TEST_INPUT_DIR}/export_check/no_check_enclosed.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + end + end + + context 'when enclosed file check is skipped', doc_refs: ['Dim_loading_enclosedCheck'] do + it 'returns success code even when file is missing' do + Test.main("check -i #{TEST_INPUT_DIR}/export_check/no_check_enclosed.dim --no-check-enclosed") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'when Dim file has custom attributes defined' do + context "when custom attributes are provided with '-a' param while loading" do + it 'returns success code', doc_refs: ['Dim_AttrFiles_Attribute'] do + Test.main("check -i #{TEST_INPUT_DIR}/with_custom_attributes/test_module.dim -a #{TEST_INPUT_DIR}/with_custom_attributes/attributes.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + end + + context 'when custom attributes are not provided during loading' do + let(:filename) { "#{TEST_INPUT_DIR}/custom_attributes_without_attributes_file/test_module.dim" } + + it 'exits process with meaningful message', doc_refs: ['Dim_AttrFiles_Attribute'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include("Error: in #{filename}: attribute necessary not allowed") + end + end + end + + context 'loading a dim file with document and module' do + it 'shall exit and throw meaningful error message', doc_refs: ['Dim_loading_document'] do + Test.main("check -i #{TEST_INPUT_DIR}/document/document_and_modulename.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('module and document found in the file; please rename module to document') + end + end + + context 'when loading dim file with a empty document' do + it 'shall throw an error with meaningful error message', doc_refs: ['Dim_loading_document'] do + Test.main("check -i #{TEST_INPUT_DIR}/document/empty_document.dim") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'document must be a non-empty string' + end + end + + context 'when empty requirement is loaded' do + it 'loads the requirement with default attributes', doc_refs: ['Dim_loading_readGood'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/empty_requirement/module.dim") + req = loader.requirements['ESR_Test_empty'] + expect(req.type).to eq 'requirement' + end + end + + context 'when enclosed file contains absolute path' do + it 'shall throw an error with meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/invalid_enclosed.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include "'/module/valid_test_1.dim' must not be an absolute path" + end + end + end +end diff --git a/dim/spec/loader_property_spec.rb b/dim/spec/loader_property_spec.rb new file mode 100644 index 0000000..d0fcaf7 --- /dev/null +++ b/dim/spec/loader_property_spec.rb @@ -0,0 +1,44 @@ +require_relative 'framework/helper' + +module Dim + describe 'Loading a properties file' do + context 'with an invalid attribute type' do + let(:err_msg) { 'Error: in properties.yaml: The value for key asil in properties files must be a string' } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_PropFiles_Property'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_property/invalid_asil_value/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include err_msg + end + end + + context 'with non-allowed attribute value' do + let(:err_msg) do + "Error: in properties.yaml: The properties file includes an invalid asil value " \ + "'ASIL_Y' for module: test_module_3." + end + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_PropFiles_Property'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_property/invalid_asil_level/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include err_msg + end + end + + context 'with invalid YAML syntax' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_PropFiles_Property'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_property/invalid_file/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'Error: in properties.yaml:' + end + end + + context 'with empty yaml file' do + it 'shall print warning message and skip file loading', doc_refs: ['Dim_PropFiles_Property'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_property/empty_property/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + expect(@test_stdout).to include('Warning: empty file detected; skipped loading of properties.yaml') + end + end + end +end diff --git a/dim/spec/loader_requirement_spec.rb b/dim/spec/loader_requirement_spec.rb new file mode 100644 index 0000000..4ab65bc --- /dev/null +++ b/dim/spec/loader_requirement_spec.rb @@ -0,0 +1,94 @@ +require_relative 'framework/helper' + +module Dim + describe 'Loading a requirements file' do + context 'with invalid YAML character' do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/invalid_input/modules/yaml_syntax_invalid_char.dim") + it 'shall exchange the character with valid replacement', doc_refs: ['Dim_Syntax_InvalidChars'] do + req = loader.requirements['ESR-0010-4139'] + expect(req.data['text']).to match 'req[SOH]1' + end + end + + context 'with non-breaking spaces' do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/nb_space/module.dim") + it 'shall replace them with regular spaces', doc_refs: ['Dim_Syntax_InvalidChars'] do + expect(Dim::ExitHelper.exit_code).to be 0 + nbsreq = loader.requirements['Has_Non_Breaking_Space'] + expect(nbsreq.text).to eq 'ABC ABC' + expect(nbsreq.miscellaneous).to eq 'ABC ABC' + end + end + + context 'with utf-8 encoding' do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/different_encodings/utf-8_input.dim") + it 'shall not lead to an error', doc_refs: ['Dim_Syntax_utf8'] do + req = loader.requirements['test_id_1'] + expect(req.data['text']).to match 'µC shall trigger ä if µP reaches temperature x°.' + end + end + + context 'with windows1250 encoding' do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/different_encodings/Windows1250_input.dim") + it 'shall convert the data to UTF-8 and not lead to an error', doc_refs: ['Dim_Syntax_utf8'] do + req = loader.requirements['test_id_1'] + expect(req.data['text']).to match '?C shall trigger ? if ?P reaches temperature x?.' + end + end + + context 'with ISO8859-1 encoding' do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/different_encodings/ISO8859-1_input.dim") + it 'shall convert the data to UTF-8 and not lead to an error', doc_refs: ['Dim_Syntax_utf8'] do + req = loader.requirements['test_id_1'] + expect(req.data['text']).to match '?C shall trigger ? if ?P reaches temperature x?.' + end + end + + context 'with ISO8859-1 encoding but invalid syntax' do + let(:filename) { "#{TEST_INPUT_DIR}/different_encodings/ISO8859-1_input_invalid.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_Syntax_YAML'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'Error:' + expect(@test_stderr).to include filename + end + end + + context 'with invalid top level attribute' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/modules/toplevel_invalid.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ConfigFiles_Files'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'top level must be a hash with keys "module", "enclosed", "metadata" and/or unique ids' + expect(@test_stderr).to include filename + end + end + + context 'with invalid attribute name' do + let(:filename) { "#{TEST_INPUT_DIR}/invalid_input/modules/unallowed_attribute.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include 'attribute test not allowed' + expect(@test_stderr).to include filename + end + end + + context 'with attribute name used twice for a requirement' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_loading_readBad'] do + Test.main("check -i #{TEST_INPUT_DIR}/invalid_input/modules/duplicate_keys.dim") + expect(Dim::ExitHelper.exit_code).to be > 0 + # NOTE: line is optional, depends on the underlying psych version + expect(@test_stderr).to match(/Error: (|line 6: )found "text" twice which must be unique\./) + end + end + end +end diff --git a/dim/spec/options_spec.rb b/dim/spec/options_spec.rb new file mode 100644 index 0000000..e8a4847 --- /dev/null +++ b/dim/spec/options_spec.rb @@ -0,0 +1,77 @@ +require_relative 'framework/helper' + +module Dim + describe 'Command line option' do + context '--help' do + it ' shall show the usage information', doc_refs: ['Dim_CLI_help'] do + Test.main('--help') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include('Usage: dim.rb') + end + end + + context '-h' do + it ' shall show the usage information', doc_refs: ['Dim_CLI_help'] do + Test.main('-h') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include('Usage: dim.rb') + end + end + + context '--version' do + it ' shall show the current version', doc_refs: ['Dim_CLI_version'] do + Test.main('--version') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include(Dim::Ver.sion) + end + end + + context '-v' do + it ' shall show the current version', doc_refs: ['Dim_CLI_version'] do + Test.main('-v') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include(Dim::Ver.sion) + end + end + + context '--license' do + it ' shall show the current license', doc_refs: ['Dim_CLI_license'] do + Test.main('--license') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include('Copyright') + end + end + + context '-l' do + it ' shall show the current license', doc_refs: ['Dim_CLI_license'] do + Test.main('-l') + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stderr).to include('Copyright') + end + end + + context 'with unknown argument' do + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_CLI_exit'] do + Test.main("export -i #{TEST_INPUT_DIR}/one_module_in_several_files/Config.yml -o #{TEST_OUTPUT_DIR}/wrong --wrong-arg") + expect(@test_stderr).to include('invalid option: --wrong-arg') + expect(Dim::ExitHelper.exit_code).to be > 0 + end + end + + context 'when empty argument is passed' do + it 'shall throw an error and print error message', doc_ref: ['Dim_CLI_help'] do + Test.main("") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include('Usage: dim.rb [options]') + end + end + + context 'when invalid subcommand is passed' do + it 'shall throw an error and print error message', doc_ref: ['Dim_CLI_exit'] do + Test.main("wrong") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include('Usage: dim.rb [options]') + end + end + end +end diff --git a/dim/spec/output_spec.rb b/dim/spec/output_spec.rb new file mode 100644 index 0000000..da06c17 --- /dev/null +++ b/dim/spec/output_spec.rb @@ -0,0 +1,24 @@ +require_relative 'framework/helper' + +module Dim + class TestThreadOut + def flush + puts 'test123' + end + end + + describe 'Dim output' do + context 'using string streams' do + t = ThreadOut.new('test', 'test') + it 'shall not lead to exceptions if a pipe is broken', doc_refs: ['Dim_testing_output'] do + expect { t.flush }.not_to raise_error + end + it 'shall be readable by unit tests', doc_refs: ['Dim_testing_output'] do + s = TestThreadOut.new + Thread.current['test'] = s + expect { t.flush }.not_to raise_error + expect(@test_stdout).to include('test123') + end + end + end +end diff --git a/dim/spec/property_spec.rb b/dim/spec/property_spec.rb new file mode 100644 index 0000000..b37a264 --- /dev/null +++ b/dim/spec/property_spec.rb @@ -0,0 +1,121 @@ +require_relative 'framework/helper' + +module Dim + describe 'Properties file' do + context 'with asil and cal attributes' do + it 'shall resolve default-values', + doc_refs: %w[Dim_ConfigFiles_Property Dim_PropFiles_Property Dim_ReqFiles_asil Dim_ReqFiles_calString] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/auto_asilCal_check/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + + expect(loader.requirements['test_id_asilNotSet'].data['asil']).to eql 'not_set' + expect(loader.requirements['test_id_asilNone'].data['asil']).to eql 'ASIL_A' + expect(loader.requirements['test_id_asilSet'].data['asil']).to eql 'ASIL_D' + expect(loader.requirements['test_id_asilNotSet'].data['cal']).to eql 'not_set' + expect(loader.requirements['test_id_asilNone'].data['cal']).to eql 'not_set' + expect(loader.requirements['test_id_asilSet'].data['cal']).to eql 'QM' + + expect(loader.requirements['test_id_asilCalNotSet'].data['asil']).to eql 'not_set' + expect(loader.requirements['test_id_asilCalNone'].data['asil']).to eql 'ASIL_B' + expect(loader.requirements['test_id_asilCalSet'].data['asil']).to eql 'ASIL_D' + expect(loader.requirements['test_id_asilCalNotSet'].data['cal']).to eql 'not_set' + expect(loader.requirements['test_id_asilCalNone'].data['cal']).to eql 'CAL_4' + expect(loader.requirements['test_id_asilCalSet'].data['cal']).to eql 'QM' + + expect(loader.requirements['test_id_noneNotSet'].data['asil']).to eql 'not_set' + expect(loader.requirements['test_id_noneNone'].data['asil']).to eql 'not_set' + expect(loader.requirements['test_id_noneSet'].data['asil']).to eql 'ASIL_D' + expect(loader.requirements['test_id_noneNotSet'].data['cal']).to eql 'not_set' + expect(loader.requirements['test_id_noneNone'].data['cal']).to eql 'not_set' + expect(loader.requirements['test_id_noneSet'].data['cal']).to eql 'QM' + end + end + + context 'with references defined' do + it 'shall be checked for consistency in context of the loaded configuration', + doc_refs: %w[Dim_ConfigFiles_Property Dim_PropFiles_Property Dim_loading_checkCyclic + Dim_loading_checkMissing] do + Test.main("check -i #{TEST_INPUT_DIR}/property_file_refs/Config_circular_reference.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('"ref_test_module1_req1" is cyclically referenced: ref_test_module1_req1 -> ref_test_module2_req1 -> ref_test_module1_req1') + expect(@test_stderr).to include('spec/test_input/property_file_refs/ref_test_module1.dim') + + Test.main("check -i #{TEST_INPUT_DIR}/property_file_refs/Config_invalid_reference.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include('"ref_test_module1_req1" refers to non-existing "ref_test_module1_req3"') + expect(@test_stderr).to include('spec/test_input/property_file_refs/ref_test_module1.dim') + end + end + + #TODO: Remove this when test_setups is removed + context 'when test_setups are defined' do + it 'it also adds the value for verification_methods', doc_refs: [] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/property_file_insertion/test_setups/Config.dim") + expect(loader.requirements['ID_empty_test_setups'].verification_methods).to eq ['off_target'] + end + end + + context 'with dim attributes defined' do + it 'shall resolve default-values and empty attributes of dim modules', + doc_refs: %w[Dim_ConfigFiles_Property Dim_PropFiles_Property] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/property_file_insertion/Config.dim") + expect(Dim::ExitHelper.exit_code).to be 0 + + expect(loader.requirements['test_module_for_insertion_empty'].data['text']).to eql 'inserted text from properties file' + expect(loader.requirements['test_module_for_insertion_empty'].data['asil']).to eql 'ASIL_B' + expect(loader.requirements['test_module_for_insertion_empty'].data['verification_criteria']).to eql 'inserted verification criteria' + expect(loader.requirements['test_module_for_insertion_empty'].data['cal']).to eql 'QM' + expect(loader.requirements['test_module_for_insertion_empty'].data['feature']).to eql 'inserted_feature' + expect(loader.requirements['test_module_for_insertion_empty'].data['change_request']).to eql 'inserted_CR' + expect(loader.requirements['test_module_for_insertion_empty'].data['tags']).to eql 'legal, sys' + expect(loader.requirements['test_module_for_insertion_empty'].data['developer']).to eql 'inserted developer' + expect(loader.requirements['test_module_for_insertion_empty'].data['tester']).to eql 'inserted tester' + expect(loader.requirements['test_module_for_insertion_empty'].data['test_setups']).to eql 'manual' + expect(loader.requirements['test_module_for_insertion_empty'].data['verification_methods']).to eql 'manual' + expect(loader.requirements['test_module_for_insertion_empty'].data['status']).to eql 'valid' + expect(loader.requirements['test_module_for_insertion_empty'].data['review_status']).to eql 'rejected' + expect(loader.requirements['test_module_for_insertion_empty'].data['comment']).to eql 'inserted comment' + expect(loader.requirements['test_module_for_insertion_empty'].data['miscellaneous']).to eql 'inserted miscellaneous' + expect(loader.requirements['test_module_for_insertion_empty'].data['sources']).to eql 'inserted sources' + expect(loader.requirements['test_module_for_insertion_empty'].data['miscellaneous']).to eql 'inserted miscellaneous' + expect(loader.requirements['test_module_for_insertion_empty'].data['refs']).to eql 'test_module_no_insertion_empty' + + expect(loader.requirements['test_module_for_insertion_not_empty'].data['text']).to eql 'test text' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['asil']).to eql 'QM' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['verification_criteria']).to eql 'test criteria' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['cal']).to eql 'CAL_4' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['feature']).to eql 'test_feature' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['change_request']).to eql 'test_CR' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['tags']).to eql 'swa' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['developer']).to eql 'test_developer' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['test_setups']).to eql 'none' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['verification_methods']).to eql 'none' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['status']).to eql 'invalid' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['review_status']).to eql 'unclear' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['comment']).to eql 'test_comment' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['miscellaneous']).to eql 'test_misc' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['sources']).to eql 'test_source' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['miscellaneous']).to eql 'test_misc' + expect(loader.requirements['test_module_for_insertion_not_empty'].data['refs']).to eql 'test_module_for_insertion_empty' + + expect(loader.requirements['test_module_no_insertion_empty'].data['type']).to eql 'requirement' + expect(loader.requirements['test_module_no_insertion_empty_text'].data['text']).to eql '' + + expect(loader.requirements['test_module_text_insertion_text'].data['text']).to eql 'test text' + expect(loader.requirements['test_module_text_insertion_no_text'].data['text']).to eql "multi,\nline test\ntext from property\nfile!" + expect(loader.requirements['test_module_text_insertion_no_text'].data['asil']).to eql 'ASIL_C' + + expect(loader.requirements['test_module_for_requirement_empty'].data['type']).to eq 'information' + expect(loader.requirements['test_module_for_requirement_info'].data['type']).to eq 'information' + expect(loader.requirements['test_module_for_requirement_req'].data['type']).to eq 'requirement' + + expect(loader.requirements['test_module_for_information_empty'].data['type']).to eq 'requirement' + expect(loader.requirements['test_module_for_information_info'].data['type']).to eq 'information' + expect(loader.requirements['test_module_for_information_req'].data['type']).to eq 'requirement' + end + end + end +end diff --git a/dim/spec/requirement_spec.rb b/dim/spec/requirement_spec.rb new file mode 100644 index 0000000..665bf8f --- /dev/null +++ b/dim/spec/requirement_spec.rb @@ -0,0 +1,1158 @@ +require_relative 'framework/helper' + +# rubocop:disable Metric/BlockLength, Layout/LineLength +module Dim + describe 'Requirements file attribute' do + context 'module' do + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/module/invalid_type.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_document'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: module name must be a non-empty string" + end + end + + context 'when value string is empty' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/module/empty.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_document'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: module name must be a non-empty string" + end + end + + it 'shall default to the folder name of the requirements file', doc_refs: ['Dim_ReqFiles_document'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/module/default.dim") + expect(loader.requirements['ID_0'].moduleName).to eq('module') + expect(loader.requirements['ID_0'].document).to eq('module') + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + it 'shall be non-unique', doc_refs: ['Dim_ReqFiles_document'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/module/config.dim") + expect(loader.requirements['ID_1'].moduleName).to eq('Name1') + expect(loader.requirements['ID_1'].document).to eq('Name1') + expect(loader.requirements['ID_2'].document).to eq('Name1') + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + context 'when module is missing' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/module/without_module.dim" } + + it 'shall throw an error', doc_refs: ['Dim_ReqFiles_MissingDocument'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: Document name is missing; please add document name" + end + end + end + + context 'enclosed' do + it 'shall be a string or an array of strings', doc_refs: ['Dim_ReqFiles_enclosed'] do + Test.main("export -i #{TEST_INPUT_DIR}/reqs/enclosed/string.dim -o #{TEST_OUTPUT_DIR}/out_string -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(File.exist?("#{TEST_OUTPUT_DIR}/out_string/enclosed/data/a.txt")).to be true + Test.main("export -i #{TEST_INPUT_DIR}/reqs/enclosed/array.dim -o #{TEST_OUTPUT_DIR}/out_array -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(File.exist?("#{TEST_OUTPUT_DIR}/out_array/enclosed/data/b.txt")).to be true + expect(File.exist?("#{TEST_OUTPUT_DIR}/out_array/enclosed/data/c.txt")).to be true + end + + it 'shall be a optional', doc_refs: ['Dim_ReqFiles_enclosed'] do + Test.main("export -i #{TEST_INPUT_DIR}/reqs/enclosed/default.dim -o #{TEST_OUTPUT_DIR}/out_default -f rst") + expect(Dim::ExitHelper.exit_code).to eq 0 + files = Dir.glob("#{TEST_OUTPUT_DIR}/out_default/enclosed/**/*") + # only Requirements.rst means no additional files + expect(files.length).to be 1 + expect(files[0]).to include('Requirements.rst') + end + + context 'when file does not exists' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/enclosed/notexist.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_enclosed'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'module_non_existing.dim" in "enclosed" does not refer to any existing file' + expect(@test_stderr).to include filename + end + end + + context 'when string is empty' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/enclosed/empty_string.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_enclosed'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: \"enclosed\" must be a non-empty string or an array of non-empty strings" + end + end + + context 'when string includes ".."' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/enclosed/dotdot.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_enclosed'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: '../enclosed/dotdot.dim' must not include '..'" + end + end + + context 'when file path contains the superfluous characters' do + let(:file_path) { "#{TEST_INPUT_DIR}/reqs/enclosed/dot.dim" } + let(:loader) { Dim::Loader.new } + + it 'removes from file path' do + loader.load(file: file_path) + expect(loader.module_data['enclosed'][:files][file_path]).to match_array ['dot.dim'] + end + end + + context 'when enclosed files uses backward slash in filepath' do + let(:file_path) { "#{TEST_INPUT_DIR}/reqs/enclosed/backward.dim" } + let(:loader) { Dim::Loader.new } + let(:err) do + "Warning: Backward slashes detected in filepath .\\data\\a.txt. Use '/' over '\\' in filepath" + end + + it 'warns user about backward slash in the filepath' do + loader.load(file: file_path) + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include err + end + end + end + + context 'metadata' do + it 'shall be an optional string', doc_refs: ['Dim_ReqFiles_metadata'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/metadata/default.dim") + expect(loader.metadata['Name1']).to eq('') + expect(Dim::ExitHelper.exit_code).to eq 0 + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/metadata/data.dim") + expect(loader.metadata['Name1']).to eq("Test\nABC") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + context 'when value is not a string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/metadata/invalid_type.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_metadata'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: metadata must be a string" + end + end + end + + context 'id' do + it 'in regular form is a key of a collection of key/values pairs of strings', + doc_refs: ['Dim_ReqFiles_regularYaml'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/id/invalid_value.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "CompanyName" must be String not Hash' + expect(@test_stderr).to include 'reqs/id/invalid_value.dim' + + Test.main("check -i #{TEST_INPUT_DIR}/reqs/id/invalid_key.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attributes for id "test_id" must be key-value pairs' + expect(@test_stderr).to include 'reqs/id/invalid_key.dim' + end + + context 'when in short form is a key of a key/value pair of strings' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/id/invalid_short.dim" } + + it 'throws error and prints meaningful error message', doc_refs: ['Dim_ReqFiles_shortYaml'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'Invalid short-form in requirement "test_key", valid forms are "h " or "info "' + expect(@test_stderr).to include filename + end + end + + it 'without any data shall be accepted without errors', doc_refs: ['Dim_ReqFiles_id'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/id/only_id.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + it 'not specified (no requirements) shall not lead to an error', doc_refs: ['Dim_ReqFiles_id'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/id/empty.dim") + expect(loader.requirements.length).to be 0 + expect(Dim::ExitHelper.exit_code).to eq 0 + end + + context 'when ","' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/id/comma.dim" } + + it 'shall throw an error and print a meaningful error message', doc_refs: ['Dim_ReqFiles_id'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include("Error: in #{filename}: Disallowed ',' found in id \"ESR_Test,1\"") + end + end + end + + context 'type' do + it 'shall be requirement, information and heading_0 to heading_100', doc_refs: ['Dim_ReqFiles_type'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/type/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_r'].type).to eq('requirement') + expect(loader.requirements['id_i'].type).to eq('information') + expect(loader.requirements['id_h0'].type).to eq('heading_0') + expect(loader.requirements['id_h1'].type).to eq('heading_1') + expect(loader.requirements['id_h100'].type).to eq('heading_100') + end + + it 'requirement shall be the default', doc_refs: ['Dim_ReqFiles_type'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/type/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].type).to eq('requirement') + end + + it 'unknown shall throw an error and print a meaningful error message', doc_refs: ['Dim_ReqFiles_type'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/type/unknown.dim") + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include 'attribute "type" must not be "unknown" (id: ID_unknown). "type" must be exactly one of "requirement", "information", "heading_". Default is "requirement".' + end + + it 'empty string shall throw an error and print a meaningful error message', doc_refs: ['Dim_ReqFiles_type'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/type/empty.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'attribute "type" must not be "" (id: ID_T1). "type" must be exactly one of "requirement", "information", "heading_". Default is "requirement".' + end + + it 'heading level too high shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_type'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/type/heading101.dim") + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include 'heading level above 100 is not allowed and makes absolutely no sense: heading' + end + + it 'shall be h0 to h100 and info in short form', + doc_refs: %w[Dim_ReqFiles_shortHeadingForm Dim_ReqFiles_shortInfoForm] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/type/valid_short.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['test_id_h0'].type).to eq('heading_0') + expect(loader.requirements['test_id_h1'].type).to eq('heading_1') + expect(loader.requirements['test_id_h100'].type).to eq('heading_100') + expect(loader.requirements['test_id_info'].type).to eq('information') + end + end + + context 'text' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_text'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_singleLine'].text).to eq('Single line') + expect(loader.requirements['ID_multiLine'].text).to eq("Multi\nline") + expect(loader.requirements['ID_empty'].text).to eq('') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_text'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_default'].text).to eq('') + end + + it 'shall be the rest after h0 to h100 and info in short form', + doc_refs: %w[Dim_ReqFiles_shortHeadingForm Dim_ReqFiles_shortInfoForm] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text/valid_short.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['test_id_h0'].text).to eq('H0') + expect(loader.requirements['test_id_h1'].text).to eq('H1') + expect(loader.requirements['test_id_h100'].text).to eq('H100') + expect(loader.requirements['test_id_info'].text).to eq("Short\ninformation") + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/text/no_string.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_text'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"text\" must be String not Array" + end + end + end + + context 'verification_criteria' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_verificationCriteria'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/vc/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v'].verification_criteria).to eq('This is a VC.') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_verificationCriteria'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/vc/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].verification_criteria).to eq('') + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/vc/invalid_type.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_verificationCriteria'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"verification_criteria\" must be String not Array" + end + end + end + + context 'feature' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_feature'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/feature/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v'].feature).to eq('This is a feature.') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_feature'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/feature/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].feature).to eq('') + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/feature/invalid_type.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_feature'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"feature\" must be String not Array" + end + end + end + + context 'change_request' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_changeRequest'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/cr/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v'].change_request).to eq('This is a CR.') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_changeRequest'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/cr/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].change_request).to eq('') + end + + context 'value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/cr/invalid_type.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_changeRequest'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"change_request\" must be String not Array" + end + end + end + + context 'tags' do + it 'shall be a comma separated string', doc_refs: ['Dim_ReqFiles_tags'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tags_attr/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].tags).to match_array(['memory']) + expect(loader.requirements['id_v2'].tags).to include('covered') + expect(loader.requirements['id_v2'].tags).to include('swa') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_tags'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tags_attr/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].tags).to eq([]) + end + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_tags'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/tags_attr/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "tags" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/tags_attr/invalid_type.dim:' + end + + it 'with duplicates shall not throw an error but duplicates are removed', doc_refs: ['Dim_ReqFiles_tags'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tags_attr/duplicate.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_duplicate'].tags).to match_array(%w[memory covered]) + end + + it 'shall not throw an error if an unknown tag is used', + doc_refs: ['Dim_ReqFiles_tags'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/tags_attr/unknown.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(@test_stdout).to include 'Done.' + end + end + + context 'asil' do + it 'shall be a predefined string', doc_refs: ['Dim_ReqFiles_asil'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/asil/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].asil).to eq('QM') + expect(loader.requirements['id_v2'].asil).to eq('QM(A)') + expect(loader.requirements['id_v3'].asil).to eq('ASIL_D') + expect(loader.requirements['id_v4'].asil).to eq('not_set') + expect(loader.requirements['id_v5'].asil).to eq('not_set') + end + + it 'shall be default=not_set if not specified', doc_refs: ['Dim_ReqFiles_asil'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/asil/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].asil).to eq('not_set') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_asil'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/asil/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "asil" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/asil/invalid_type.dim:' + end + + it 'shall throw an error and print a meaningful error message if value is an empty string', + doc_refs: ['Dim_ReqFiles_asil'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/asil/empty.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "asil" must not be "" (id: id_e). "asil" must be exactly one of "not_set",' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/asil/empty.dim:' + end + end + + context 'cal' do + it 'shall be a predefined string', doc_refs: ['Dim_ReqFiles_calString'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/cal/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].cal).to eq('CAL_4') + expect(loader.requirements['id_v2'].cal).to eq('QM') + expect(loader.requirements['id_v3'].cal).to eq('not_set') + expect(loader.requirements['id_v4'].cal).to eq('not_set') + end + + it 'shall be not_set if not specified', doc_refs: ['Dim_ReqFiles_calString'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/cal/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].cal).to eq('not_set') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_calString'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/cal/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "cal" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/cal/invalid_type.dim:' + end + + it 'shall throw an error and print a meaningful error message if value is an empty string', + doc_refs: ['Dim_ReqFiles_calString'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/cal/empty.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "cal" must not be "" (id: id_e). "cal" must be exactly one of "QM", "CAL_1", "CAL_2", "CAL_3", "CAL_4", "not_set". Default is "not_set"' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/cal/empty.dim' + end + end + + context 'developer' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_developer'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/developer/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].developer).to eq(['Hallo']) + expect(loader.requirements['id_v2'].developer).to eq([]) + expect(loader.requirements['id_v3'].developer).to eq(["A\nB"]) + end + + it 'shall resolve if missing', doc_refs: ['Dim_ReqFiles_developer'] do + # category set (config loaded) + lc = Dim::Loader.new + lc.load(file: "#{TEST_INPUT_DIR}/reqs/developer/resolve_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lc.requirements['input_r'].developer).to eql [] + expect(lc.requirements['input_i'].developer).to eql [] + expect(lc.requirements['module_r'].developer).to eql ['CompanyName'] + expect(lc.requirements['module_i'].developer).to eql [] + # category unspecified + lm = Dim::Loader.new + lm.load(file: "#{TEST_INPUT_DIR}/reqs/developer/resolve_module.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lm.requirements['module_r'].developer).to eql [] + expect(lm.requirements['module_i'].developer).to eql [] + end + + it 'shall be not_set by default', doc_refs: ['Dim_ReqFiles_developer'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/developer/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].developer).to eq [] + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/developer/default_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].developer).to eq ['CompanyName'] + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_developer'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/developer/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "developer" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/developer/invalid_type.dim:' + end + end + + context 'tester' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_tester'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tester/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].tester).to eq ['Hallo'] + expect(loader.requirements['id_v2'].tester).to eq [] + expect(loader.requirements['id_v3'].tester).to eq ["A\nB"] + end + + it 'shall resolve if not preset', doc_refs: ['Dim_ReqFiles_tester'] do + # category set (config loaded) + lc = Dim::Loader.new + lc.load(file: "#{TEST_INPUT_DIR}/reqs/tester/resolve_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lc.requirements['input_r'].tester).to eql [] + expect(lc.requirements['input_i'].tester).to eql [] + expect(lc.requirements['module_r'].tester).to eql ['CompanyName'] + expect(lc.requirements['module_i'].tester).to eql [] + # category unspecified + lm = Dim::Loader.new + lm.load(file: "#{TEST_INPUT_DIR}/reqs/tester/resolve_module.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lm.requirements['module_r'].tester).to eql [] + expect(lm.requirements['module_i'].tester).to eql [] + end + + it 'shall be not_set by default', doc_refs: ['Dim_ReqFiles_tester'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tester/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].tester).to eq [] + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/tester/default_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].tester).to eq ['CompanyName'] + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_tester'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/tester/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "tester" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/tester/invalid_type.dim:' + end + end + + context 'test_setups' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_testSetups'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/ts/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].test_setups).to eq ['none'] + expect(loader.requirements['id_v2'].test_setups).to match_array(%w[off_target on_target manual]) + end + + it 'shall resolve default', doc_refs: ['Dim_ReqFiles_testSetups'] do + # category set (config loaded) + lc = Dim::Loader.new + lc.load(file: "#{TEST_INPUT_DIR}/reqs/ts/resolve_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lc.requirements['input_r'].test_setups).to eql ['none'] + expect(lc.requirements['input_i'].test_setups).to eql ['none'] + expect(lc.requirements['input_p'].test_setups).to eql ['none'] + expect(lc.requirements['input_t'].test_setups).to eql ['none'] + expect(lc.requirements['module_r'].test_setups).to eql ['off_target'] + expect(lc.requirements['module_i'].test_setups).to eql ['none'] + expect(lc.requirements['module_p'].test_setups).to eql ['none'] + expect(lc.requirements['module_t'].test_setups).to eql ['off_target'] + expect(lc.requirements['software_r'].test_setups).to eql ['on_target'] + expect(lc.requirements['software_i'].test_setups).to eql ['none'] + expect(lc.requirements['software_p'].test_setups).to eql ['none'] + expect(lc.requirements['software_t'].test_setups).to eql ['off_target'] + # category unspecified + lm = Dim::Loader.new + lm.load(file: "#{TEST_INPUT_DIR}/reqs/ts/resolve_module.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lm.requirements['module_r'].test_setups).to eql ['none'] + expect(lm.requirements['module_i'].test_setups).to eql ['none'] + expect(lm.requirements['module_p'].test_setups).to eql ['none'] + expect(lm.requirements['module_t'].test_setups).to eql ['none'] + ls = Dim::Loader.new + ls.load(file: "#{TEST_INPUT_DIR}/reqs/ts/resolve_software.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(ls.requirements['software_r'].test_setups).to eql ['none'] + expect(ls.requirements['software_i'].test_setups).to eql ['none'] + expect(ls.requirements['software_p'].test_setups).to eql ['none'] + expect(ls.requirements['software_t'].test_setups).to eql ['none'] + end + + it 'shall be nil by default', doc_refs: ['Dim_ReqFiles_testSetups'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/ts/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].test_setups).to eq ['none'] + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/ts/default_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].test_setups).to eq ['off_target'] + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_testSetups'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/ts/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "test_setups" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/ts/invalid_type.dim:' + end + + it 'with duplicates shall not throw an error but duplicates are removed', doc_refs: ['Dim_ReqFiles_testSetups'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/ts/duplicate.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_duplicate'].test_setups).to match_array(%w[off_target on_target]) + end + + it 'unknown shall throw an error and print a meaningful error message', doc_refs: ['Dim_ReqFiles_testSetups'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/ts/unknown.dim") + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include ' attribute "test_setups" is invalid: "unknown" (id: id_unknown). "test_setups" must be one or more of "none", "off_target", "on_target", "manual".' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/ts/unknown.dim:' + end + + it 'shall throw error when empty value is set', doc_refs: ['Dim_ReqFiles_testSetups'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/ts/empty.dim") + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include 'attribute "test_setups" is invalid: "" (id: id_d). "test_setups" must be one or more of "none", "off_target", "on_target", "manual".' + end + + it 'shall throw an error and print a meaningful error message if none is used with another enum value', + doc_refs: ['Dim_ReqFiles_testSetups'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/ts/combined_none.dim") + expect(Dim::ExitHelper.exit_code).to be > 0 + expect(@test_stderr).to include "verification_methods or test_setups for \"test_id_1\" can't include 'none' along with on_target" + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/ts/combined_none.dim:' + end + end + + context 'verification_methods' do + context 'when Dim file contains valid data' do + let(:loader) { Dim::Loader.new } + + before do + loader.load(file: 'spec/test_input/verification_methods/verification_methods.dim') + end + + context 'when verification_methods and test_setups are empty in dim file' do + let(:requirement) { loader.requirements['ID_1'] } + + it 'shall have test_setups and verification_methods set to none', + doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + expect(requirement.test_setups).to match_array ['none'] + expect(requirement.data['test_setups']).to eq 'none' + + expect(requirement.verification_methods).to match_array ['none'] + expect(requirement.data['verification_methods']).to eq 'none' + end + end + + context 'when verification_methods present in the Dim file while test_setups is missing' do + let(:requirement_2) { loader.requirements['ID_2'] } + let(:requirement_3) { loader.requirements['ID_3'] } + let(:requirement_4) { loader.requirements['ID_4'] } + + let(:expected_array) { %w[off_target on_target] } + + it 'shall return test_setups same as verification_methods', + doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + expect(requirement_2.test_setups).to match_array expected_array + expect(requirement_2.verification_methods).to match_array expected_array + + expect(requirement_3.test_setups).to match_array ['off_target'] + expect(requirement_3.verification_methods).to match_array ['off_target'] + + expect(requirement_4.test_setups).to match_array expected_array + expect(requirement_4.verification_methods).to match_array expected_array + + expect(requirement_2.data['test_setups']).to eq 'off_target, on_target' + expect(requirement_2.data['verification_methods']).to eq 'off_target, on_target' + + expect(requirement_3.data['test_setups']).to eq 'off_target' + expect(requirement_3.data['verification_methods']).to eq 'off_target' + + expect(requirement_4.data['test_setups']).to eq 'off_target, on_target' + expect(requirement_4.data['verification_methods']).to eq 'off_target, on_target' + end + end + + context 'when verification_methods is missing from Dim file and test_setups are present' do + let(:requirement) { loader.requirements['ID_5'] } + + it 'shall have values from test_setups added to verification_methods', + doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + expect(requirement.test_setups).to match_array %w[manual off_target on_target] + expect(requirement.verification_methods).to match_array %w[manual off_target on_target] + + expect(requirement.data['test_setups']).to eq 'off_target, on_target, manual' + expect(requirement.data['verification_methods']).to eq 'off_target, on_target, manual' + end + end + end + + context 'when verification_methods contains none and test_setups is present in the Dim file' do + it 'shall throw an error with the meaningful error message', + doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + Test.main("check -i spec/test_input/verification_methods/none_verification_methods.dim") + + expect(Dim::ExitHelper.exit_code).to be 1 + expect(@test_stderr).to include("test_setups for \"ID_1\" can't include 'none' along with off_target") + end + end + + context 'when verification_methods are present in Dim and test_setups is none' do + it 'shall throw an error with a meaningful error message', + doc_refs: %w[Dim_ReqFiles_verificationMethods_backward Dim_ReqFiles_verificationMethods] do + Test.main("check -i spec/test_input/verification_methods/none_test_setups.dim") + + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include("verification_methods or test_setups for \"ID_1\" can't include 'none' along with off_target") + end + end + + context 'when verification_methods and test_setups in Dim contains none' do + let(:loader) { Dim::Loader.new } + let(:requirement) { loader.requirements['ID_1'] } + + before do + loader.load(file: 'spec/test_input/verification_methods/all_none.dim') + end + + it 'shall load Dim', doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + expect(requirement.test_setups).to match_array ['none'] + expect(requirement.verification_methods).to match_array ['none'] + end + end + + context 'when test_setups is none or verification_methods is none' do + it 'shall load dim file', doc_refs: %w[Dim_ReqFiles_verificationMethods Dim_ReqFiles_verificationMethods_backward] do + loader = Dim::Loader.new + loader.load(file: 'spec/test_input/verification_methods/single_none.dim') + + expect(loader.requirements['ID_1'].test_setups).to eq ['none'] + expect(loader.requirements['ID_1'].verification_methods).to eq ['none'] + expect(loader.requirements['ID_1'].data['test_setups']).to eq 'none' + expect(loader.requirements['ID_1'].data['verification_methods']).to eq 'none' + + expect(loader.requirements['ID_2'].test_setups).to eq ['none'] + expect(loader.requirements['ID_2'].verification_methods).to eq ['none'] + end + end + end + + context 'status' do + it 'shall be a predefined string', doc_refs: ['Dim_ReqFiles_status'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/status/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_draft'].status).to eq('draft') + expect(loader.requirements['id_valid'].status).to eq('valid') + expect(loader.requirements['id_invalid'].status).to eq('invalid') + end + + it 'shall resolve if missing', doc_refs: ['Dim_ReqFiles_status'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/status/resolve.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_r'].status).to eq('draft') + expect(loader.requirements['id_i'].status).to eq('draft') + expect(loader.requirements['id_h'].status).to eq('valid') + end + + it 'shall resolve as default nil', doc_refs: ['Dim_ReqFiles_status'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/status/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_r'].status).to eq('draft') + expect(loader.requirements['id_i'].status).to eq('draft') + expect(loader.requirements['id_h'].status).to eq('valid') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_status'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/status/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "status" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/status/invalid_type.dim:' + end + + it 'shall throw an error and print a meaningful error message if value is an empty string', + doc_refs: ['Dim_ReqFiles_status'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/status/empty.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "status" must not be "" (id: id_empty). "status" must be exactly one of "valid",' + end + + it 'shall throw an error and print a meaningful error message if value is unknown', + doc_refs: ['Dim_ReqFiles_status'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/status/unknown.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "status" must not be "unknown" (id: id_unknown). "status" must be exactly one of "valid",' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/status/unknown.dim:' + end + end + + context 'review_status' do + it 'shall be a predefined string', doc_refs: ['Dim_ReqFiles_reviewStatus'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/rs/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_accepted'].review_status).to eq('accepted') + expect(loader.requirements['id_rejected'].review_status).to eq('rejected') + expect(loader.requirements['id_unclear'].review_status).to eq('unclear') + expect(loader.requirements['id_not_reviewed'].review_status).to eq('not_reviewed') + expect(loader.requirements['id_not_relevant'].review_status).to eq('not_relevant') + end + + it 'shall resolve if not added', doc_refs: ['Dim_ReqFiles_reviewStatus'] do + lm = Dim::Loader.new + lm.load(file: "#{TEST_INPUT_DIR}/reqs/rs/resolve_module.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lm.requirements['module_r'].review_status).to eq('not_reviewed') + lc = Dim::Loader.new + lc.load(file: "#{TEST_INPUT_DIR}/reqs/rs/resolve_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lc.requirements['input_r'].review_status).to eq('not_reviewed') + expect(lc.requirements['module_r'].review_status).to eq('accepted') + end + + it 'shall not_set as default not_set', doc_refs: ['Dim_ReqFiles_reviewStatus'] do + lm = Dim::Loader.new + lm.load(file: "#{TEST_INPUT_DIR}/reqs/rs/default_module.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lm.requirements['module_r'].review_status).to eq('not_reviewed') + lc = Dim::Loader.new + lc.load(file: "#{TEST_INPUT_DIR}/reqs/rs/default_config.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(lc.requirements['input_r'].review_status).to eq('not_reviewed') + expect(lc.requirements['module_r'].review_status).to eq('accepted') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_reviewStatus'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/rs/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "review_status" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/rs/invalid_type.dim:' + end + + it 'shall throw an error and print a meaningful error message if value is an empty string', + doc_refs: ['Dim_ReqFiles_reviewStatus'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/rs/empty.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "review_status" must not be "" (id: id_empty). "review_status" must be exactly one of "accepted",' + end + + it 'shall throw an error and print a meaningful error message if value is unknown', + doc_refs: ['Dim_ReqFiles_reviewStatus'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/rs/unknown.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'attribute "review_status" must not be "unknown" (id: id_unknown). "review_status" must be exactly one of "accepted",' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/rs/unknown.dim:' + end + end + + context 'comment' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_comment'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/comment/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v'].comment).to eq('This is a comment.') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_comment'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/comment/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].comment).to eq('') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_comment'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/comment/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "comment" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/comment/invalid_type.dim:' + end + end + + context 'miscellaneous' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_miscellaneous'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/misc/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v'].miscellaneous).to eq('This is a miscellaneous.') + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_miscellaneous'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/misc/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].miscellaneous).to eq('') + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_miscellaneous'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/misc/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "miscellaneous" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/misc/invalid_type.dim:' + end + end + + context 'sources' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_sources'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/sources/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].sources).to match_array(%w[a.cpp]) + expect(loader.requirements['id_v2'].sources).to match_array(%w[a.cpp b.cpp]) + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_sources'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/sources/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].sources).to eq [] + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_sources'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/sources/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "sources" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/sources/invalid_type.dim:' + end + + it 'with duplicates shall not throw an error but duplicates are removed', doc_refs: ['Dim_ReqFiles_sources'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/sources/duplicate.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].sources).to match_array(%w[b.cpp a.cpp]) + end + end + + context 'refs' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_refs'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/refs/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_v1'].refs).to match_array(%w[id_v3]) + expect(loader.requirements['id_v2'].refs).to match_array(%w[id_v3 id_v1]) + end + + it 'shall be an empty string if not specified', doc_refs: ['Dim_ReqFiles_refs'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/refs/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].refs).to eq [] + end + + it 'shall throw an error and print a meaningful error message if value is no string', + doc_refs: ['Dim_ReqFiles_refs'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/refs/invalid_type.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include 'value of attribute "refs" must be String not Array' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/refs/invalid_type.dim:' + end + + it 'with duplicates shall not throw an error but duplicates are removed', doc_refs: ['Dim_ReqFiles_refs'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/refs/duplicate.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['id_d'].refs).to match_array(%w[id_v3 id_v2]) + end + + it 'with references to non-existing requirements shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_refs'] do + Test.main("check -i #{TEST_INPUT_DIR}/reqs/refs/unresolved.dim") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include '"id_v1" refers to non-existing "id_v2"' + expect(@test_stderr).to include 'Error: in spec/test_input/reqs/refs/unresolved.dim:' + end + end + + context 'when heading method is called on the requirement object' do + it 'shall return the heading_1 when heading is called on the requirements object', doc_refs: ['Dim_ReqFiles_type'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/language/module_ok.dim") + req = loader.requirements['ESR_Test_1'] + + expect(req.heading_2).to eq 'heading_2' + end + end + + context 'language variants of text' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text_lang/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ESR_Test_1'].text).to eq("juhu\njuhu") + expect(loader.requirements['ESR_Test_1'].text_spanish).to eq('ole') + expect(loader.requirements['ESR_Test_2'].text).to eq('mist') + expect(loader.requirements['ESR_Test_2'].text_english).to eq('damn') + expect(loader.requirements['ESR_Test_3'].text).to eq('achso') + expect(loader.requirements['ESR_Test_3'].text_french).to eq('') + end + + it 'shall be an empty string if not specified in this particular requirement but specified in another requirement', + doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text_lang/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_default1'].text_german).to eq('') + expect(loader.requirements['ID_default1'].text_french).to eq('bla') + expect(loader.requirements['ID_default2'].text_german).to eq('') + expect(loader.requirements['ID_default2'].text_french).to eq('') + + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/text_lang/not_specified.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_not'].respond_to?('text_german')).to be(true) + expect(loader.requirements['ID_not'].respond_to?('text_english')).to be(false) + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/text_lang/no_string.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_language'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"text_german\" must be String not Array" + end + end + end + + context 'when language variants of verification_criteria' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/vc_lang/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ESR_Test_1'].verification_criteria).to eq("juhu\njuhu") + expect(loader.requirements['ESR_Test_1'].verification_criteria_spanish).to eq('ole') + expect(loader.requirements['ESR_Test_2'].verification_criteria).to eq('mist') + expect(loader.requirements['ESR_Test_2'].verification_criteria_english).to eq('damn') + expect(loader.requirements['ESR_Test_3'].verification_criteria).to eq('achso') + expect(loader.requirements['ESR_Test_3'].verification_criteria_french).to eq('') + end + + it 'shall be an empty string if not specified in this particular requirement but specified in another requirement', + doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/vc_lang/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_default1'].verification_criteria_german).to eq('') + expect(loader.requirements['ID_default1'].verification_criteria_french).to eq('bla') + expect(loader.requirements['ID_default2'].verification_criteria_german).to eq('') + expect(loader.requirements['ID_default2'].verification_criteria_french).to eq('') + + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/vc_lang/not_specified.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_not'].respond_to?('verification_criteria_german')).to be(true) + expect(loader.requirements['ID_not'].respond_to?('verification_criteria_english')).to be(false) + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/vc_lang/no_string.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_language'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"verification_criteria_german\" must be String not Array" + end + end + end + + context 'language variants of comment' do + it 'shall be any string', doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/comment_lang/valid.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ESR_Test_1'].comment).to eq("juhu\njuhu") + expect(loader.requirements['ESR_Test_1'].comment_spanish).to eq('ole') + expect(loader.requirements['ESR_Test_2'].comment).to eq('mist') + expect(loader.requirements['ESR_Test_2'].comment_english).to eq('damn') + expect(loader.requirements['ESR_Test_3'].comment).to eq('achso') + expect(loader.requirements['ESR_Test_3'].comment_french).to eq('') + end + + it 'shall be an empty string if not specified in this particular requirement but specified in another requirement', + doc_refs: ['Dim_ReqFiles_language'] do + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/comment_lang/default.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_default1'].comment_german).to eq('') + expect(loader.requirements['ID_default1'].comment_french).to eq('bla') + expect(loader.requirements['ID_default2'].comment_german).to eq('') + expect(loader.requirements['ID_default2'].comment_french).to eq('') + + loader = Dim::Loader.new + loader.load(file: "#{TEST_INPUT_DIR}/reqs/comment_lang/not_specified.dim") + expect(Dim::ExitHelper.exit_code).to eq 0 + expect(loader.requirements['ID_not'].respond_to?('comment_german')).to be(true) + expect(loader.requirements['ID_not'].respond_to?('comment_english')).to be(false) + end + + context 'when value is no string' do + let(:filename) { "#{TEST_INPUT_DIR}/reqs/comment_lang/no_string.dim" } + + it 'shall throw an error and print a meaningful error message', + doc_refs: ['Dim_ReqFiles_language'] do + Test.main("check -i #{filename}") + expect(Dim::ExitHelper.exit_code).to eq 1 + expect(@test_stderr).to include "Error: in #{filename}: value of attribute \"comment_german\" must be String not Array" + end + end + end + end +end +# rubocop:enable Metric/BlockLength, Layout/LineLength diff --git a/dim/spec/stats_spec.rb b/dim/spec/stats_spec.rb new file mode 100644 index 0000000..9f5e2fa --- /dev/null +++ b/dim/spec/stats_spec.rb @@ -0,0 +1,35 @@ +require_relative 'framework/helper' + +module Dim + describe 'dim stats' do + context '-i ' do + it 'shall print detailed statistics of the module', doc_refs: ['Dim_stats_Details'] do + Test.main("stats -i #{TEST_INPUT_DIR}/stats_input/test_module_1.dim") + expect(@test_stdout).to include 'DOCUMENT: test_module_1' + expect(@test_stdout).to include 'Number of files: 1' + expect(@test_stdout).to include 'Number of entries: 9' + expect(@test_stdout).to include 'Requirements: 9' + expect(@test_stdout).to include 'Valid requirements: 8' + expect(@test_stdout).to include ' Accepted: 5' + expect(@test_stdout).to include ' Covered: 4' + expect(@test_stdout).to include ' Not covered: 1' + expect(@test_stdout).to include ' Rejected: 1' + expect(@test_stdout).to include ' Unclear: 1' + expect(@test_stdout).to include ' Not reviewed: 1' + end + end + + context '-i ' do + it 'shall print statistics of all modules and a summary', + doc_refs: %w[Dim_stats_General Dim_loading_readGood] do + Test.main("stats -i #{TEST_INPUT_DIR}/stats_input/Config.dim") + expect(@test_stdout).to include 'ALL' + expect(@test_stdout).to include 'DOCUMENT: test_module_1' + expect(@test_stdout).to include 'DOCUMENT: test_module_2' + expect(@test_stdout).to include 'Requirements: 11' + expect(@test_stdout).to include 'Requirements: 9' + expect(@test_stdout).to include 'Requirements: 2' + end + end + end +end diff --git a/dim/spec/test_input/auto_asilCal_check/Config.dim b/dim/spec/test_input/auto_asilCal_check/Config.dim new file mode 100644 index 0000000..cc63d0b --- /dev/null +++ b/dim/spec/test_input/auto_asilCal_check/Config.dim @@ -0,0 +1,7 @@ +Config: + - originator: CompanyName + files: + - test_module_*.dim + category: "module" + +Properties: "properties.yaml" diff --git a/dim/spec/test_input/auto_asilCal_check/properties.yaml b/dim/spec/test_input/auto_asilCal_check/properties.yaml new file mode 100644 index 0000000..5fe70cb --- /dev/null +++ b/dim/spec/test_input/auto_asilCal_check/properties.yaml @@ -0,0 +1,7 @@ +test_module_asil: + asil: ASIL_A + reuse: yes + +test_module_asilCal: + asil: ASIL_B + cal: CAL_4 diff --git a/dim/spec/test_input/auto_asilCal_check/test_module_asil.dim b/dim/spec/test_input/auto_asilCal_check/test_module_asil.dim new file mode 100644 index 0000000..55cefa3 --- /dev/null +++ b/dim/spec/test_input/auto_asilCal_check/test_module_asil.dim @@ -0,0 +1,11 @@ +module: test_module_asil + +test_id_asilNotSet: + asil: not_set + cal: not_set + +test_id_asilNone: + +test_id_asilSet: + asil: ASIL_D + cal: QM diff --git a/dim/spec/test_input/auto_asilCal_check/test_module_asilCal.dim b/dim/spec/test_input/auto_asilCal_check/test_module_asilCal.dim new file mode 100644 index 0000000..98de307 --- /dev/null +++ b/dim/spec/test_input/auto_asilCal_check/test_module_asilCal.dim @@ -0,0 +1,11 @@ +module: test_module_asilCal + +test_id_asilCalNotSet: + asil: not_set + cal: not_set + +test_id_asilCalNone: + +test_id_asilCalSet: + asil: ASIL_D + cal: QM diff --git a/dim/spec/test_input/auto_asilCal_check/test_module_none.dim b/dim/spec/test_input/auto_asilCal_check/test_module_none.dim new file mode 100644 index 0000000..bd222b5 --- /dev/null +++ b/dim/spec/test_input/auto_asilCal_check/test_module_none.dim @@ -0,0 +1,11 @@ +module: test_module_none + +test_id_noneNotSet: + asil: not_set + cal: not_set + +test_id_noneNone: + +test_id_noneSet: + asil: ASIL_D + cal: QM diff --git a/dim/spec/test_input/backward_reference_same_category/circular/config.dim b/dim/spec/test_input/backward_reference_same_category/circular/config.dim new file mode 100644 index 0000000..3326da6 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/circular/config.dim @@ -0,0 +1,7 @@ +Config: + - originator: CompanyName + files: + - module1.dim + - module2.dim + - module3.dim + category: software diff --git a/dim/spec/test_input/backward_reference_same_category/circular/module1.dim b/dim/spec/test_input/backward_reference_same_category/circular/module1.dim new file mode 100644 index 0000000..f6731d6 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/circular/module1.dim @@ -0,0 +1,5 @@ +module: SRS_esr + +SRS_req_1: + text: sample text + refs: SRS_req_2 diff --git a/dim/spec/test_input/backward_reference_same_category/circular/module2.dim b/dim/spec/test_input/backward_reference_same_category/circular/module2.dim new file mode 100644 index 0000000..4a2f731 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/circular/module2.dim @@ -0,0 +1,5 @@ +module: SRS_esr + +SRS_req_2: + text: sample text + refs: SRS_req_3 diff --git a/dim/spec/test_input/backward_reference_same_category/circular/module3.dim b/dim/spec/test_input/backward_reference_same_category/circular/module3.dim new file mode 100644 index 0000000..cd688a4 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/circular/module3.dim @@ -0,0 +1,5 @@ +module: SRS_esr + +SRS_req_3: + text: sample text + refs: SRS_req_1 diff --git a/dim/spec/test_input/backward_reference_same_category/non_circular/config.dim b/dim/spec/test_input/backward_reference_same_category/non_circular/config.dim new file mode 100644 index 0000000..5c7b365 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/non_circular/config.dim @@ -0,0 +1,8 @@ +Config: + - originator: CompanyName + files: + - index.dim + - module1.dim + - module2.dim + category: software + disable_naming_convention_check: yes diff --git a/dim/spec/test_input/backward_reference_same_category/non_circular/index.dim b/dim/spec/test_input/backward_reference_same_category/non_circular/index.dim new file mode 100644 index 0000000..e4743fa --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/non_circular/index.dim @@ -0,0 +1,4 @@ +module: Software_1 + +SRS_Spec_Main: + refs: SRS_module_1, SRS_module_2 diff --git a/dim/spec/test_input/backward_reference_same_category/non_circular/module1.dim b/dim/spec/test_input/backward_reference_same_category/non_circular/module1.dim new file mode 100644 index 0000000..cf66955 --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/non_circular/module1.dim @@ -0,0 +1,4 @@ +module: Software_1 + +SRS_module_1: + refs: SRS_module_2 diff --git a/dim/spec/test_input/backward_reference_same_category/non_circular/module2.dim b/dim/spec/test_input/backward_reference_same_category/non_circular/module2.dim new file mode 100644 index 0000000..5caf1af --- /dev/null +++ b/dim/spec/test_input/backward_reference_same_category/non_circular/module2.dim @@ -0,0 +1,3 @@ +module: Software_1 + +SRS_module_2: diff --git a/dim/spec/test_input/backward_reference_within_category/config.dim b/dim/spec/test_input/backward_reference_within_category/config.dim new file mode 100644 index 0000000..16cd8e9 --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/config.dim @@ -0,0 +1,20 @@ +Config: + - originator: ESR Software + files: srs/module.dim + category: software + + - originator: ESR Architecture + files: swa/module.dim + category: architecture + + - originator: ESR Module + files: smd/module.dim + category: module + + - originator: ESR Input + files: input/module.dim + category: input + + - originator: ESR System + files: sys/module.dim + category: system diff --git a/dim/spec/test_input/backward_reference_within_category/input/module.dim b/dim/spec/test_input/backward_reference_within_category/input/module.dim new file mode 100644 index 0000000..88c79c6 --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/input/module.dim @@ -0,0 +1,7 @@ +module: esr_input + +IN_requirement1: + text: sample text + +IN_requirement2: + text: sample text diff --git a/dim/spec/test_input/backward_reference_within_category/smd/module.dim b/dim/spec/test_input/backward_reference_within_category/smd/module.dim new file mode 100644 index 0000000..e2eca3f --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/smd/module.dim @@ -0,0 +1,7 @@ +module: esr_module + +SMD_requirement1: + text: sample text + +SMD_requirement2: + text: sample text diff --git a/dim/spec/test_input/backward_reference_within_category/srs/module.dim b/dim/spec/test_input/backward_reference_within_category/srs/module.dim new file mode 100644 index 0000000..1dce2be --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/srs/module.dim @@ -0,0 +1,9 @@ +module: SRS_esr + +SRS_requirement_1: + text: sample text + refs: SWA_requirement1 + +SRS_requirement_2: + text: sample text + refs: SRS_requirement_1 diff --git a/dim/spec/test_input/backward_reference_within_category/swa/module.dim b/dim/spec/test_input/backward_reference_within_category/swa/module.dim new file mode 100644 index 0000000..52907d7 --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/swa/module.dim @@ -0,0 +1,8 @@ +module: esr_swa + +SWA_requirement1: + text: sample text + refs: SYS_requirement1, SRS_requirement_2 + +SWA_requirement2: + text: sample text diff --git a/dim/spec/test_input/backward_reference_within_category/sys/module.dim b/dim/spec/test_input/backward_reference_within_category/sys/module.dim new file mode 100644 index 0000000..859e26e --- /dev/null +++ b/dim/spec/test_input/backward_reference_within_category/sys/module.dim @@ -0,0 +1,8 @@ +module: esr_sys + +SYS_requirement1: + text: sample text + refs: SRS_requirement_1 + +SYS_requirement2: + text: sample text diff --git a/dim/spec/test_input/convenience/module_ok.dim b/dim/spec/test_input/convenience/module_ok.dim new file mode 100644 index 0000000..03da524 --- /dev/null +++ b/dim/spec/test_input/convenience/module_ok.dim @@ -0,0 +1,67 @@ +module: ok + +ESR_Test_L3a: + text: xy + tags: covered + test_setups: none + +ESR_Test_L3b: + text: xy + tags: covered, tested + test_setups: off_target + +ESR_Test_L3c: + text: xy + tags: covered, tested + test_setups: off_target + +ESR_Test_L3d: + tags: process + text: xy + test_setups: off_target + +ESR_Test_L3e: + tags: covered + text: xy + test_setups: off_target + +ESR_Test_L2ab: + text: xy + tags: covered, tested + refs: ESR_Test_L3a, ESR_Test_L3b + test_setups: off_target + +ESR_Test_L2bc: + text: xy + refs: ESR_Test_L3b, ESR_Test_L3c + test_setups: off_target + +ESR_Test_L2cd: + text: xy + tags: covered, tested + refs: ESR_Test_L3c, ESR_Test_L3d + test_setups: off_target + +ESR_Test_L2ce: + text: xy + tags: covered, tested + refs: ESR_Test_L3c, ESR_Test_L3e + test_setups: off_target + +ESR_Test_L1abc: + text: xy + tags: covered, tested + refs: ESR_Test_L2ab, ESR_Test_L2bc + test_setups: off_target + +ESR_Test_L1bcd: + text: xy + tags: covered, tested + refs: ESR_Test_L2bc, ESR_Test_L2cd + test_setups: off_target + +ESR_Test_L0abcd: + text: xy + tags: covered, tested + refs: ESR_Test_L1abc, ESR_Test_L1bcd + test_setups: off_target diff --git a/dim/spec/test_input/custom_attributes_without_attributes_file/Config.dim b/dim/spec/test_input/custom_attributes_without_attributes_file/Config.dim new file mode 100644 index 0000000..0618433 --- /dev/null +++ b/dim/spec/test_input/custom_attributes_without_attributes_file/Config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module diff --git a/dim/spec/test_input/custom_attributes_without_attributes_file/test_module.dim b/dim/spec/test_input/custom_attributes_without_attributes_file/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/custom_attributes_without_attributes_file/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/cyclic_reference_different_modules/config.dim b/dim/spec/test_input/cyclic_reference_different_modules/config.dim new file mode 100644 index 0000000..34b3198 --- /dev/null +++ b/dim/spec/test_input/cyclic_reference_different_modules/config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module_1.dim + - test_module_2.dim + category: "module" \ No newline at end of file diff --git a/dim/spec/test_input/cyclic_reference_different_modules/test_module_1.dim b/dim/spec/test_input/cyclic_reference_different_modules/test_module_1.dim new file mode 100644 index 0000000..486b129 --- /dev/null +++ b/dim/spec/test_input/cyclic_reference_different_modules/test_module_1.dim @@ -0,0 +1,5 @@ +module: test_module_1 + +test_module_1-0000-0001: + text: req1 + refs: test_module_2-0000-0001 \ No newline at end of file diff --git a/dim/spec/test_input/cyclic_reference_different_modules/test_module_2.dim b/dim/spec/test_input/cyclic_reference_different_modules/test_module_2.dim new file mode 100644 index 0000000..b485fb8 --- /dev/null +++ b/dim/spec/test_input/cyclic_reference_different_modules/test_module_2.dim @@ -0,0 +1,5 @@ +module: test_module_2 + +test_module_2-0000-0001: + text: req2 + refs: test_module_1-0000-0001 \ No newline at end of file diff --git a/dim/spec/test_input/cyclic_reference_same_file/test_module_1.dim b/dim/spec/test_input/cyclic_reference_same_file/test_module_1.dim new file mode 100644 index 0000000..28ec0ff --- /dev/null +++ b/dim/spec/test_input/cyclic_reference_same_file/test_module_1.dim @@ -0,0 +1,9 @@ +module: test_module_1 + +test_id_1: + text: First test requirement + refs: test_id_2 + +test_id_2: + text: Second test requirement + refs: test_id_1 diff --git a/dim/spec/test_input/different_encodings/ISO8859-1_input.dim b/dim/spec/test_input/different_encodings/ISO8859-1_input.dim new file mode 100644 index 0000000..52e4c82 --- /dev/null +++ b/dim/spec/test_input/different_encodings/ISO8859-1_input.dim @@ -0,0 +1,4 @@ +module: ISO8859-1 + +test_id_1: + text: µC shall trigger ä if µP reaches temperature x°. \ No newline at end of file diff --git a/dim/spec/test_input/different_encodings/ISO8859-1_input_invalid.dim b/dim/spec/test_input/different_encodings/ISO8859-1_input_invalid.dim new file mode 100644 index 0000000..838a0a7 --- /dev/null +++ b/dim/spec/test_input/different_encodings/ISO8859-1_input_invalid.dim @@ -0,0 +1,4 @@ +module: ISO8859-1 + +test_id_1: + text: µC: shall trigger ä if µP reaches temperature x°. diff --git a/dim/spec/test_input/different_encodings/Windows1250_input.dim b/dim/spec/test_input/different_encodings/Windows1250_input.dim new file mode 100644 index 0000000..3589946 --- /dev/null +++ b/dim/spec/test_input/different_encodings/Windows1250_input.dim @@ -0,0 +1,4 @@ +module: Windows1250 + +test_id_1: + text: µC shall trigger ä if µP reaches temperature x°. \ No newline at end of file diff --git a/dim/spec/test_input/different_encodings/utf-8_input.dim b/dim/spec/test_input/different_encodings/utf-8_input.dim new file mode 100644 index 0000000..4c2290b --- /dev/null +++ b/dim/spec/test_input/different_encodings/utf-8_input.dim @@ -0,0 +1,4 @@ +module: utf-8 + +test_id_1: + text: µC shall trigger ä if µP reaches temperature x°. \ No newline at end of file diff --git a/dim/spec/test_input/document/document.dim b/dim/spec/test_input/document/document.dim new file mode 100644 index 0000000..74665cb --- /dev/null +++ b/dim/spec/test_input/document/document.dim @@ -0,0 +1,4 @@ +document: ABC + +ID_1: + text: document test diff --git a/dim/spec/test_input/document/document.dim.expected b/dim/spec/test_input/document/document.dim.expected new file mode 100644 index 0000000..8660c4b --- /dev/null +++ b/dim/spec/test_input/document/document.dim.expected @@ -0,0 +1,4 @@ +document: ABC + +ID_1: + text: document test diff --git a/dim/spec/test_input/document/document_and_modulename.dim b/dim/spec/test_input/document/document_and_modulename.dim new file mode 100644 index 0000000..d2eeeed --- /dev/null +++ b/dim/spec/test_input/document/document_and_modulename.dim @@ -0,0 +1,6 @@ +document: ABC + +module: XYZ + +ID_1: + text: Document Test diff --git a/dim/spec/test_input/document/empty_document.dim b/dim/spec/test_input/document/empty_document.dim new file mode 100644 index 0000000..9b0394a --- /dev/null +++ b/dim/spec/test_input/document/empty_document.dim @@ -0,0 +1,4 @@ +document: + +ID_1: + text: document test diff --git a/dim/spec/test_input/document/missing_document.dim b/dim/spec/test_input/document/missing_document.dim new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/document/modulename.dim b/dim/spec/test_input/document/modulename.dim new file mode 100644 index 0000000..8b0d063 --- /dev/null +++ b/dim/spec/test_input/document/modulename.dim @@ -0,0 +1,4 @@ +module: ABC + +ID_1: + text: document test diff --git a/dim/spec/test_input/document/modulename.dim.expected b/dim/spec/test_input/document/modulename.dim.expected new file mode 100644 index 0000000..8660c4b --- /dev/null +++ b/dim/spec/test_input/document/modulename.dim.expected @@ -0,0 +1,4 @@ +document: ABC + +ID_1: + text: document test diff --git a/dim/spec/test_input/document/output/csv/Requirements.csv b/dim/spec/test_input/document/output/csv/Requirements.csv new file mode 100644 index 0000000..d89ce22 --- /dev/null +++ b/dim/spec/test_input/document/output/csv/Requirements.csv @@ -0,0 +1,3 @@ +Sep=, +id,document_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,verification_methods,status,review_status,comment,miscellaneous,sources,refs +"ID_1","ABC","","requirement","document test","","","","","not_set","not_set","","","none","draft","not_reviewed","","","","" diff --git a/dim/spec/test_input/document/output/json/Requirements.json b/dim/spec/test_input/document/output/json/Requirements.json new file mode 100644 index 0000000..287a52a --- /dev/null +++ b/dim/spec/test_input/document/output/json/Requirements.json @@ -0,0 +1,24 @@ +[ + { + "id": "ID_1", + "document_name": "ABC", + "originator": "", + "type": "requirement", + "text": "document test", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "none", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + } +] diff --git a/dim/spec/test_input/document/output/rst/Requirements.rst b/dim/spec/test_input/document/output/rst/Requirements.rst new file mode 100644 index 0000000..3ac775b --- /dev/null +++ b/dim/spec/test_input/document/output/rst/Requirements.rst @@ -0,0 +1,22 @@ +:raw-html:`ABC` +=============== + +.. requirement:: ID_1 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`document test` diff --git a/dim/spec/test_input/empty_custom_attributes_file/Config.dim b/dim/spec/test_input/empty_custom_attributes_file/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/empty_custom_attributes_file/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/empty_custom_attributes_file/attributes.dim b/dim/spec/test_input/empty_custom_attributes_file/attributes.dim new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/empty_custom_attributes_file/test_module.dim b/dim/spec/test_input/empty_custom_attributes_file/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/empty_custom_attributes_file/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/empty_requirement/module.dim b/dim/spec/test_input/empty_requirement/module.dim new file mode 100644 index 0000000..c2a565f --- /dev/null +++ b/dim/spec/test_input/empty_requirement/module.dim @@ -0,0 +1,3 @@ +module: empty_requirement + +ESR_Test_empty: diff --git a/dim/spec/test_input/enclosed_check/test.txt b/dim/spec/test_input/enclosed_check/test.txt new file mode 100644 index 0000000..e1ccc78 --- /dev/null +++ b/dim/spec/test_input/enclosed_check/test.txt @@ -0,0 +1 @@ +Hallllllllllllllllllllllllllllllloooooooooooooooo \ No newline at end of file diff --git a/dim/spec/test_input/enclosed_check/test_module_1_1.dim b/dim/spec/test_input/enclosed_check/test_module_1_1.dim new file mode 100644 index 0000000..a26c1ce --- /dev/null +++ b/dim/spec/test_input/enclosed_check/test_module_1_1.dim @@ -0,0 +1,7 @@ +module: test_module + +enclosed: + - test.txt + +test_id_1: + text: First test req \ No newline at end of file diff --git a/dim/spec/test_input/export_calculated_infos/Input1.yml b/dim/spec/test_input/export_calculated_infos/Input1.yml new file mode 100644 index 0000000..b8be17a --- /dev/null +++ b/dim/spec/test_input/export_calculated_infos/Input1.yml @@ -0,0 +1,36 @@ +module: ABC123 + +SRS_ABC123_req1: + text: Text1 + review_status: unclear + tags: covered + +SRS_ABC123_req2: + text: Text2 + +SRS_ABC123_req3: + text: Text3 + tags: covered + +SRS_ABC123_req4: h2 HEADING2 + +SRS_ABC123_req5: h3 HEADING3 + +SRS_ABC123_req6: + text: Text6 + test_setups: on_target + verification_criteria: Bla + review_status: accepted +SRS_ABC123_req7: + text: Text7 + test_setups: on_target + verification_criteria: Bla + review_status: accepted + tags: covered + +SRS_ABC123_req8: + text: Text8 + developer: CompanyName + test_setups: on_target + review_status: unclear + tags: tested diff --git a/dim/spec/test_input/export_calculated_infos/Input2.yml b/dim/spec/test_input/export_calculated_infos/Input2.yml new file mode 100644 index 0000000..86c9a97 --- /dev/null +++ b/dim/spec/test_input/export_calculated_infos/Input2.yml @@ -0,0 +1,11 @@ +module: ABC123 + +SRS_A_1: + text: bla + review_status: unclear + +SRS_A_2: + text: | + b"l'a + verification_criteria: nothing + tags: performance diff --git a/dim/spec/test_input/export_calculated_infos/output/Requirements1.csv b/dim/spec/test_input/export_calculated_infos/output/Requirements1.csv new file mode 100644 index 0000000..bfcf075 --- /dev/null +++ b/dim/spec/test_input/export_calculated_infos/output/Requirements1.csv @@ -0,0 +1,10 @@ +Sep=, +id,document_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,verification_methods,status,review_status,comment,miscellaneous,sources,refs +"SRS_ABC123_req1","ABC123","","requirement","Text1","","","","covered","not_set","not_set","","","none","draft","unclear","","","","" +"SRS_ABC123_req2","ABC123","","requirement","Text2","","","","","not_set","not_set","","","none","draft","not_reviewed","","","","" +"SRS_ABC123_req3","ABC123","","requirement","Text3","","","","covered","not_set","not_set","","","none","draft","not_reviewed","","","","" +"SRS_ABC123_req4","ABC123","","heading_2","HEADING2","","","","","not_set","not_set","","","none","valid","not_reviewed","","","","" +"SRS_ABC123_req5","ABC123","","heading_3","HEADING3","","","","","not_set","not_set","","","none","valid","not_reviewed","","","","" +"SRS_ABC123_req6","ABC123","","requirement","Text6","Bla","","","","not_set","not_set","","","on_target","draft","accepted","","","","" +"SRS_ABC123_req7","ABC123","","requirement","Text7","Bla","","","covered","not_set","not_set","","","on_target","draft","accepted","","","","" +"SRS_ABC123_req8","ABC123","","requirement","Text8","","","","tested","not_set","not_set","CompanyName","","on_target","draft","unclear","","","","" diff --git a/dim/spec/test_input/export_calculated_infos/output/Requirements2.csv b/dim/spec/test_input/export_calculated_infos/output/Requirements2.csv new file mode 100644 index 0000000..a6c59a0 --- /dev/null +++ b/dim/spec/test_input/export_calculated_infos/output/Requirements2.csv @@ -0,0 +1,4 @@ +Sep=, +id,document_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,verification_methods,status,review_status,comment,miscellaneous,sources,refs +"SRS_A_1","ABC123","","requirement","bla","","","","","not_set","not_set","","","none","draft","unclear","","","","" +"SRS_A_2","ABC123","","requirement","b""l'a","nothing","","","performance","not_set","not_set","","","none","draft","not_reviewed","","","","" diff --git a/dim/spec/test_input/export_check/Config.dim b/dim/spec/test_input/export_check/Config.dim new file mode 100644 index 0000000..289d9c2 --- /dev/null +++ b/dim/spec/test_input/export_check/Config.dim @@ -0,0 +1,17 @@ +Config: + - originator: CompanyName + files: + - test_srs_1.dim + category: "software" + disable_naming_convention_check: yes + - originator: CompanyName + files: + - test_module_1.dim + - test_module_3.dim + - test_module_4.dim + - test_module_5.dim + - test_export*.dim + category: "module" + - originator: XY_Company + files: test_module_2.dim + category: module diff --git a/dim/spec/test_input/export_check/export_test_12_1.dim b/dim/spec/test_input/export_check/export_test_12_1.dim new file mode 100644 index 0000000..56b6c8c --- /dev/null +++ b/dim/spec/test_input/export_check/export_test_12_1.dim @@ -0,0 +1,17 @@ +module: test_export_12 + +export_1: + text: Another test req + tags: established, process, covered, tested + feature: Blah + change_request: Fasel + verification_criteria: Value xy shall equal value ab. + test_setups: on_target, off_target + miscellaneous: Additional random information + comment: Req is nice + asil: ASIL_A + tester: xy_company + refs: + +enclosed: + - images/test.jpeg diff --git a/dim/spec/test_input/export_check/export_test_12_2.dim b/dim/spec/test_input/export_check/export_test_12_2.dim new file mode 100644 index 0000000..de5e155 --- /dev/null +++ b/dim/spec/test_input/export_check/export_test_12_2.dim @@ -0,0 +1,17 @@ +module: test_export_12 + +export_2: + text: Another test req + tags: established, process, covered, tested + feature: Blah + change_request: Fasel + verification_criteria: Value xy shall equal value ab. + test_setups: on_target, off_target + miscellaneous: Additional random information + comment: Req is nice + asil: ASIL_A + tester: xy_company + refs: + +enclosed: + - images/test_new.jpeg diff --git a/dim/spec/test_input/export_check/images/test.jpeg b/dim/spec/test_input/export_check/images/test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/spec/test_input/export_check/images/test_new.jpeg b/dim/spec/test_input/export_check/images/test_new.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/spec/test_input/export_check/no_check_enclosed.dim b/dim/spec/test_input/export_check/no_check_enclosed.dim new file mode 100644 index 0000000..66f563f --- /dev/null +++ b/dim/spec/test_input/export_check/no_check_enclosed.dim @@ -0,0 +1,18 @@ +module: no_enclosed_check + + +no_check_1: + text: Another test req + tags: established, process, covered, tested + feature: Blah + change_request: Fasel + verification_criteria: Value xy shall equal value ab. + test_setups: on_target, off_target + miscellaneous: Additional random information + comment: Req is nice + asil: ASIL_A + tester: xy_company + refs: + +enclosed: + - images/invalid.jpeg diff --git a/dim/spec/test_input/export_check/output/X-_.test___srs_/Requirements.rst b/dim/spec/test_input/export_check/output/X-_.test___srs_/Requirements.rst new file mode 100644 index 0000000..7b0c5b8 --- /dev/null +++ b/dim/spec/test_input/export_check/output/X-_.test___srs_/Requirements.rst @@ -0,0 +1,22 @@ +:raw-html:`X-é.test*()srs=` +=========================== + +.. requirement:: test_srs_1 + :category: software + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: a/b.c + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: on_target + :verification_criteria: + + :raw-html:`Some req` diff --git a/dim/spec/test_input/export_check/output/index_001_software_companyname.rst b/dim/spec/test_input/export_check/output/index_001_software_companyname.rst new file mode 100644 index 0000000..c265904 --- /dev/null +++ b/dim/spec/test_input/export_check/output/index_001_software_companyname.rst @@ -0,0 +1,7 @@ +Software (CompanyName) +====================== + +.. toctree:: + :maxdepth: 1 + + X-_.test___srs_/Requirements diff --git a/dim/spec/test_input/export_check/output/index_002_module_companyname.rst b/dim/spec/test_input/export_check/output/index_002_module_companyname.rst new file mode 100644 index 0000000..313da27 --- /dev/null +++ b/dim/spec/test_input/export_check/output/index_002_module_companyname.rst @@ -0,0 +1,21 @@ +Module (CompanyName) +==================== + +.. toctree:: + :maxdepth: 1 + + mod01/Requirements + mod02/Requirements + mod03/Requirements + mod04/Requirements + mod05/Requirements + mod06/Requirements + mod07/Requirements + mod08/Requirements + mod09/Requirements + mod10/Requirements + mod11/Requirements + test_module_1/Requirements + test_module_3/Requirements + test_module_4/Requirements + test_module_5/Requirements diff --git a/dim/spec/test_input/export_check/output/index_003_module_xy_company.rst b/dim/spec/test_input/export_check/output/index_003_module_xy_company.rst new file mode 100644 index 0000000..124f45b --- /dev/null +++ b/dim/spec/test_input/export_check/output/index_003_module_xy_company.rst @@ -0,0 +1,7 @@ +Module (XY_Company) +=================== + +.. toctree:: + :maxdepth: 1 + + test_module_2/Requirements diff --git a/dim/spec/test_input/export_check/output/mod01/Requirements.rst b/dim/spec/test_input/export_check/output/mod01/Requirements.rst new file mode 100644 index 0000000..15b45b7 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod01/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod01` +================= + +.. requirement:: Test_Export_01 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: X + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod02/Requirements.rst b/dim/spec/test_input/export_check/output/mod02/Requirements.rst new file mode 100644 index 0000000..ad03519 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod02/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod02` +================= + +.. requirement:: Test_Export_02 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: X + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod03/Requirements.rst b/dim/spec/test_input/export_check/output/mod03/Requirements.rst new file mode 100644 index 0000000..01c904e --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod03/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod03` +================= + +.. requirement:: Test_Export_03 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: X + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod04/Requirements.rst b/dim/spec/test_input/export_check/output/mod04/Requirements.rst new file mode 100644 index 0000000..d40059b --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod04/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod04` +================= + +.. requirement:: Test_Export_04 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: X + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod05/Requirements.rst b/dim/spec/test_input/export_check/output/mod05/Requirements.rst new file mode 100644 index 0000000..e16b47b --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod05/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod05` +================= + +.. requirement:: Test_Export_05 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod06/Requirements.rst b/dim/spec/test_input/export_check/output/mod06/Requirements.rst new file mode 100644 index 0000000..a80eb13 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod06/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod06` +================= + +.. requirement:: Test_Export_06 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: X + :tester: CompanyName + :verification_methods: none + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod07/Requirements.rst b/dim/spec/test_input/export_check/output/mod07/Requirements.rst new file mode 100644 index 0000000..01ac178 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod07/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod07` +================= + +.. requirement:: Test_Export_07 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: X + :verification_methods: none + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod08/Requirements.rst b/dim/spec/test_input/export_check/output/mod08/Requirements.rst new file mode 100644 index 0000000..a4f3bc8 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod08/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod08` +================= + +.. requirement:: Test_Export_08 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: X + :verification_methods: none + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod09/Requirements.rst b/dim/spec/test_input/export_check/output/mod09/Requirements.rst new file mode 100644 index 0000000..bc72735 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod09/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod09` +================= + +.. requirement:: Test_Export_09 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: X + :tester: CompanyName + :verification_methods: none + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod10/Requirements.rst b/dim/spec/test_input/export_check/output/mod10/Requirements.rst new file mode 100644 index 0000000..b8daba4 --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod10/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod10` +================= + +.. requirement:: Test_Export_10 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: none + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/mod11/Requirements.rst b/dim/spec/test_input/export_check/output/mod11/Requirements.rst new file mode 100644 index 0000000..a8227fd --- /dev/null +++ b/dim/spec/test_input/export_check/output/mod11/Requirements.rst @@ -0,0 +1,20 @@ +:raw-html:`mod11` +================= + +.. requirement:: Test_Export_11 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: A B + :tester: C D + :verification_methods: off_target + :verification_criteria: diff --git a/dim/spec/test_input/export_check/output/test_module_1/Requirements.rst b/dim/spec/test_input/export_check/output/test_module_1/Requirements.rst new file mode 100644 index 0000000..aebdfff --- /dev/null +++ b/dim/spec/test_input/export_check/output/test_module_1/Requirements.rst @@ -0,0 +1,62 @@ +:raw-html:`test_module_1` +========================= + +.. requirement:: test_id_1 + :category: module + :status: draft + :review_status: accepted + :asil: ASIL_A + :cal: not_set + :tags: established, process, covered, tested + :comment: :raw-html:`Req is nice` + :miscellaneous: :raw-html:`Additional random information` + :refs: test_id_2, test_id_1b + :sources: + :feature: :raw-html:`Blah` + :change_request: :raw-html:`Fasel` + :developer: CompanyName + :tester: xy_company + :verification_methods: on_target, off_target + :verification_criteria: :raw-html:`Value xy shall equal value ab.` + + :raw-html:`Another test req` + +.. requirement:: test_id_1b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`Second test req Bold` + +.. requirement:: test_id_1c + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: :raw-html:`Misc.` + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: :raw-html:`-

Verification Criteria English: Verify me!` + + :raw-html:`Third test req Bold

Text German: Das ist Nummer drei.` diff --git a/dim/spec/test_input/export_check/output/test_module_2/Requirements.rst b/dim/spec/test_input/export_check/output/test_module_2/Requirements.rst new file mode 100644 index 0000000..072de62 --- /dev/null +++ b/dim/spec/test_input/export_check/output/test_module_2/Requirements.rst @@ -0,0 +1,123 @@ +:raw-html:`test_module_2` +========================= + +:raw-html:`This is the meta data.
Exported Jan 1, 2000.` + +.. requirement:: test_id_2 + :category: module + :status: draft + :review_status: accepted + :asil: ASIL_A + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: x_x + :sources: + :feature: + :change_request: + :developer: xy_company + :tester: XY_Company + :verification_methods: off_target + :verification_criteria: + + :raw-html:`You have to follow:

And that's
it!
Firstname Lastname Ag` e
John Smith 40
Jane Doe 30


Text English: Another test RRRREQ

Text French: Another test FRR` + + +----------------------- + +:raw-html:`H2` +++++++++++++++ + +:raw-html:`H1` +-------------- + +:raw-html:`H2` +++++++++++++++ + +:raw-html:`H3` +~~~~~~~~~~~~~~ + +:raw-html:`H3` +~~~~~~~~~~~~~~ + + +^^^^^^^^^^^^^^^^^^^^^^^ + +:raw-html:`H5` +"""""""""""""" + + +""""""""""""""""""""""" + + +""""""""""""""""""""""" + + +""""""""""""""""""""""" + + +""""""""""""""""""""""" + +:raw-html:`H10` +""""""""""""""" + +.. requirement:: x_x + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: XY_Company + :tester: XY_Company + :verification_methods: off_target + :verification_criteria: + + :raw-html:`x` + +.. requirement:: y_y + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_id_2 + :sources: + :feature: + :change_request: + :developer: XY_Company + :tester: XY_Company + :verification_methods: off_target + :verification_criteria: + + :raw-html:`y` + +.. information:: z_z + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: :raw-html:`That is a comment.` + :miscellaneous: :raw-html:`Misc.` + :refs: + + :raw-html:`This is an information.

Text German: Das ist eine Information.` + +:raw-html:`SHUT-DOWN PHASE: See system function "Provide Shut-down".` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. enclosed:: + + images/test.jpeg diff --git a/dim/spec/test_input/export_check/output/test_module_2/images/test.jpeg b/dim/spec/test_input/export_check/output/test_module_2/images/test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/spec/test_input/export_check/output/test_module_3/Requirements.rst b/dim/spec/test_input/export_check/output/test_module_3/Requirements.rst new file mode 100644 index 0000000..094fab0 --- /dev/null +++ b/dim/spec/test_input/export_check/output/test_module_3/Requirements.rst @@ -0,0 +1,22 @@ +:raw-html:`test_module_3` +========================= + +.. requirement:: test_id_10 + :category: module + :status: draft + :review_status: accepted + :asil: ASIL_A + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`test req of dim file without module name` diff --git a/dim/spec/test_input/export_check/output/test_module_4/Requirements.rst b/dim/spec/test_input/export_check/output/test_module_4/Requirements.rst new file mode 100644 index 0000000..e39d545 --- /dev/null +++ b/dim/spec/test_input/export_check/output/test_module_4/Requirements.rst @@ -0,0 +1,162 @@ +:raw-html:`test_module_4` +========================= + +.. requirement:: test_4_normal + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_asil + :category: module + :status: draft + :review_status: accepted + :asil: ASIL_B + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_cal + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: CAL_4 + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_integrity + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: integrity + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_draft + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_invalid + :category: module + :status: invalid + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_rejected + :category: module + :status: draft + :review_status: rejected + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` + +.. requirement:: test_4_all + :category: module + :status: draft + :review_status: rejected + :asil: ASIL_B(D) + :cal: CAL_4 + :tags: memory, integrity + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`yay` diff --git a/dim/spec/test_input/export_check/output/test_module_5/Requirements.rst b/dim/spec/test_input/export_check/output/test_module_5/Requirements.rst new file mode 100644 index 0000000..631f495 --- /dev/null +++ b/dim/spec/test_input/export_check/output/test_module_5/Requirements.rst @@ -0,0 +1,602 @@ +:raw-html:`test_module_5` +========================= + +.. requirement:: test_5_c1a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c1b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_c1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_c1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2c + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_c1a, test_5_c1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2d + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2e + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_c1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2f + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_c1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2g + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_c1a, test_5_c1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_c2h + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t1a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t1b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested + :comment: + :miscellaneous: + :refs: test_5_t1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested + :comment: + :miscellaneous: + :refs: test_5_t1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2c + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested + :comment: + :miscellaneous: + :refs: test_5_t1a, test_5_t1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2d + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2e + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_t1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2f + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_t1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2g + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: test_5_t1a, test_5_t1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_t2h + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct1a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested, covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct1b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2a + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested, covered + :comment: + :miscellaneous: + :refs: test_5_ct1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2b + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested, covered + :comment: + :miscellaneous: + :refs: test_5_ct1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2c + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested, covered + :comment: + :miscellaneous: + :refs: test_5_ct1a, test_5_ct1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2d + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: tested, covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2e + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_ct1a + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2f + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_ct1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2g + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: test_5_ct1a, test_5_ct1b + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` + +.. requirement:: test_5_ct2h + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`dummy` diff --git a/dim/spec/test_input/export_check/test_export_01.dim b/dim/spec/test_input/export_check/test_export_01.dim new file mode 100644 index 0000000..93c55f4 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_01.dim @@ -0,0 +1,4 @@ +module: mod01 + +Test_Export_01: + developer: X diff --git a/dim/spec/test_input/export_check/test_export_02.dim b/dim/spec/test_input/export_check/test_export_02.dim new file mode 100644 index 0000000..3b78aa2 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_02.dim @@ -0,0 +1,4 @@ +module: mod02 + +Test_Export_02: + tester: X diff --git a/dim/spec/test_input/export_check/test_export_03.dim b/dim/spec/test_input/export_check/test_export_03.dim new file mode 100644 index 0000000..79d7cc9 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_03.dim @@ -0,0 +1,4 @@ +module: mod03 + +Test_Export_03: + tester: X diff --git a/dim/spec/test_input/export_check/test_export_04.dim b/dim/spec/test_input/export_check/test_export_04.dim new file mode 100644 index 0000000..cfd2f06 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_04.dim @@ -0,0 +1,4 @@ +module: mod04 + +Test_Export_04: + developer: X diff --git a/dim/spec/test_input/export_check/test_export_05.dim b/dim/spec/test_input/export_check/test_export_05.dim new file mode 100644 index 0000000..e33eee2 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_05.dim @@ -0,0 +1,3 @@ +module: mod05 + +Test_Export_05: diff --git a/dim/spec/test_input/export_check/test_export_06.dim b/dim/spec/test_input/export_check/test_export_06.dim new file mode 100644 index 0000000..4e9e916 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_06.dim @@ -0,0 +1,5 @@ +module: mod06 + +Test_Export_06: + test_setups: none + developer: X diff --git a/dim/spec/test_input/export_check/test_export_07.dim b/dim/spec/test_input/export_check/test_export_07.dim new file mode 100644 index 0000000..5968937 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_07.dim @@ -0,0 +1,5 @@ +module: mod07 + +Test_Export_07: + test_setups: none + tester: X diff --git a/dim/spec/test_input/export_check/test_export_08.dim b/dim/spec/test_input/export_check/test_export_08.dim new file mode 100644 index 0000000..3b4e81b --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_08.dim @@ -0,0 +1,5 @@ +module: mod08 + +Test_Export_08: + test_setups: none + tester: X diff --git a/dim/spec/test_input/export_check/test_export_09.dim b/dim/spec/test_input/export_check/test_export_09.dim new file mode 100644 index 0000000..ea770db --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_09.dim @@ -0,0 +1,5 @@ +module: mod09 + +Test_Export_09: + test_setups: none + developer: X diff --git a/dim/spec/test_input/export_check/test_export_10.dim b/dim/spec/test_input/export_check/test_export_10.dim new file mode 100644 index 0000000..0f08155 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_10.dim @@ -0,0 +1,4 @@ +module: mod10 + +Test_Export_10: + test_setups: none diff --git a/dim/spec/test_input/export_check/test_export_11.dim b/dim/spec/test_input/export_check/test_export_11.dim new file mode 100644 index 0000000..430b450 --- /dev/null +++ b/dim/spec/test_input/export_check/test_export_11.dim @@ -0,0 +1,10 @@ +module: mod11 + +Test_Export_11: + test_setups: off_target + developer: | + A + B + tester: | + C + D diff --git a/dim/spec/test_input/export_check/test_module_1.dim b/dim/spec/test_input/export_check/test_module_1.dim new file mode 100644 index 0000000..47b51a9 --- /dev/null +++ b/dim/spec/test_input/export_check/test_module_1.dim @@ -0,0 +1,23 @@ +module: test_module_1 + +test_id_1: + text: Another test req + tags: established, process, covered, tested + feature: Blah + change_request: Fasel + verification_criteria: Value xy shall equal value ab. + test_setups: on_target, off_target + miscellaneous: Additional random information + comment: Req is nice + asil: ASIL_A + tester: xy_company + refs: test_id_2, test_id_1b + +test_id_1b: + text: Second test req Bold + +test_id_1c: + text: Third test req Bold + verification_criteria_english: Verify me! + text_german: Das ist Nummer drei. + miscellaneous: Misc. diff --git a/dim/spec/test_input/export_check/test_module_2.dim b/dim/spec/test_input/export_check/test_module_2.dim new file mode 100644 index 0000000..bb3180f --- /dev/null +++ b/dim/spec/test_input/export_check/test_module_2.dim @@ -0,0 +1,73 @@ +module: test_module_2 + +metadata: | + This is the meta data. + Exported Jan 1, 2000. + +enclosed: + - images/test.jpeg + +test_id_2: + text: | + You have to follow: + + And that's
it! + + + + + + + + + + + + + + + + + +
FirstnameLastnameAg` e
JohnSmith40
JaneDoe30
+ + text_english: Another test RRRREQ + text_french: Another test FRR + developer: xy_company + asil: ASIL_A + refs: test_heading_1, test_heading_2, x_x + +test_heading_1: h2 H2 + +test_heading_2: h1 H1 + +test_heading_3: h2 H2 + +test_heading_4: h3 H3 + +test_heading_5: h3 H3 + +test_heading_6: h5 H5 + +test_heading_7: h10 H10 + +x_x: + text: x + +y_y: + text: y + refs: test_id_2 + +z_z: + type: information + text: This is an information. + text_german: Das ist eine Information. + comment: That is a comment. + verification_criteria_english: Verify me! + miscellaneous: Misc. + +heading_multiline_html: + type: heading_4 + text: | + SHUT-DOWN PHASE: + See system function "Provide Shut-down". diff --git a/dim/spec/test_input/export_check/test_module_3.dim b/dim/spec/test_input/export_check/test_module_3.dim new file mode 100644 index 0000000..a74be80 --- /dev/null +++ b/dim/spec/test_input/export_check/test_module_3.dim @@ -0,0 +1,5 @@ +module: test_module_3 + +test_id_10: + text: test req of dim file without module name + asil: ASIL_A \ No newline at end of file diff --git a/dim/spec/test_input/export_check/test_module_4.dim b/dim/spec/test_input/export_check/test_module_4.dim new file mode 100644 index 0000000..ec3f6d4 --- /dev/null +++ b/dim/spec/test_input/export_check/test_module_4.dim @@ -0,0 +1,36 @@ +module: test_module_4 + +test_4_normal: + text: yay + +test_4_asil: + text: yay + asil: ASIL_B + +test_4_cal: + text: yay + cal: CAL_4 + +test_4_integrity: + text: yay + tags: integrity + +test_4_draft: + text: yay + status: draft + +test_4_invalid: + text: yay + status: invalid + +test_4_rejected: + text: yay + review_status: rejected + +test_4_all: + text: yay + asil: ASIL_B(D) + status: draft + tags: memory, integrity + cal: CAL_4 + review_status: rejected diff --git a/dim/spec/test_input/export_check/test_module_5.dim b/dim/spec/test_input/export_check/test_module_5.dim new file mode 100644 index 0000000..a6ab48a --- /dev/null +++ b/dim/spec/test_input/export_check/test_module_5.dim @@ -0,0 +1,130 @@ +module: test_module_5 + +test_5_c1a: + text: dummy + tags: covered + +test_5_c1b: + text: dummy + +test_5_c2a: + text: dummy + tags: covered + refs: test_5_c1a + +test_5_c2b: + text: dummy + tags: covered + refs: test_5_c1b + +test_5_c2c: + text: dummy + tags: covered + refs: test_5_c1a, test_5_c1b + +test_5_c2d: + text: dummy + tags: covered + +test_5_c2e: + text: dummy + refs: test_5_c1a + +test_5_c2f: + text: dummy + refs: test_5_c1b + +test_5_c2g: + text: dummy + refs: test_5_c1a, test_5_c1b + +test_5_c2h: + text: dummy + +test_5_t1a: + text: dummy + tags: tested + +test_5_t1b: + text: dummy + +test_5_t2a: + text: dummy + tags: tested + refs: test_5_t1a + +test_5_t2b: + text: dummy + tags: tested + refs: test_5_t1b + +test_5_t2c: + text: dummy + tags: tested + refs: test_5_t1a, test_5_t1b + +test_5_t2d: + text: dummy + tags: tested + +test_5_t2e: + text: dummy + refs: test_5_t1a + +test_5_t2f: + text: dummy + refs: test_5_t1b + +test_5_t2g: + text: dummy + refs: test_5_t1a, test_5_t1b + +test_5_t2h: + text: dummy + +test_5_ct1a: + text: dummy + tags: tested, covered + +test_5_ct1b: + text: dummy + tags: covered + +test_5_ct2a: + text: dummy + tags: tested, covered + refs: test_5_ct1a + +test_5_ct2b: + text: dummy + tags: tested, covered + refs: test_5_ct1b + +test_5_ct2c: + text: dummy + tags: tested, covered + refs: test_5_ct1a, test_5_ct1b + +test_5_ct2d: + text: dummy + tags: tested, covered + +test_5_ct2e: + text: dummy + refs: test_5_ct1a + tags: covered + +test_5_ct2f: + text: dummy + refs: test_5_ct1b + tags: covered + +test_5_ct2g: + text: dummy + refs: test_5_ct1a, test_5_ct1b + tags: covered + +test_5_ct2h: + text: dummy + tags: covered + diff --git a/dim/spec/test_input/export_check/test_srs_1.dim b/dim/spec/test_input/export_check/test_srs_1.dim new file mode 100644 index 0000000..cfc7fc4 --- /dev/null +++ b/dim/spec/test_input/export_check/test_srs_1.dim @@ -0,0 +1,5 @@ +module: X-é.test*()srs= + +test_srs_1: + text: Some req + sources: a/b.c diff --git a/dim/spec/test_input/export_check/using_config/Config.dim b/dim/spec/test_input/export_check/using_config/Config.dim new file mode 100644 index 0000000..0394f07 --- /dev/null +++ b/dim/spec/test_input/export_check/using_config/Config.dim @@ -0,0 +1,9 @@ +Config: + - originator: CompanyName + files: + - module1.dim + category: module + - originator: XY_Company + files: + - module2.dim + category: module diff --git a/dim/spec/test_input/export_check/using_config/SingleOriginConfig.dim b/dim/spec/test_input/export_check/using_config/SingleOriginConfig.dim new file mode 100644 index 0000000..cd56ac3 --- /dev/null +++ b/dim/spec/test_input/export_check/using_config/SingleOriginConfig.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: + - module1.dim + category: module diff --git a/dim/spec/test_input/export_check/using_config/images/test.jpeg b/dim/spec/test_input/export_check/using_config/images/test.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/spec/test_input/export_check/using_config/images/test_new.jpeg b/dim/spec/test_input/export_check/using_config/images/test_new.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..83eecd42a2709554a698ac564a5b5af28be8093c GIT binary patch literal 100698 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 literal 0 HcmV?d00001 diff --git a/dim/spec/test_input/export_check/using_config/module1.dim b/dim/spec/test_input/export_check/using_config/module1.dim new file mode 100644 index 0000000..e1d2cc5 --- /dev/null +++ b/dim/spec/test_input/export_check/using_config/module1.dim @@ -0,0 +1,9 @@ +module: test_module_1 + +Test_Export_01: + developer: + tester: + text: Test Module Export 1 + +enclosed: + - images/test.jpeg diff --git a/dim/spec/test_input/export_check/using_config/module2.dim b/dim/spec/test_input/export_check/using_config/module2.dim new file mode 100644 index 0000000..9dd4358 --- /dev/null +++ b/dim/spec/test_input/export_check/using_config/module2.dim @@ -0,0 +1,9 @@ +module: test_module_2 + +Test_Export_11: + developer: + tester: + text: Test Module Export 1 + +enclosed: + - images/test_new.jpeg diff --git a/dim/spec/test_input/export_empty_requirements/module.dim b/dim/spec/test_input/export_empty_requirements/module.dim new file mode 100644 index 0000000..1119a97 --- /dev/null +++ b/dim/spec/test_input/export_empty_requirements/module.dim @@ -0,0 +1 @@ +module: export_with_same_enclosed diff --git a/dim/spec/test_input/export_when_media_file_present/different_sample.txt b/dim/spec/test_input/export_when_media_file_present/different_sample.txt new file mode 100644 index 0000000..9a8d8aa --- /dev/null +++ b/dim/spec/test_input/export_when_media_file_present/different_sample.txt @@ -0,0 +1 @@ +Lorem Ipsum diff --git a/dim/spec/test_input/export_when_media_file_present/module.dim b/dim/spec/test_input/export_when_media_file_present/module.dim new file mode 100644 index 0000000..edfb840 --- /dev/null +++ b/dim/spec/test_input/export_when_media_file_present/module.dim @@ -0,0 +1,7 @@ +module: export_test + +enclosed: + - sample.txt + +test_id_1: + text: shall not copy the enclosed file diff --git a/dim/spec/test_input/export_when_media_file_present/sample.txt b/dim/spec/test_input/export_when_media_file_present/sample.txt new file mode 100644 index 0000000..6113104 --- /dev/null +++ b/dim/spec/test_input/export_when_media_file_present/sample.txt @@ -0,0 +1,3 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit, +sed do eiusmod tempor incididunt ut labore et dolore +magna aliqua diff --git a/dim/spec/test_input/export_with_custom_attributes/Config.dim b/dim/spec/test_input/export_with_custom_attributes/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/export_with_custom_attributes/attributes.dim b/dim/spec/test_input/export_with_custom_attributes/attributes.dim new file mode 100644 index 0000000..ee58e22 --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/attributes.dim @@ -0,0 +1,41 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false +version: + type: multi + default: 1.1 + allowed: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 +color: + type: list + default: yellow + allowed: + - red + - green + - yellow + - blue +label: + type: split + default: red + allowed: + - red + - green + - yellow + - blue + - black + - brown + - white + - pink + - orange diff --git a/dim/spec/test_input/export_with_custom_attributes/output/Requirements.csv b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.csv new file mode 100644 index 0000000..5aa191a --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.csv @@ -0,0 +1,5 @@ +Sep=, +id,document_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,verification_methods,status,review_status,comment,miscellaneous,sources,refs,cluster,necessary,version,color,label +"test_id_1","test_module","CompanyName","requirement","First Test Requirement","","","","","not_set","not_set","CompanyName","CompanyName","off_target","invalid","accepted","","","",""," 1.6.5 ","false","1.1","yellow","red" +"test_id_2","test_module","CompanyName","requirement","Second Test Requirement","","","","covered","not_set","not_set","CompanyName","CompanyName","off_target","draft","accepted","","","",""," 1.6.5 ","","1.2, 1.4, 1.5","green, yellow, blue","red" +"test_id_3","test_module","CompanyName","requirement","Third Test Requirement","","","","","not_set","not_set","CompanyName","CompanyName","off_target","draft","unclear","","","",""," x x ","","1.1","yellow","red, orange, pink, white" diff --git a/dim/spec/test_input/export_with_custom_attributes/output/Requirements.json b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.json new file mode 100644 index 0000000..8bbdd28 --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.json @@ -0,0 +1,86 @@ +[ + { + "id": "test_id_1", + "document_name": "test_module", + "originator": "CompanyName", + "type": "requirement", + "text": "First Test Requirement", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "CompanyName", + "tester": "CompanyName", + "verification_methods": "off_target", + "verification_methods": "off_target", + "status": "invalid", + "review_status": "accepted", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "", + "cluster": " 1.6.5 ", + "necessary": "false", + "version": "1.1", + "color": "yellow", + "label": "red" + }, + { + "id": "test_id_2", + "document_name": "test_module", + "originator": "CompanyName", + "type": "requirement", + "text": "Second Test Requirement", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "covered", + "asil": "not_set", + "cal": "not_set", + "developer": "CompanyName", + "tester": "CompanyName", + "verification_methods": "off_target", + "verification_methods": "off_target", + "status": "draft", + "review_status": "accepted", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "", + "cluster": " 1.6.5 ", + "necessary": "", + "version": "1.2, 1.4, 1.5", + "color": "green, yellow, blue", + "label": "red" + }, + { + "id": "test_id_3", + "document_name": "test_module", + "originator": "CompanyName", + "type": "requirement", + "text": "Third Test Requirement", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "CompanyName", + "tester": "CompanyName", + "verification_methods": "off_target", + "verification_methods": "off_target", + "status": "draft", + "review_status": "unclear", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "", + "cluster": "\t\tx\t\tx\t\t", + "necessary": "", + "version": "1.1", + "color": "yellow", + "label": "red, orange, pink, white" + } +] diff --git a/dim/spec/test_input/export_with_custom_attributes/output/Requirements.rst b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.rst new file mode 100644 index 0000000..a3c900d --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/output/Requirements.rst @@ -0,0 +1,77 @@ +:raw-html:`test_module` +======================= + +.. requirement:: test_id_1 + :category: module + :status: invalid + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :cluster: 1.6.5 + :necessary: false + :version: 1.1 + :color: yellow + :label: red + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`First Test Requirement` + +.. requirement:: test_id_2 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :comment: + :miscellaneous: + :refs: + :cluster: 1.6.5 + :necessary: + :version: 1.2, 1.4, 1.5 + :color: green, yellow, blue + :label: red + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`Second Test Requirement` + +.. requirement:: test_id_3 + :category: module + :status: draft + :review_status: unclear + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :cluster:   x  x   + :necessary: + :version: 1.1 + :color: yellow + :label: red, orange, pink, white + :sources: + :feature: + :change_request: + :developer: CompanyName + :tester: CompanyName + :verification_methods: off_target + :verification_criteria: + + :raw-html:`Third Test Requirement` diff --git a/dim/spec/test_input/export_with_custom_attributes/test_module.dim b/dim/spec/test_input/export_with_custom_attributes/test_module.dim new file mode 100644 index 0000000..9cfd9ce --- /dev/null +++ b/dim/spec/test_input/export_with_custom_attributes/test_module.dim @@ -0,0 +1,21 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + cluster: 1.6.5 + tags: covered + version: 1.2, 1.4, 1.5 + color: green, yellow, blue + +test_id_3: + text: Third Test Requirement + review_status: unclear + cluster: x x + label: red, orange, pink, white diff --git a/dim/spec/test_input/filter_check/module.dim b/dim/spec/test_input/filter_check/module.dim new file mode 100644 index 0000000..9ff19ff --- /dev/null +++ b/dim/spec/test_input/filter_check/module.dim @@ -0,0 +1,17 @@ +module: test + +test_id_1: + type: requirement + text: First req + +test_id_2: + type: requirement + text: Second test req + +test_id_3: + type: information + text: test info + +test_id_4: + type: requirement + text: Fourth test req diff --git a/dim/spec/test_input/format/.gitignore b/dim/spec/test_input/format/.gitignore new file mode 100644 index 0000000..94a3dc5 --- /dev/null +++ b/dim/spec/test_input/format/.gitignore @@ -0,0 +1 @@ +*.formatted diff --git a/dim/spec/test_input/format/collection/asil.conf b/dim/spec/test_input/format/collection/asil.conf new file mode 100644 index 0000000..878ee8e --- /dev/null +++ b/dim/spec/test_input/format/collection/asil.conf @@ -0,0 +1,5 @@ +Config: + - originator: UnitTest + files: asil.dim + category: module +Properties: asil.prop diff --git a/dim/spec/test_input/format/collection/asil.dim b/dim/spec/test_input/format/collection/asil.dim new file mode 100644 index 0000000..204c8be --- /dev/null +++ b/dim/spec/test_input/format/collection/asil.dim @@ -0,0 +1,10 @@ +module: abc + +ASIL_not_set: + asil: not_set + +ASIL_QM: + asil: QM + +ASIL_B_D: + asil: ASIL_B(D) diff --git a/dim/spec/test_input/format/collection/asil.dim.expected b/dim/spec/test_input/format/collection/asil.dim.expected new file mode 100644 index 0000000..ce00fd5 --- /dev/null +++ b/dim/spec/test_input/format/collection/asil.dim.expected @@ -0,0 +1,10 @@ +document: abc + +ASIL_not_set: + asil: not_set + +ASIL_QM: + asil: QM + +ASIL_B_D: + asil: ASIL_B(D) diff --git a/dim/spec/test_input/format/collection/asil.prop b/dim/spec/test_input/format/collection/asil.prop new file mode 100644 index 0000000..f7e7c9c --- /dev/null +++ b/dim/spec/test_input/format/collection/asil.prop @@ -0,0 +1,2 @@ +abc: + asil: ASIL_C diff --git a/dim/spec/test_input/format/collection/cal.dim b/dim/spec/test_input/format/collection/cal.dim new file mode 100644 index 0000000..6504360 --- /dev/null +++ b/dim/spec/test_input/format/collection/cal.dim @@ -0,0 +1,23 @@ +module: cal_test + +CAL_R1: + cal: CAL_1 + +CAL_R2: + cal: CAL_2 + +CAL_R3: + cal: CAL_3 + +CAL_R4: + cal: CAL_4 + +CAL_R5: + cal: QM +CAL_R6: + cal: not_set + +CAL_R7: + cal: not_set + +CAL_R8: diff --git a/dim/spec/test_input/format/collection/cal.dim.expected b/dim/spec/test_input/format/collection/cal.dim.expected new file mode 100644 index 0000000..a89710d --- /dev/null +++ b/dim/spec/test_input/format/collection/cal.dim.expected @@ -0,0 +1,24 @@ +document: cal_test + +CAL_R1: + cal: CAL_1 + +CAL_R2: + cal: CAL_2 + +CAL_R3: + cal: CAL_3 + +CAL_R4: + cal: CAL_4 + +CAL_R5: + cal: QM + +CAL_R6: + cal: not_set + +CAL_R7: + cal: not_set + +CAL_R8: diff --git a/dim/spec/test_input/format/collection/change_request.dim b/dim/spec/test_input/format/collection/change_request.dim new file mode 100644 index 0000000..cb4e82f --- /dev/null +++ b/dim/spec/test_input/format/collection/change_request.dim @@ -0,0 +1,16 @@ +module: change_request + +CR_R0: + +CR_R1: + change_request: CrABC + +CR_R2: + change_request: TicketID-000000000001, TicketID-000000000002, TicketID-000000000003, TicketID-000000000004, TicketID-000000000005 + +CR_R3: + change_request: | + :ABC: + +CR_R4: + change_request: \ No newline at end of file diff --git a/dim/spec/test_input/format/collection/change_request.dim.expected b/dim/spec/test_input/format/collection/change_request.dim.expected new file mode 100644 index 0000000..80cdb8e --- /dev/null +++ b/dim/spec/test_input/format/collection/change_request.dim.expected @@ -0,0 +1,17 @@ +document: change_request + +CR_R0: + +CR_R1: + change_request: CrABC + +CR_R2: + change_request: TicketID-000000000001, TicketID-000000000002, TicketID-000000000003, TicketID-000000000004, + TicketID-000000000005 + +CR_R3: + change_request: | + :ABC: + +CR_R4: + change_request: diff --git a/dim/spec/test_input/format/collection/comment.dim b/dim/spec/test_input/format/collection/comment.dim new file mode 100644 index 0000000..0393b86 --- /dev/null +++ b/dim/spec/test_input/format/collection/comment.dim @@ -0,0 +1,18 @@ +module: comment + +COMMENT_R0: + +COMMENT_R1: + comment: First test. + +COMMENT_R2: + comment: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x + y + +COMMENT_R3: + comment: | + :unit: 123. + +COMMENT_R4: + comment: \ No newline at end of file diff --git a/dim/spec/test_input/format/collection/comment.dim.expected b/dim/spec/test_input/format/collection/comment.dim.expected new file mode 100644 index 0000000..6f51d6b --- /dev/null +++ b/dim/spec/test_input/format/collection/comment.dim.expected @@ -0,0 +1,17 @@ +document: comment + +COMMENT_R0: + +COMMENT_R1: + comment: First test. + +COMMENT_R2: + comment: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + y + +COMMENT_R3: + comment: | + :unit: 123. + +COMMENT_R4: + comment: diff --git a/dim/spec/test_input/format/collection/complete.conf b/dim/spec/test_input/format/collection/complete.conf new file mode 100644 index 0000000..a1f7828 --- /dev/null +++ b/dim/spec/test_input/format/collection/complete.conf @@ -0,0 +1,5 @@ +Config: + - originator: UnitTest + files: "*.dim" + category: module +Properties: asil.prop diff --git a/dim/spec/test_input/format/collection/developer.dim b/dim/spec/test_input/format/collection/developer.dim new file mode 100644 index 0000000..1106e8f --- /dev/null +++ b/dim/spec/test_input/format/collection/developer.dim @@ -0,0 +1,13 @@ +module: developer + +Dev_R1: + developer: +Dev_R2: + developer: Lorem Ipsum +Dev_R3: + developer: you +Dev_R4: + developer: you,me +Dev_R5: + developer: | + [you],me diff --git a/dim/spec/test_input/format/collection/developer.dim.expected b/dim/spec/test_input/format/collection/developer.dim.expected new file mode 100644 index 0000000..4aef869 --- /dev/null +++ b/dim/spec/test_input/format/collection/developer.dim.expected @@ -0,0 +1,17 @@ +document: developer + +Dev_R1: + developer: + +Dev_R2: + developer: Lorem Ipsum + +Dev_R3: + developer: you + +Dev_R4: + developer: you, me + +Dev_R5: + developer: | + [you], me diff --git a/dim/spec/test_input/format/collection/enclosedArray.dim b/dim/spec/test_input/format/collection/enclosedArray.dim new file mode 100644 index 0000000..f6c3a3e --- /dev/null +++ b/dim/spec/test_input/format/collection/enclosedArray.dim @@ -0,0 +1,5 @@ +module: enclosed_array + +enclosed: + - enclosedString.dim + - enclosedArray.dim diff --git a/dim/spec/test_input/format/collection/enclosedArray.dim.expected b/dim/spec/test_input/format/collection/enclosedArray.dim.expected new file mode 100644 index 0000000..ea21313 --- /dev/null +++ b/dim/spec/test_input/format/collection/enclosedArray.dim.expected @@ -0,0 +1,5 @@ +document: enclosed_array + +enclosed: + - enclosedString.dim + - enclosedArray.dim diff --git a/dim/spec/test_input/format/collection/enclosedString.dim b/dim/spec/test_input/format/collection/enclosedString.dim new file mode 100644 index 0000000..8eccb93 --- /dev/null +++ b/dim/spec/test_input/format/collection/enclosedString.dim @@ -0,0 +1,4 @@ + module: enclosed_string + + enclosed: + enclosedString.dim diff --git a/dim/spec/test_input/format/collection/enclosedString.dim.expected b/dim/spec/test_input/format/collection/enclosedString.dim.expected new file mode 100644 index 0000000..ee47536 --- /dev/null +++ b/dim/spec/test_input/format/collection/enclosedString.dim.expected @@ -0,0 +1,3 @@ +document: enclosed_string + +enclosed: enclosedString.dim diff --git a/dim/spec/test_input/format/collection/feature.dim b/dim/spec/test_input/format/collection/feature.dim new file mode 100644 index 0000000..65c43c7 --- /dev/null +++ b/dim/spec/test_input/format/collection/feature.dim @@ -0,0 +1,15 @@ +module: feature +FEATURE_R0: + +FEATURE_R1: + feature: FeatureABC + +FEATURE_R2: + feature: TicketID-000000000001, TicketID-000000000002, TicketID-000000000003, TicketID-000000000004, TicketID-000000000005 + +FEATURE_R3: + feature: | + :ABC: + +FEATURE_R4: + feature: \ No newline at end of file diff --git a/dim/spec/test_input/format/collection/feature.dim.expected b/dim/spec/test_input/format/collection/feature.dim.expected new file mode 100644 index 0000000..8be56c9 --- /dev/null +++ b/dim/spec/test_input/format/collection/feature.dim.expected @@ -0,0 +1,17 @@ +document: feature + +FEATURE_R0: + +FEATURE_R1: + feature: FeatureABC + +FEATURE_R2: + feature: TicketID-000000000001, TicketID-000000000002, TicketID-000000000003, TicketID-000000000004, + TicketID-000000000005 + +FEATURE_R3: + feature: | + :ABC: + +FEATURE_R4: + feature: diff --git a/dim/spec/test_input/format/collection/language.dim b/dim/spec/test_input/format/collection/language.dim new file mode 100644 index 0000000..a7fe100 --- /dev/null +++ b/dim/spec/test_input/format/collection/language.dim @@ -0,0 +1,26 @@ +module: language + +LANGUAGE_1: + comment: c + comment_bla: c_bla + +LANGUAGE_2: + text_bla: t_bla + +LANGUAGE_3: + text_bla_fasel: t_bla + +LANGUAGE_4: + text_bla: + +LANGUAGE_5: + verification_criteria_bla: vc + +LANGUAGE_6: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x + +LANGUAGE_7: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x x x x x x x + +LANGUAGE_8: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x diff --git a/dim/spec/test_input/format/collection/language.dim.expected b/dim/spec/test_input/format/collection/language.dim.expected new file mode 100644 index 0000000..fb82925 --- /dev/null +++ b/dim/spec/test_input/format/collection/language.dim.expected @@ -0,0 +1,27 @@ +document: language + +LANGUAGE_1: + comment: c + comment_bla: c_bla + +LANGUAGE_2: + text_bla: t_bla + +LANGUAGE_3: + text_bla_fasel: t_bla + +LANGUAGE_4: + +LANGUAGE_5: + verification_criteria_bla: vc + +LANGUAGE_6: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x + +LANGUAGE_7: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x x x x x x x + +LANGUAGE_8: + verification_criteria_blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x diff --git a/dim/spec/test_input/format/collection/metadataEmpty.dim b/dim/spec/test_input/format/collection/metadataEmpty.dim new file mode 100644 index 0000000..ece7952 --- /dev/null +++ b/dim/spec/test_input/format/collection/metadataEmpty.dim @@ -0,0 +1,4 @@ +module: empty_metadata + +metadata: + diff --git a/dim/spec/test_input/format/collection/metadataEmpty.dim.expected b/dim/spec/test_input/format/collection/metadataEmpty.dim.expected new file mode 100644 index 0000000..1759c15 --- /dev/null +++ b/dim/spec/test_input/format/collection/metadataEmpty.dim.expected @@ -0,0 +1 @@ +document: empty_metadata diff --git a/dim/spec/test_input/format/collection/metadataString.dim b/dim/spec/test_input/format/collection/metadataString.dim new file mode 100644 index 0000000..862c4bc --- /dev/null +++ b/dim/spec/test_input/format/collection/metadataString.dim @@ -0,0 +1,6 @@ + module: metadata_string + + metadata: > + [Version 1.0] LAH xy + + Exported at January 1, 2000 diff --git a/dim/spec/test_input/format/collection/metadataString.dim.expected b/dim/spec/test_input/format/collection/metadataString.dim.expected new file mode 100644 index 0000000..02e60fe --- /dev/null +++ b/dim/spec/test_input/format/collection/metadataString.dim.expected @@ -0,0 +1,5 @@ +document: metadata_string + +metadata: | + [Version 1.0] LAH xy + Exported at January 1, 2000 diff --git a/dim/spec/test_input/format/collection/miscellaneous.dim b/dim/spec/test_input/format/collection/miscellaneous.dim new file mode 100644 index 0000000..19a25c1 --- /dev/null +++ b/dim/spec/test_input/format/collection/miscellaneous.dim @@ -0,0 +1,10 @@ +module: miscellaneous + +MISC_R0: + miscellaneous: + +MISC_R1: + miscellaneous: | + First test. +MISC_R2: + miscellaneous: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y diff --git a/dim/spec/test_input/format/collection/miscellaneous.dim.expected b/dim/spec/test_input/format/collection/miscellaneous.dim.expected new file mode 100644 index 0000000..e3e4307 --- /dev/null +++ b/dim/spec/test_input/format/collection/miscellaneous.dim.expected @@ -0,0 +1,11 @@ +document: miscellaneous + +MISC_R0: + miscellaneous: + +MISC_R1: + miscellaneous: First test. + +MISC_R2: + miscellaneous: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + y diff --git a/dim/spec/test_input/format/collection/oneLiners.dim b/dim/spec/test_input/format/collection/oneLiners.dim new file mode 100644 index 0000000..3c6e56a --- /dev/null +++ b/dim/spec/test_input/format/collection/oneLiners.dim @@ -0,0 +1,27 @@ +module: one_liners + +REQ_0a: info In total 150 chars in one-liner...................................................................................... +REQ_0b: + type: information + text: In total 150 chars in one-liner...................................................................................... + tags: + comment: + +REQ_0c: info In total 151 chars in one-liner....................................................................................... +REQ_0d: + type: information + text: In total 150 chars in one-liner...................................................................................... + +REQ_1a: | + info + Single Line Stripped + +REQ_1b: | + info + Multi Line: + - bla + - fasel + +REQ_2a: + type: heading_0 + text: MyHeading diff --git a/dim/spec/test_input/format/collection/oneLiners.dim.expected b/dim/spec/test_input/format/collection/oneLiners.dim.expected new file mode 100644 index 0000000..0f0326f --- /dev/null +++ b/dim/spec/test_input/format/collection/oneLiners.dim.expected @@ -0,0 +1,28 @@ +document: one_liners + +REQ_0a: info In total 150 chars in one-liner...................................................................................... + +REQ_0b: + type: information + text: In total 150 chars in + one-liner...................................................................................... + tags: + comment: + +REQ_0c: + type: information + text: In total 151 chars in + one-liner....................................................................................... + +REQ_0d: info In total 150 chars in one-liner...................................................................................... + +REQ_1a: info Single Line Stripped + +REQ_1b: + type: information + text: | + Multi Line: + - bla + - fasel + +REQ_2a: h0 MyHeading diff --git a/dim/spec/test_input/format/collection/onlyModule.dim b/dim/spec/test_input/format/collection/onlyModule.dim new file mode 100644 index 0000000..0706642 --- /dev/null +++ b/dim/spec/test_input/format/collection/onlyModule.dim @@ -0,0 +1 @@ +module: ABC \ No newline at end of file diff --git a/dim/spec/test_input/format/collection/onlyModule.dim.expected b/dim/spec/test_input/format/collection/onlyModule.dim.expected new file mode 100644 index 0000000..34f3e68 --- /dev/null +++ b/dim/spec/test_input/format/collection/onlyModule.dim.expected @@ -0,0 +1 @@ +document: ABC diff --git a/dim/spec/test_input/format/collection/order.dim b/dim/spec/test_input/format/collection/order.dim new file mode 100644 index 0000000..6c75d73 --- /dev/null +++ b/dim/spec/test_input/format/collection/order.dim @@ -0,0 +1,33 @@ +module: ordered + +enclosed: + - order.dim + - order.dim.expected + +REQ1: + verification_criteria: VC + refs: REQ2 + asil: ASIL_B + tester: me + status: valid + sources: x.y + miscellaneous: MISC + developer: you + text: Do it now! + type: information + tags: memory + text_french: fr + text_german: gr + test_setups: on_target + review_status: unclear + verification_criteria_german: vgr + comment_german: cgr + comment_italian: igr + comment: Oh well. + cal: QM + verification_criteria_french: vfr + +metadata: V1 + +REQ2: + diff --git a/dim/spec/test_input/format/collection/order.dim.expected b/dim/spec/test_input/format/collection/order.dim.expected new file mode 100644 index 0000000..329ee96 --- /dev/null +++ b/dim/spec/test_input/format/collection/order.dim.expected @@ -0,0 +1,32 @@ +document: ordered + +metadata: V1 + +REQ1: + type: information + text: Do it now! + text_french: fr + text_german: gr + verification_criteria: VC + verification_criteria_french: vfr + verification_criteria_german: vgr + tags: memory + asil: ASIL_B + cal: QM + developer: you + tester: me + verification_methods: on_target + status: valid + review_status: unclear + comment: Oh well. + comment_german: cgr + comment_italian: igr + miscellaneous: MISC + sources: x.y + refs: REQ2 + +REQ2: + +enclosed: + - order.dim + - order.dim.expected diff --git a/dim/spec/test_input/format/collection/refs.dim b/dim/spec/test_input/format/collection/refs.dim new file mode 100644 index 0000000..a609981 --- /dev/null +++ b/dim/spec/test_input/format/collection/refs.dim @@ -0,0 +1,10 @@ +module: references + +REFS_R1: + refs: + +REFS_R2: + refs: REFS_R1 + +REFS_R3: + refs: REFS_R1,REFS_R2,REFS_R1 diff --git a/dim/spec/test_input/format/collection/refs.dim.expected b/dim/spec/test_input/format/collection/refs.dim.expected new file mode 100644 index 0000000..7b1c74d --- /dev/null +++ b/dim/spec/test_input/format/collection/refs.dim.expected @@ -0,0 +1,12 @@ +document: references + +REFS_R1: + refs: + +REFS_R2: + refs: REFS_R1 + +REFS_R3: + refs: > + REFS_R1, + REFS_R2 diff --git a/dim/spec/test_input/format/collection/review_status.dim b/dim/spec/test_input/format/collection/review_status.dim new file mode 100644 index 0000000..a8509a2 --- /dev/null +++ b/dim/spec/test_input/format/collection/review_status.dim @@ -0,0 +1,8 @@ +module: review + +RS_R1: + +RS_R2: + review_status: accepted +RS_R3: + review_status: not_reviewed diff --git a/dim/spec/test_input/format/collection/review_status.dim.expected b/dim/spec/test_input/format/collection/review_status.dim.expected new file mode 100644 index 0000000..a10e274 --- /dev/null +++ b/dim/spec/test_input/format/collection/review_status.dim.expected @@ -0,0 +1,9 @@ +document: review + +RS_R1: + +RS_R2: + review_status: accepted + +RS_R3: + review_status: not_reviewed diff --git a/dim/spec/test_input/format/collection/sources.dim b/dim/spec/test_input/format/collection/sources.dim new file mode 100644 index 0000000..0a37e76 --- /dev/null +++ b/dim/spec/test_input/format/collection/sources.dim @@ -0,0 +1,10 @@ +module: source_test + +SOURCES_S1: + sources: + +SOURCES_S2: + sources: "xy/z.cpp,xy/z.cpp" + +SOURCES_S3: + sources: abc.h,xy/z.cpp diff --git a/dim/spec/test_input/format/collection/sources.dim.expected b/dim/spec/test_input/format/collection/sources.dim.expected new file mode 100644 index 0000000..a90a1d6 --- /dev/null +++ b/dim/spec/test_input/format/collection/sources.dim.expected @@ -0,0 +1,12 @@ +document: source_test + +SOURCES_S1: + sources: + +SOURCES_S2: + sources: xy/z.cpp + +SOURCES_S3: + sources: > + abc.h, + xy/z.cpp diff --git a/dim/spec/test_input/format/collection/status.dim b/dim/spec/test_input/format/collection/status.dim new file mode 100644 index 0000000..062c43c --- /dev/null +++ b/dim/spec/test_input/format/collection/status.dim @@ -0,0 +1,39 @@ +module: status_test + +STATUS_R1: + status: valid + +STATUS_R2: + status: draft + +STATUS_R3: + +STATUS_R4: + +STATUS_H1: + type: heading_1 + status: valid + +STATUS_H2: + type: heading_1 + status: draft + +STATUS_H3: + type: heading_1 + +STATUS_H4: + type: heading_1 + +STATUS_I1: + type: information + status: valid + +STATUS_I2: + type: information + status: draft + +STATUS_I3: + type: information + +STATUS_I4: + type: information diff --git a/dim/spec/test_input/format/collection/status.dim.expected b/dim/spec/test_input/format/collection/status.dim.expected new file mode 100644 index 0000000..dc9f8c5 --- /dev/null +++ b/dim/spec/test_input/format/collection/status.dim.expected @@ -0,0 +1,39 @@ +document: status_test + +STATUS_R1: + status: valid + +STATUS_R2: + status: draft + +STATUS_R3: + +STATUS_R4: + +STATUS_H1: + type: heading_1 + status: valid + +STATUS_H2: + type: heading_1 + status: draft + +STATUS_H3: + type: heading_1 + +STATUS_H4: + type: heading_1 + +STATUS_I1: + type: information + status: valid + +STATUS_I2: + type: information + status: draft + +STATUS_I3: + type: information + +STATUS_I4: + type: information diff --git a/dim/spec/test_input/format/collection/tags.dim b/dim/spec/test_input/format/collection/tags.dim new file mode 100644 index 0000000..41a212e --- /dev/null +++ b/dim/spec/test_input/format/collection/tags.dim @@ -0,0 +1,10 @@ +module: tag_test + +TAGS_R1: + tags: + +TAGS_R2: + tags: memory + +TAGS_R3: + tags: memory,performance,memory diff --git a/dim/spec/test_input/format/collection/tags.dim.expected b/dim/spec/test_input/format/collection/tags.dim.expected new file mode 100644 index 0000000..11d3456 --- /dev/null +++ b/dim/spec/test_input/format/collection/tags.dim.expected @@ -0,0 +1,10 @@ +document: tag_test + +TAGS_R1: + tags: + +TAGS_R2: + tags: memory + +TAGS_R3: + tags: memory, performance diff --git a/dim/spec/test_input/format/collection/test_setups.dim b/dim/spec/test_input/format/collection/test_setups.dim new file mode 100644 index 0000000..10ab22d --- /dev/null +++ b/dim/spec/test_input/format/collection/test_setups.dim @@ -0,0 +1,11 @@ +module: test_setup + +TS_R1: +TS_R2: +TS_R3: + test_setups: off_target,off_target +TS_R4: + test_setups: off_target +TS_R5: + test_setups: | + off_target,off_target,on_target,on_target diff --git a/dim/spec/test_input/format/collection/test_setups.dim.expected b/dim/spec/test_input/format/collection/test_setups.dim.expected new file mode 100644 index 0000000..eaf15b7 --- /dev/null +++ b/dim/spec/test_input/format/collection/test_setups.dim.expected @@ -0,0 +1,14 @@ +document: test_setup + +TS_R1: + +TS_R2: + +TS_R3: + verification_methods: off_target + +TS_R4: + verification_methods: off_target + +TS_R5: + verification_methods: off_target, on_target diff --git a/dim/spec/test_input/format/collection/tester.dim b/dim/spec/test_input/format/collection/tester.dim new file mode 100644 index 0000000..4d686dd --- /dev/null +++ b/dim/spec/test_input/format/collection/tester.dim @@ -0,0 +1,13 @@ +module: tester + +TESTER_R1: + tester: +TESTER_R2: + tester: auto +TESTER_R3: + tester: you +TESTER_R4: + tester: you,me +TESTER_R5: + tester: | + :you:, me diff --git a/dim/spec/test_input/format/collection/tester.dim.expected b/dim/spec/test_input/format/collection/tester.dim.expected new file mode 100644 index 0000000..11bdd1a --- /dev/null +++ b/dim/spec/test_input/format/collection/tester.dim.expected @@ -0,0 +1,17 @@ +document: tester + +TESTER_R1: + tester: + +TESTER_R2: + tester: auto + +TESTER_R3: + tester: you + +TESTER_R4: + tester: you, me + +TESTER_R5: + tester: | + :you:, me diff --git a/dim/spec/test_input/format/collection/text.dim b/dim/spec/test_input/format/collection/text.dim new file mode 100644 index 0000000..ae7ad10 --- /dev/null +++ b/dim/spec/test_input/format/collection/text.dim @@ -0,0 +1,119 @@ +module: text_test + +TEXT_R0: + text: + +TEXT_R1a: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + +TEXT_R1b: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y z + +TEXT_R1c: + text: Xx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + +TEXT_R1d: + text: Xx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y z + +TEXT_R1e: + text: > + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + +TEXT_R1f: + text: | + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + +TEXT_R1g: + text: | + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + y + +TEXT_R1h: + text: | + This + is + fine + +TEXT_R1i: + text: | + This: + - is + - fine + +TEXT_R2a: + text: " " + +TEXT_R2b: + text: " " + +TEXT_R2c: + text: " \n " + +TEXT_R2e: + text: "abc def" + +TEXT_R2e2: + text: "abc def" + +TEXT_R2e3: + text: "abc def" + +TEXT_R2f: + text: "abc \n def" + +TEXT_R3a: + text: "#abc" + +TEXT_R3b: + text: "[abc" + +TEXT_R4a: + text: "abc:def" + +TEXT_R4b: + text: "abc: def" + +TEXT_R4c: + text: "abc :def" + +TEXT_R4d: + text: "abc:" + +TEXT_R4e: + text: "abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc:" + +TEXT_R4f: + text: "'abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc:" + +TEXT_R4g: + text: "'abc' abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc:" + +TEXT_R5a: + text: "abc#def" + +TEXT_R5b: + text: "abc# def" + +TEXT_R5c: + text: "abc #def" + +TEXT_R5d: + text: "abc#" + +TEXT_R6a: + text: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +TEXT_R6b: + text: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaa + +TEXT_R7: + text: true diff --git a/dim/spec/test_input/format/collection/text.dim.expected b/dim/spec/test_input/format/collection/text.dim.expected new file mode 100644 index 0000000..f0a0f6f --- /dev/null +++ b/dim/spec/test_input/format/collection/text.dim.expected @@ -0,0 +1,136 @@ +document: text_test + +TEXT_R0: + text: + +TEXT_R1a: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + +TEXT_R1b: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + z + +TEXT_R1c: + text: Xx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + +TEXT_R1d: + text: Xx x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y + z + +TEXT_R1e: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x + +TEXT_R1f: + text: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + x x x x x x x x x x x x x x x x x x x x x x + +TEXT_R1g: + text: | + x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + y + +TEXT_R1h: + text: | + This + is + fine + +TEXT_R1i: + text: | + This: + - is + - fine + +TEXT_R2a: + text: + +TEXT_R2b: + text: + +TEXT_R2c: + text: + +TEXT_R2e: + text: abc def + +TEXT_R2e2: + text: abc def + +TEXT_R2e3: + text: > + abc + def + +TEXT_R2f: + text: | + abc + def + +TEXT_R3a: + text: | + #abc + +TEXT_R3b: + text: | + [abc + +TEXT_R4a: + text: abc:def + +TEXT_R4b: + text: | + abc: def + +TEXT_R4c: + text: abc :def + +TEXT_R4d: + text: | + abc: + +TEXT_R4e: + text: > + abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc + abc abc abc: + +TEXT_R4f: + text: > + 'abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc + abc abc abc: + +TEXT_R4g: + text: > + 'abc' abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc abc + abc abc abc abc: + +TEXT_R5a: + text: abc#def + +TEXT_R5b: + text: abc# def + +TEXT_R5c: + text: | + abc #def + +TEXT_R5d: + text: abc# + +TEXT_R6a: + text: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + +TEXT_R6b: + text: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaa + +TEXT_R7: + text: true diff --git a/dim/spec/test_input/format/collection/type.dim b/dim/spec/test_input/format/collection/type.dim new file mode 100644 index 0000000..212abcb --- /dev/null +++ b/dim/spec/test_input/format/collection/type.dim @@ -0,0 +1,9 @@ +module: type_test + +TYPE_R1: + type: heading_1 + +TYPE_R2: + type: heading_20 +TYPE_R3: + type: requirement diff --git a/dim/spec/test_input/format/collection/type.dim.expected b/dim/spec/test_input/format/collection/type.dim.expected new file mode 100644 index 0000000..94a0270 --- /dev/null +++ b/dim/spec/test_input/format/collection/type.dim.expected @@ -0,0 +1,10 @@ +document: type_test + +TYPE_R1: + type: heading_1 + +TYPE_R2: + type: heading_20 + +TYPE_R3: + type: requirement diff --git a/dim/spec/test_input/format/collection/verification_criteria.dim b/dim/spec/test_input/format/collection/verification_criteria.dim new file mode 100644 index 0000000..1a58bb6 --- /dev/null +++ b/dim/spec/test_input/format/collection/verification_criteria.dim @@ -0,0 +1,10 @@ +module: verification_test + +VC_R0: + verification_criteria: + +VC_R1: + verification_criteria: | + First test. +VC_R2: + verification_criteria: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x y diff --git a/dim/spec/test_input/format/collection/verification_criteria.dim.expected b/dim/spec/test_input/format/collection/verification_criteria.dim.expected new file mode 100644 index 0000000..752959b --- /dev/null +++ b/dim/spec/test_input/format/collection/verification_criteria.dim.expected @@ -0,0 +1,11 @@ +document: verification_test + +VC_R0: + verification_criteria: + +VC_R1: + verification_criteria: First test. + +VC_R2: + verification_criteria: x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x + y diff --git a/dim/spec/test_input/format/collection/verification_methods.dim b/dim/spec/test_input/format/collection/verification_methods.dim new file mode 100644 index 0000000..a062691 --- /dev/null +++ b/dim/spec/test_input/format/collection/verification_methods.dim @@ -0,0 +1,11 @@ +module: verification_methods + +VM_R1: +VM_R2: +VM_R3: + verification_methods: off_target,off_target +VM_R4: + verification_methods: off_target +VM_R5: + verification_methods: | + off_target,off_target,on_target,on_target diff --git a/dim/spec/test_input/format/collection/verification_methods.dim.expected b/dim/spec/test_input/format/collection/verification_methods.dim.expected new file mode 100644 index 0000000..49e4825 --- /dev/null +++ b/dim/spec/test_input/format/collection/verification_methods.dim.expected @@ -0,0 +1,14 @@ +document: verification_methods + +VM_R1: + +VM_R2: + +VM_R3: + verification_methods: off_target + +VM_R4: + verification_methods: off_target + +VM_R5: + verification_methods: off_target, on_target diff --git a/dim/spec/test_input/format/empty/none.dim b/dim/spec/test_input/format/empty/none.dim new file mode 100644 index 0000000..34868c9 --- /dev/null +++ b/dim/spec/test_input/format/empty/none.dim @@ -0,0 +1 @@ +document: empty diff --git a/dim/spec/test_input/format/empty/none.dim.expected b/dim/spec/test_input/format/empty/none.dim.expected new file mode 100644 index 0000000..34868c9 --- /dev/null +++ b/dim/spec/test_input/format/empty/none.dim.expected @@ -0,0 +1 @@ +document: empty diff --git a/dim/spec/test_input/format/inplace/.gitignore b/dim/spec/test_input/format/inplace/.gitignore new file mode 100644 index 0000000..bef8ee8 --- /dev/null +++ b/dim/spec/test_input/format/inplace/.gitignore @@ -0,0 +1,2 @@ +first.inplace.dim +second.inplace.dim diff --git a/dim/spec/test_input/format/inplace/complete.conf b/dim/spec/test_input/format/inplace/complete.conf new file mode 100644 index 0000000..e9a64e8 --- /dev/null +++ b/dim/spec/test_input/format/inplace/complete.conf @@ -0,0 +1,6 @@ +Config: + - originator: UnitTest + files: + - first.inplace.dim + - second.inplace.dim + category: module diff --git a/dim/spec/test_input/format/inplace/complete_extra.conf b/dim/spec/test_input/format/inplace/complete_extra.conf new file mode 100644 index 0000000..eb02a49 --- /dev/null +++ b/dim/spec/test_input/format/inplace/complete_extra.conf @@ -0,0 +1,6 @@ +Config: + - originator: UnitTest + files: + - first.dim + - second.dim + category: module diff --git a/dim/spec/test_input/format/inplace/first.dim b/dim/spec/test_input/format/inplace/first.dim new file mode 100644 index 0000000..f6233af --- /dev/null +++ b/dim/spec/test_input/format/inplace/first.dim @@ -0,0 +1,4 @@ +R0: + text: INPLACE + +module: abc diff --git a/dim/spec/test_input/format/inplace/first.dim.expected b/dim/spec/test_input/format/inplace/first.dim.expected new file mode 100644 index 0000000..df8bcb7 --- /dev/null +++ b/dim/spec/test_input/format/inplace/first.dim.expected @@ -0,0 +1,4 @@ +document: abc + +R0: + text: INPLACE diff --git a/dim/spec/test_input/format/inplace/second.dim b/dim/spec/test_input/format/inplace/second.dim new file mode 100644 index 0000000..288f11f --- /dev/null +++ b/dim/spec/test_input/format/inplace/second.dim @@ -0,0 +1,6 @@ +module: abc +R1: + type: heading_1 + text: Soso + + diff --git a/dim/spec/test_input/format/inplace/second.dim.expected b/dim/spec/test_input/format/inplace/second.dim.expected new file mode 100644 index 0000000..56da59a --- /dev/null +++ b/dim/spec/test_input/format/inplace/second.dim.expected @@ -0,0 +1,3 @@ +document: abc + +R1: h1 Soso diff --git a/dim/spec/test_input/format/with_custom_attributes/Config.dim b/dim/spec/test_input/format/with_custom_attributes/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/format/with_custom_attributes/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/format/with_custom_attributes/attributes.dim b/dim/spec/test_input/format/with_custom_attributes/attributes.dim new file mode 100644 index 0000000..683d56e --- /dev/null +++ b/dim/spec/test_input/format/with_custom_attributes/attributes.dim @@ -0,0 +1,39 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false +version: + type: list + default: 1.1 + allowed: + - 1.1 + - 1.2 + - 1.3 + - 1.4 + - 1.5 + - 1.6 + - 1.7 + - 1.8 +color: + type: multi + allowed: + - green + - yellow + - blue + default: green +label: + type: split + default: red + allowed: + - red + - orange + - pink + - white + - gray + - black diff --git a/dim/spec/test_input/format/with_custom_attributes/test_module.dim b/dim/spec/test_input/format/with_custom_attributes/test_module.dim new file mode 100644 index 0000000..3b474db --- /dev/null +++ b/dim/spec/test_input/format/with_custom_attributes/test_module.dim @@ -0,0 +1,21 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + cluster: 1.6.5 + tags: covered + version: 1.2, 1.4, 1.5 + color: green, yellow + +test_id_3: + text: Third Test Requirement + review_status: unclear + cluster: x x + label: red, orange, pink, white diff --git a/dim/spec/test_input/format/with_custom_attributes/test_module.dim.expected b/dim/spec/test_input/format/with_custom_attributes/test_module.dim.expected new file mode 100644 index 0000000..a724723 --- /dev/null +++ b/dim/spec/test_input/format/with_custom_attributes/test_module.dim.expected @@ -0,0 +1,25 @@ +document: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + tags: covered + review_status: accepted + cluster: 1.6.5 + version: 1.2, 1.4, 1.5 + color: green, yellow + +test_id_3: + text: Third Test Requirement + review_status: unclear + cluster: x x + label: > + red, + orange, + pink, + white diff --git a/dim/spec/test_input/format_lineendings/.gitattributes b/dim/spec/test_input/format_lineendings/.gitattributes new file mode 100644 index 0000000..26aabf1 --- /dev/null +++ b/dim/spec/test_input/format_lineendings/.gitattributes @@ -0,0 +1,3 @@ +crlf.dim text eol=crlf +lf.dim text eol=lf +mixed.dim binary diff --git a/dim/spec/test_input/format_lineendings/crlf.dim b/dim/spec/test_input/format_lineendings/crlf.dim new file mode 100644 index 0000000..97b5edc --- /dev/null +++ b/dim/spec/test_input/format_lineendings/crlf.dim @@ -0,0 +1,4 @@ +document: ABC + +SRS_A_B: + text: dummy diff --git a/dim/spec/test_input/format_lineendings/lf.dim b/dim/spec/test_input/format_lineendings/lf.dim new file mode 100644 index 0000000..97b5edc --- /dev/null +++ b/dim/spec/test_input/format_lineendings/lf.dim @@ -0,0 +1,4 @@ +document: ABC + +SRS_A_B: + text: dummy diff --git a/dim/spec/test_input/format_lineendings/mixed.dim b/dim/spec/test_input/format_lineendings/mixed.dim new file mode 100644 index 0000000..e89ef33 --- /dev/null +++ b/dim/spec/test_input/format_lineendings/mixed.dim @@ -0,0 +1,4 @@ +document: ABC + +SRS_A_B: + text: dummy diff --git a/dim/spec/test_input/invalid_attributes/default_auto.dim b/dim/spec/test_input/invalid_attributes/default_auto.dim new file mode 100644 index 0000000..2877321 --- /dev/null +++ b/dim/spec/test_input/invalid_attributes/default_auto.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: 'auto' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/invalid_attributes/invalid_allowed.dim b/dim/spec/test_input/invalid_attributes/invalid_allowed.dim new file mode 100644 index 0000000..cf3049d --- /dev/null +++ b/dim/spec/test_input/invalid_attributes/invalid_allowed.dim @@ -0,0 +1,7 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: red + allowed: red, green diff --git a/dim/spec/test_input/invalid_attributes/invalid_default.dim b/dim/spec/test_input/invalid_attributes/invalid_default.dim new file mode 100644 index 0000000..88b03ff --- /dev/null +++ b/dim/spec/test_input/invalid_attributes/invalid_default.dim @@ -0,0 +1,9 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: red + allowed: + - green + - blue diff --git a/dim/spec/test_input/invalid_attributes/invalid_type.dim b/dim/spec/test_input/invalid_attributes/invalid_type.dim new file mode 100644 index 0000000..f772b2a --- /dev/null +++ b/dim/spec/test_input/invalid_attributes/invalid_type.dim @@ -0,0 +1,10 @@ +cluster: + type: multiple + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/invalid_attributes/test_module.dim b/dim/spec/test_input/invalid_attributes/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/invalid_attributes/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/invalid_format_style/module.dim b/dim/spec/test_input/invalid_format_style/module.dim new file mode 100644 index 0000000..8d8b356 --- /dev/null +++ b/dim/spec/test_input/invalid_format_style/module.dim @@ -0,0 +1,5 @@ +module: invalid_format_style + +id_1: + text: when invalid format style is given for the attribute + dummy: lorem ipsum diff --git a/dim/spec/test_input/invalid_input/absolute_file_path.dim b/dim/spec/test_input/invalid_input/absolute_file_path.dim new file mode 100644 index 0000000..31d394a --- /dev/null +++ b/dim/spec/test_input/invalid_input/absolute_file_path.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: /modules/test_module_1.dim + category: module diff --git a/dim/spec/test_input/invalid_input/backward_config.dim b/dim/spec/test_input/invalid_input/backward_config.dim new file mode 100644 index 0000000..30f297c --- /dev/null +++ b/dim/spec/test_input/invalid_input/backward_config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + category: system + files: + - .\modules\duplicate_module.dim diff --git a/dim/spec/test_input/invalid_input/category_array.dim b/dim/spec/test_input/invalid_input/category_array.dim new file mode 100644 index 0000000..ea3a965 --- /dev/null +++ b/dim/spec/test_input/invalid_input/category_array.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: abc + category: + - module + - system diff --git a/dim/spec/test_input/invalid_input/config_string.dim b/dim/spec/test_input/invalid_input/config_string.dim new file mode 100644 index 0000000..592747d --- /dev/null +++ b/dim/spec/test_input/invalid_input/config_string.dim @@ -0,0 +1 @@ +Config: Wrong diff --git a/dim/spec/test_input/invalid_input/custom_attributes.dim b/dim/spec/test_input/invalid_input/custom_attributes.dim new file mode 100644 index 0000000..33199a0 --- /dev/null +++ b/dim/spec/test_input/invalid_input/custom_attributes.dim @@ -0,0 +1,7 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: + - attributes.dim diff --git a/dim/spec/test_input/invalid_input/duplicate_files.dim b/dim/spec/test_input/invalid_input/duplicate_files.dim new file mode 100644 index 0000000..dd8c843 --- /dev/null +++ b/dim/spec/test_input/invalid_input/duplicate_files.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - modules/duplicate_module.dim + - modules/duplicate_module.dim + category: module diff --git a/dim/spec/test_input/invalid_input/duplicate_metadata.dim b/dim/spec/test_input/invalid_input/duplicate_metadata.dim new file mode 100644 index 0000000..9069b08 --- /dev/null +++ b/dim/spec/test_input/invalid_input/duplicate_metadata.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - modules/duplicate_meta1.dim + - modules/duplicate_meta2.dim + category: module diff --git a/dim/spec/test_input/invalid_input/empty_yaml.dim b/dim/spec/test_input/invalid_input/empty_yaml.dim new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/invalid_input/files_key_invalid_string.dim b/dim/spec/test_input/invalid_input/files_key_invalid_string.dim new file mode 100644 index 0000000..21f10aa --- /dev/null +++ b/dim/spec/test_input/invalid_input/files_key_invalid_string.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: + category: module diff --git a/dim/spec/test_input/invalid_input/files_key_no_array.dim b/dim/spec/test_input/invalid_input/files_key_no_array.dim new file mode 100644 index 0000000..57defb6 --- /dev/null +++ b/dim/spec/test_input/invalid_input/files_key_no_array.dim @@ -0,0 +1,3 @@ +Config: + CompanyName: + Files: \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/hash_in_files.dim b/dim/spec/test_input/invalid_input/hash_in_files.dim new file mode 100644 index 0000000..efc2e4c --- /dev/null +++ b/dim/spec/test_input/invalid_input/hash_in_files.dim @@ -0,0 +1,6 @@ +Config: + - originator: bla + files: + yeah: aa + super: bb + category: module diff --git a/dim/spec/test_input/invalid_input/invalid_config_entry_attribute.dim b/dim/spec/test_input/invalid_input/invalid_config_entry_attribute.dim new file mode 100644 index 0000000..bcea61f --- /dev/null +++ b/dim/spec/test_input/invalid_input/invalid_config_entry_attribute.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: abc + category: software + wrong: attribute diff --git a/dim/spec/test_input/invalid_input/invalid_config_toplevel_attribute.dim b/dim/spec/test_input/invalid_input/invalid_config_toplevel_attribute.dim new file mode 100644 index 0000000..86bad8c --- /dev/null +++ b/dim/spec/test_input/invalid_input/invalid_config_toplevel_attribute.dim @@ -0,0 +1,7 @@ +Config: + CompanyName: + files: + - modules/duplicate_module.dim + category: module + +Test: diff --git a/dim/spec/test_input/invalid_input/invalid_enclosed.dim b/dim/spec/test_input/invalid_input/invalid_enclosed.dim new file mode 100644 index 0000000..1fcd568 --- /dev/null +++ b/dim/spec/test_input/invalid_input/invalid_enclosed.dim @@ -0,0 +1,6 @@ +module: invalid_enclosed + +enclosed: + - /module/valid_test_1.dim + +ESR_Test_1: diff --git a/dim/spec/test_input/invalid_input/invalid_originator.dim b/dim/spec/test_input/invalid_input/invalid_originator.dim new file mode 100644 index 0000000..968767c --- /dev/null +++ b/dim/spec/test_input/invalid_input/invalid_originator.dim @@ -0,0 +1,6 @@ +Config: + - originator: 334 + files: + - modules/test_module_1.dim + - modules/test_module_2.dim + category: module diff --git a/dim/spec/test_input/invalid_input/invalid_types.dim b/dim/spec/test_input/invalid_input/invalid_types.dim new file mode 100644 index 0000000..5b13a8c --- /dev/null +++ b/dim/spec/test_input/invalid_input/invalid_types.dim @@ -0,0 +1,9 @@ +Config: + - originator: CompanyName + files: modules/test_module_1.dim + category: module + - originator: Customer + files: + - modules/test_module_1.dim + - modules/test_module_2.dim + category: test diff --git a/dim/spec/test_input/invalid_input/missing_config_entry_attribute.dim b/dim/spec/test_input/invalid_input/missing_config_entry_attribute.dim new file mode 100644 index 0000000..59cc9fd --- /dev/null +++ b/dim/spec/test_input/invalid_input/missing_config_entry_attribute.dim @@ -0,0 +1,3 @@ +Config: + - originator: CompanyName + files: abc diff --git a/dim/spec/test_input/invalid_input/modules/attribute_empty.dim b/dim/spec/test_input/invalid_input/modules/attribute_empty.dim new file mode 100644 index 0000000..33e6e8e --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/attribute_empty.dim @@ -0,0 +1,4 @@ +module: test_module + +test_id_1: + text: \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/modules/attribute_no_string.dim b/dim/spec/test_input/invalid_input/modules/attribute_no_string.dim new file mode 100644 index 0000000..663c237 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/attribute_no_string.dim @@ -0,0 +1,5 @@ +module: test_module + +test_id_1: + text: + - test \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/modules/duplicate_keys.dim b/dim/spec/test_input/invalid_input/modules/duplicate_keys.dim new file mode 100644 index 0000000..60d074b --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/duplicate_keys.dim @@ -0,0 +1,6 @@ +module: test + +test_id_1: + text: some text + review_status: unclear + text: some other text diff --git a/dim/spec/test_input/invalid_input/modules/duplicate_meta1.dim b/dim/spec/test_input/invalid_input/modules/duplicate_meta1.dim new file mode 100644 index 0000000..15fb974 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/duplicate_meta1.dim @@ -0,0 +1,3 @@ +module: ABC + +metadata: Description 1 diff --git a/dim/spec/test_input/invalid_input/modules/duplicate_meta2.dim b/dim/spec/test_input/invalid_input/modules/duplicate_meta2.dim new file mode 100644 index 0000000..90becca --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/duplicate_meta2.dim @@ -0,0 +1,3 @@ +module: ABC + +metadata: Description 2 diff --git a/dim/spec/test_input/invalid_input/modules/duplicate_module.dim b/dim/spec/test_input/invalid_input/modules/duplicate_module.dim new file mode 100644 index 0000000..da41ded --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/duplicate_module.dim @@ -0,0 +1,4 @@ +module: test + +test_id: + text: test_value \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/modules/subfolder/Config.dim b/dim/spec/test_input/invalid_input/modules/subfolder/Config.dim new file mode 100644 index 0000000..3da28b3 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/subfolder/Config.dim @@ -0,0 +1,6 @@ +Config: + CompanyName: + files: + - ../valid_test_1.dim + - ../valid_test_2.dim + category: module \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/modules/test_module_1.dim b/dim/spec/test_input/invalid_input/modules/test_module_1.dim new file mode 100644 index 0000000..2db0ee9 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/test_module_1.dim @@ -0,0 +1,19 @@ +module: test_module_1 + +test_id_1: + text: Another test req + tags: established, process, covered, tested + feature: Blah + verification_criteria: Value xy shall equal value ab. + test_setups: on_target, off_target + miscellaneous: Additional random information + comment: Req is nice + asil: ASIL_A + tester: xy_company + refs: test_id_2 + +test_id_1b: + text: Second test req Bold + +test_id_1c: + text: Third test req Bold diff --git a/dim/spec/test_input/invalid_input/modules/test_module_2.dim b/dim/spec/test_input/invalid_input/modules/test_module_2.dim new file mode 100644 index 0000000..5f6fedc --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/test_module_2.dim @@ -0,0 +1,6 @@ +module: test_module_2 + +test_id_2: + text: Another test req + developer: xy_company + asil: ASIL_A diff --git a/dim/spec/test_input/invalid_input/modules/toplevel_invalid.dim b/dim/spec/test_input/invalid_input/modules/toplevel_invalid.dim new file mode 100644 index 0000000..671a618 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/toplevel_invalid.dim @@ -0,0 +1 @@ +This file has no key which can be used for the top level diff --git a/dim/spec/test_input/invalid_input/modules/unallowed_attribute.dim b/dim/spec/test_input/invalid_input/modules/unallowed_attribute.dim new file mode 100644 index 0000000..7c324f8 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/unallowed_attribute.dim @@ -0,0 +1,5 @@ +module: test_module + +test_id_1: + text: First test requirement + test: Invalid key \ No newline at end of file diff --git a/dim/spec/test_input/invalid_input/modules/valid_test_1.dim b/dim/spec/test_input/invalid_input/modules/valid_test_1.dim new file mode 100644 index 0000000..b4c774b --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/valid_test_1.dim @@ -0,0 +1,4 @@ +module: valid_test_1 + +ESR-0010-4139: + text: req1 diff --git a/dim/spec/test_input/invalid_input/modules/valid_test_2.dim b/dim/spec/test_input/invalid_input/modules/valid_test_2.dim new file mode 100644 index 0000000..e04db19 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/valid_test_2.dim @@ -0,0 +1,4 @@ +module: valid_test_1 + +ESR-0010-4138: + text: req2 diff --git a/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid.dim b/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid.dim new file mode 100644 index 0000000..47ae390 --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid.dim @@ -0,0 +1,4 @@ +module: test + +test_id: + invalid: syntax: for: this: value: diff --git a/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid_char.dim b/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid_char.dim new file mode 100644 index 0000000..3e2ce0a --- /dev/null +++ b/dim/spec/test_input/invalid_input/modules/yaml_syntax_invalid_char.dim @@ -0,0 +1,4 @@ +module: yaml_syntax_invalid_char + +ESR-0010-4139: + text: req1 diff --git a/dim/spec/test_input/invalid_input/no_match_pattern.dim b/dim/spec/test_input/invalid_input/no_match_pattern.dim new file mode 100644 index 0000000..5c7f601 --- /dev/null +++ b/dim/spec/test_input/invalid_input/no_match_pattern.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: ./test*.dim + category: module diff --git a/dim/spec/test_input/invalid_input/no_yaml.dim b/dim/spec/test_input/invalid_input/no_yaml.dim new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/invalid_input/parent_dir_in_path.dim b/dim/spec/test_input/invalid_input/parent_dir_in_path.dim new file mode 100644 index 0000000..19e649f --- /dev/null +++ b/dim/spec/test_input/invalid_input/parent_dir_in_path.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: modules/../test_module_1.dim + category: module diff --git a/dim/spec/test_input/invalid_input/properties_array.dim b/dim/spec/test_input/invalid_input/properties_array.dim new file mode 100644 index 0000000..9ed435c --- /dev/null +++ b/dim/spec/test_input/invalid_input/properties_array.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: abc +Properties: + - a + - b diff --git a/dim/spec/test_input/invalid_input/same_module_different_category.dim b/dim/spec/test_input/invalid_input/same_module_different_category.dim new file mode 100644 index 0000000..10db8c6 --- /dev/null +++ b/dim/spec/test_input/invalid_input/same_module_different_category.dim @@ -0,0 +1,8 @@ +Config: + - originator: ABC + files: modules/valid_test_1.dim + category: system + - originator: ABC + files: modules/valid_test_2.dim + disable_naming_convention_check: yes + category: software diff --git a/dim/spec/test_input/invalid_input/same_module_different_owner.dim b/dim/spec/test_input/invalid_input/same_module_different_owner.dim new file mode 100644 index 0000000..b4f4eb4 --- /dev/null +++ b/dim/spec/test_input/invalid_input/same_module_different_owner.dim @@ -0,0 +1,7 @@ +Config: + - originator: ABC + files: modules/valid_test_1.dim + category: system + - originator: DEF + files: modules/valid_test_2.dim + category: system diff --git a/dim/spec/test_input/invalid_input/yaml_syntax_invalid.dim b/dim/spec/test_input/invalid_input/yaml_syntax_invalid.dim new file mode 100644 index 0000000..665178e --- /dev/null +++ b/dim/spec/test_input/invalid_input/yaml_syntax_invalid.dim @@ -0,0 +1,3 @@ +Config: + CompanyName: + files: CompanyName: test: tests diff --git a/dim/spec/test_input/invalid_property/empty_property/Config.dim b/dim/spec/test_input/invalid_property/empty_property/Config.dim new file mode 100644 index 0000000..9d9b6ac --- /dev/null +++ b/dim/spec/test_input/invalid_property/empty_property/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: ABC + files: test_module_1.dim + category: module + +Properties: properties.yaml diff --git a/dim/spec/test_input/invalid_property/empty_property/properties.yaml b/dim/spec/test_input/invalid_property/empty_property/properties.yaml new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/invalid_property/empty_property/test_module_1.dim b/dim/spec/test_input/invalid_property/empty_property/test_module_1.dim new file mode 100644 index 0000000..f81374e --- /dev/null +++ b/dim/spec/test_input/invalid_property/empty_property/test_module_1.dim @@ -0,0 +1,4 @@ +module: ABC + +ID_1: + text: empty properties file loading test diff --git a/dim/spec/test_input/invalid_property/invalid_asil_level/Config.dim b/dim/spec/test_input/invalid_property/invalid_asil_level/Config.dim new file mode 100644 index 0000000..c177341 --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_asil_level/Config.dim @@ -0,0 +1,12 @@ +Config: + CompanyName: + files: + - test_module_1.dim + - test_module_3.dim + category: "module" + + XY Company: + files: test_module_2.dim + category: module + +Properties: "properties.yaml" \ No newline at end of file diff --git a/dim/spec/test_input/invalid_property/invalid_asil_level/properties.yaml b/dim/spec/test_input/invalid_property/invalid_asil_level/properties.yaml new file mode 100644 index 0000000..d91fbba --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_asil_level/properties.yaml @@ -0,0 +1,7 @@ +test_module_2: + asil: QM + reuse: yes + +test_module_3: + asil: ASIL_Y + reuse: yes \ No newline at end of file diff --git a/dim/spec/test_input/invalid_property/invalid_asil_value/Config.dim b/dim/spec/test_input/invalid_property/invalid_asil_value/Config.dim new file mode 100644 index 0000000..c177341 --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_asil_value/Config.dim @@ -0,0 +1,12 @@ +Config: + CompanyName: + files: + - test_module_1.dim + - test_module_3.dim + category: "module" + + XY Company: + files: test_module_2.dim + category: module + +Properties: "properties.yaml" \ No newline at end of file diff --git a/dim/spec/test_input/invalid_property/invalid_asil_value/properties.yaml b/dim/spec/test_input/invalid_property/invalid_asil_value/properties.yaml new file mode 100644 index 0000000..e3d21e5 --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_asil_value/properties.yaml @@ -0,0 +1,6 @@ +test_module_2: + asil: + - asil + +test_module_3: + asil: ASIL_Y \ No newline at end of file diff --git a/dim/spec/test_input/invalid_property/invalid_file/Config.dim b/dim/spec/test_input/invalid_property/invalid_file/Config.dim new file mode 100644 index 0000000..c177341 --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_file/Config.dim @@ -0,0 +1,12 @@ +Config: + CompanyName: + files: + - test_module_1.dim + - test_module_3.dim + category: "module" + + XY Company: + files: test_module_2.dim + category: module + +Properties: "properties.yaml" \ No newline at end of file diff --git a/dim/spec/test_input/invalid_property/invalid_file/properties.yaml b/dim/spec/test_input/invalid_property/invalid_file/properties.yaml new file mode 100644 index 0000000..dd313f3 --- /dev/null +++ b/dim/spec/test_input/invalid_property/invalid_file/properties.yaml @@ -0,0 +1,2 @@ +test_module_2: + asil: nope: diff --git a/dim/spec/test_input/language/module_ok.dim b/dim/spec/test_input/language/module_ok.dim new file mode 100644 index 0000000..6751c4b --- /dev/null +++ b/dim/spec/test_input/language/module_ok.dim @@ -0,0 +1,20 @@ +module: language + +ESR_Test_1: + text: | + juhu + juhu + text_spanish: ole + verification_criteria: test + verification_criteria_spanish: verificar + verification_criteria_english: verify + +ESR_Test_2: + text: mist + text_english: damn + comment: Kommentar + comment_english: comment + +ESR_Test_3: + text: achso + text_french: diff --git a/dim/spec/test_input/language/output/Requirements.json b/dim/spec/test_input/language/output/Requirements.json new file mode 100644 index 0000000..5aee040 --- /dev/null +++ b/dim/spec/test_input/language/output/Requirements.json @@ -0,0 +1,86 @@ +[ + { + "id": "ESR_Test_1", + "document_name": "language", + "originator": "", + "type": "requirement", + "text": "juhu\njuhu", + "text_french": "", + "text_english": "", + "text_spanish": "ole", + "verification_criteria": "test", + "verification_criteria_english": "verify", + "verification_criteria_spanish": "verificar", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "none", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "comment_english": "", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ESR_Test_2", + "document_name": "language", + "originator": "", + "type": "requirement", + "text": "mist", + "text_french": "", + "text_english": "damn", + "text_spanish": "", + "verification_criteria": "", + "verification_criteria_english": "", + "verification_criteria_spanish": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "none", + "status": "draft", + "review_status": "not_reviewed", + "comment": "Kommentar", + "comment_english": "comment", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ESR_Test_3", + "document_name": "language", + "originator": "", + "type": "requirement", + "text": "achso", + "text_french": "", + "text_english": "", + "text_spanish": "", + "verification_criteria": "", + "verification_criteria_english": "", + "verification_criteria_spanish": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "none", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "comment_english": "", + "miscellaneous": "", + "sources": "", + "refs": "" + } +] diff --git a/dim/spec/test_input/load_multiple_files/Config.dim b/dim/spec/test_input/load_multiple_files/Config.dim new file mode 100644 index 0000000..230df54 --- /dev/null +++ b/dim/spec/test_input/load_multiple_files/Config.dim @@ -0,0 +1,4 @@ +Config: + CompanyName: + files: test_*.dim + category: module diff --git a/dim/spec/test_input/load_multiple_files/attributes.dim b/dim/spec/test_input/load_multiple_files/attributes.dim new file mode 100644 index 0000000..1f033ae --- /dev/null +++ b/dim/spec/test_input/load_multiple_files/attributes.dim @@ -0,0 +1,10 @@ +cluster: + format_style: text + default: '' +necessary: + format_style: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/load_multiple_files/test_module_1.dim b/dim/spec/test_input/load_multiple_files/test_module_1.dim new file mode 100644 index 0000000..2edbb66 --- /dev/null +++ b/dim/spec/test_input/load_multiple_files/test_module_1.dim @@ -0,0 +1,41 @@ +module: test_module_1 + +test_id_1: + text: First Test Requirement + status: invalid + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear + +test_id_4: + text: Fourth Test Requirement + review_status: rejected + +test_id_5: + text: Fifth Test Requirement + review_status: not_reviewed + +test_id_6: + text: Sixth Test Requirement + review_status: accepted + tags: covered + +test_id_7: + text: Seventh Test Requirement + review_status: accepted + tags: covered + +test_id_8: + text: Eighth Test Requirement + review_status: accepted + tags: covered + +test_id_9: + text: Ninth Test Requirement + review_status: accepted diff --git a/dim/spec/test_input/load_multiple_files/test_module_2.dim b/dim/spec/test_input/load_multiple_files/test_module_2.dim new file mode 100644 index 0000000..5d9ed1d --- /dev/null +++ b/dim/spec/test_input/load_multiple_files/test_module_2.dim @@ -0,0 +1,11 @@ +module: test_module_2 + +test_id_10: + text: First Test Requirement + review_status: accepted + tags: covered + +test_id_11: + text: Second Test Requirement + review_status: accepted + tags: covered diff --git a/dim/spec/test_input/metadata/meta.dim b/dim/spec/test_input/metadata/meta.dim new file mode 100644 index 0000000..683e9c5 --- /dev/null +++ b/dim/spec/test_input/metadata/meta.dim @@ -0,0 +1,6 @@ +module: ABC + +metadata: Test Meta + +SRS_X_Y: + text: bla diff --git a/dim/spec/test_input/missing_refs/test_module_1.dim b/dim/spec/test_input/missing_refs/test_module_1.dim new file mode 100644 index 0000000..a99193e --- /dev/null +++ b/dim/spec/test_input/missing_refs/test_module_1.dim @@ -0,0 +1,5 @@ +module: test_module_1 + +test_id_3: + text: Another test req + refs: non_exist diff --git a/dim/spec/test_input/missing_refs/test_module_1.dim.expected b/dim/spec/test_input/missing_refs/test_module_1.dim.expected new file mode 100644 index 0000000..9f971d9 --- /dev/null +++ b/dim/spec/test_input/missing_refs/test_module_1.dim.expected @@ -0,0 +1,5 @@ +document: test_module_1 + +test_id_3: + text: Another test req + refs: non_exist diff --git a/dim/spec/test_input/nb_space/module.dim b/dim/spec/test_input/nb_space/module.dim new file mode 100644 index 0000000..512ba5d --- /dev/null +++ b/dim/spec/test_input/nb_space/module.dim @@ -0,0 +1,5 @@ +module: nb_space + +Has_Non_Breaking_Space: + text: ABC  ABC   + miscellaneous: ABC  ABC   diff --git a/dim/spec/test_input/nested_html/module.dim b/dim/spec/test_input/nested_html/module.dim new file mode 100644 index 0000000..b3b3103 --- /dev/null +++ b/dim/spec/test_input/nested_html/module.dim @@ -0,0 +1,25 @@ +module: nested_html + +No_Html: + text: "'x'A'x'B'x'" + +Not_Nested: + text: "'x'A'x'B'x'" + +Nested: + text: "'x'A'x'B'x'" + +Nested_Twice: + text: "'x'A'x'B'x'" + +Twice_Once: + text: "'x'A'x'B'x'" + +Once_Twice: + text: "'x'A< / html>'x'B'x'" + +Nested_Twice_no_end: + text: "'x'A'x'B'x'" + +Nested_Twice_no_start: + text: "'x'A'x'B'x'" diff --git a/dim/spec/test_input/nested_html/output/Requirements.rst b/dim/spec/test_input/nested_html/output/Requirements.rst new file mode 100644 index 0000000..3938147 --- /dev/null +++ b/dim/spec/test_input/nested_html/output/Requirements.rst @@ -0,0 +1,162 @@ +:raw-html:`nested_html` +======================= + +.. requirement:: No_Html + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'<b>A</b>'x'<b>B</b>'x'` + +.. requirement:: Not_Nested + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Nested + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Nested_Twice + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Twice_Once + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Once_Twice + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Nested_Twice_no_end + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` + +.. requirement:: Nested_Twice_no_start + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`'x'A'x'B'x'` diff --git a/dim/spec/test_input/no_tester/test_module_1.dim b/dim/spec/test_input/no_tester/test_module_1.dim new file mode 100644 index 0000000..4e0a992 --- /dev/null +++ b/dim/spec/test_input/no_tester/test_module_1.dim @@ -0,0 +1,6 @@ +module: test_module_1 + +test_id_1: + text: First test requirement + test_setups: on_target + tester: '' \ No newline at end of file diff --git a/dim/spec/test_input/one_module_in_several_files/Config.yml b/dim/spec/test_input/one_module_in_several_files/Config.yml new file mode 100644 index 0000000..e801795 --- /dev/null +++ b/dim/spec/test_input/one_module_in_several_files/Config.yml @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: "**/Input*.yml" + category: module diff --git a/dim/spec/test_input/one_module_in_several_files/module1/Input1.yml b/dim/spec/test_input/one_module_in_several_files/module1/Input1.yml new file mode 100644 index 0000000..a9f5144 --- /dev/null +++ b/dim/spec/test_input/one_module_in_several_files/module1/Input1.yml @@ -0,0 +1,4 @@ +module: TestModule + +ID1: + text: great. diff --git a/dim/spec/test_input/one_module_in_several_files/module2/Input2.yml b/dim/spec/test_input/one_module_in_several_files/module2/Input2.yml new file mode 100644 index 0000000..3d13cff --- /dev/null +++ b/dim/spec/test_input/one_module_in_several_files/module2/Input2.yml @@ -0,0 +1,4 @@ +module: TestModule + +ID2: + text: great again. diff --git a/dim/spec/test_input/prefix_check/req/test_module_3.dim b/dim/spec/test_input/prefix_check/req/test_module_3.dim new file mode 100644 index 0000000..157e59a --- /dev/null +++ b/dim/spec/test_input/prefix_check/req/test_module_3.dim @@ -0,0 +1,4 @@ +ESR-0007-0565: + text: test requirement + verification_criteria: xy shall be ab + test_setups: on_target diff --git a/dim/spec/test_input/prefix_check/test_module_1.dim b/dim/spec/test_input/prefix_check/test_module_1.dim new file mode 100644 index 0000000..997035d --- /dev/null +++ b/dim/spec/test_input/prefix_check/test_module_1.dim @@ -0,0 +1,6 @@ +module: test1-test + +ESR-0007-0565: + text: test requirement + verification_criteria: xy shall be ab + test_setups: on_target diff --git a/dim/spec/test_input/prefix_check/test_module_2.dim b/dim/spec/test_input/prefix_check/test_module_2.dim new file mode 100644 index 0000000..157e59a --- /dev/null +++ b/dim/spec/test_input/prefix_check/test_module_2.dim @@ -0,0 +1,4 @@ +ESR-0007-0565: + text: test requirement + verification_criteria: xy shall be ab + test_setups: on_target diff --git a/dim/spec/test_input/property_file_insertion/Config.dim b/dim/spec/test_input/property_file_insertion/Config.dim new file mode 100644 index 0000000..da56f63 --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/Config.dim @@ -0,0 +1,7 @@ +Config: + - originator: + files: + - test_module_*.dim + category: "input" + +Properties: "properties.yaml" diff --git a/dim/spec/test_input/property_file_insertion/properties.yaml b/dim/spec/test_input/property_file_insertion/properties.yaml new file mode 100644 index 0000000..d93f59c --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/properties.yaml @@ -0,0 +1,36 @@ +test_module_for_insertion: + asil: ASIL_B + text: inserted text from properties file + verification_criteria: inserted verification criteria + cal: QM + feature: inserted_feature + change_request: inserted_CR + tags: legal, sys + developer: inserted developer + tester: inserted tester + test_setups: manual + status: valid + review_status: rejected + comment: inserted comment + miscellaneous: inserted miscellaneous + sources: inserted sources + refs: test_module_no_insertion_empty + +test_module_text_insertion: + text: | + multi, + line test + text from property + file! + verification_criteria: inserted verification criteria + +test_module_no_insertion: + type: information + reuse: yes + +test_module_for_requirement: + type: information + reuse: yes + +test_module_for_information: + type: requirement diff --git a/dim/spec/test_input/property_file_insertion/test_module_for_information.dim b/dim/spec/test_input/property_file_insertion/test_module_for_information.dim new file mode 100644 index 0000000..406f7db --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_module_for_information.dim @@ -0,0 +1,12 @@ +document: test_module_for_information + +test_module_for_information_empty: + text: type should be from property table + +test_module_for_information_req: + type: requirement + text: type should not be replaced from property value + +test_module_for_information_info: + type: information + text: type should not be replaced from property value diff --git a/dim/spec/test_input/property_file_insertion/test_module_for_insertion.dim b/dim/spec/test_input/property_file_insertion/test_module_for_insertion.dim new file mode 100644 index 0000000..ba8123c --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_module_for_insertion.dim @@ -0,0 +1,21 @@ +module: test_module_for_insertion + +test_module_for_insertion_empty: + +test_module_for_insertion_not_empty: + asil: QM + text: test text + verification_criteria: test criteria + cal: CAL_4 + feature: test_feature + change_request: test_CR + tags: swa + developer: test_developer + tester: test_tester + test_setups: none + status: invalid + review_status: unclear + comment: test_comment + miscellaneous: test_misc + sources: test_source + refs: test_module_for_insertion_empty \ No newline at end of file diff --git a/dim/spec/test_input/property_file_insertion/test_module_for_requirement.dim b/dim/spec/test_input/property_file_insertion/test_module_for_requirement.dim new file mode 100644 index 0000000..513222d --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_module_for_requirement.dim @@ -0,0 +1,12 @@ +document: test_module_for_requirement + +test_module_for_requirement_empty: + text: type should be from property table + +test_module_for_requirement_info: + type: information + text: type should not be replaced from property value + +test_module_for_requirement_req: + type: requirement + text: type should not be replaced from property value diff --git a/dim/spec/test_input/property_file_insertion/test_module_no_insertions.dim b/dim/spec/test_input/property_file_insertion/test_module_no_insertions.dim new file mode 100644 index 0000000..e26e13f --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_module_no_insertions.dim @@ -0,0 +1,9 @@ +module: test_module_no_insertion + +test_module_no_insertion_empty: + type: requirement + +test_module_no_insertion_empty_text: + type: requirement + text: + verification_criteria: \ No newline at end of file diff --git a/dim/spec/test_input/property_file_insertion/test_module_text_insertion.dim b/dim/spec/test_input/property_file_insertion/test_module_text_insertion.dim new file mode 100644 index 0000000..9e608b2 --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_module_text_insertion.dim @@ -0,0 +1,8 @@ +module: test_module_text_insertion + +test_module_text_insertion_text: + text: test text + verification_criteria: test criteria + +test_module_text_insertion_no_text: + asil: ASIL_C \ No newline at end of file diff --git a/dim/spec/test_input/property_file_insertion/test_setups/Config.dim b/dim/spec/test_input/property_file_insertion/test_setups/Config.dim new file mode 100644 index 0000000..7689652 --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_setups/Config.dim @@ -0,0 +1,7 @@ +Config: + - originator: + files: + - module.dim + category: "input" + +Properties: "properties.yaml" diff --git a/dim/spec/test_input/property_file_insertion/test_setups/module.dim b/dim/spec/test_input/property_file_insertion/test_setups/module.dim new file mode 100644 index 0000000..7416660 --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_setups/module.dim @@ -0,0 +1,3 @@ +module: test_setups_insertion + +ID_empty_test_setups: diff --git a/dim/spec/test_input/property_file_insertion/test_setups/properties.yaml b/dim/spec/test_input/property_file_insertion/test_setups/properties.yaml new file mode 100644 index 0000000..a00d07a --- /dev/null +++ b/dim/spec/test_input/property_file_insertion/test_setups/properties.yaml @@ -0,0 +1,2 @@ +test_setups_insertion: + test_setups: off_target diff --git a/dim/spec/test_input/property_file_refs/Config_circular_reference.dim b/dim/spec/test_input/property_file_refs/Config_circular_reference.dim new file mode 100644 index 0000000..5da4299 --- /dev/null +++ b/dim/spec/test_input/property_file_refs/Config_circular_reference.dim @@ -0,0 +1,7 @@ +Config: + - originator: + files: + - ref_test_module*.dim + category: "input" + +Properties: "properties_circular_ref.yaml" diff --git a/dim/spec/test_input/property_file_refs/Config_invalid_reference.dim b/dim/spec/test_input/property_file_refs/Config_invalid_reference.dim new file mode 100644 index 0000000..d34a1cd --- /dev/null +++ b/dim/spec/test_input/property_file_refs/Config_invalid_reference.dim @@ -0,0 +1,7 @@ +Config: + - originator: + files: + - ref_test_module*.dim + category: "input" + +Properties: "properties_invalid_ref.yaml" diff --git a/dim/spec/test_input/property_file_refs/properties_circular_ref.yaml b/dim/spec/test_input/property_file_refs/properties_circular_ref.yaml new file mode 100644 index 0000000..75c8cfc --- /dev/null +++ b/dim/spec/test_input/property_file_refs/properties_circular_ref.yaml @@ -0,0 +1,2 @@ +ref_test_module1: + refs: ref_test_module2_req1 \ No newline at end of file diff --git a/dim/spec/test_input/property_file_refs/properties_invalid_ref.yaml b/dim/spec/test_input/property_file_refs/properties_invalid_ref.yaml new file mode 100644 index 0000000..13860dd --- /dev/null +++ b/dim/spec/test_input/property_file_refs/properties_invalid_ref.yaml @@ -0,0 +1,2 @@ +ref_test_module1: + refs: ref_test_module1_req3 \ No newline at end of file diff --git a/dim/spec/test_input/property_file_refs/ref_test_module1.dim b/dim/spec/test_input/property_file_refs/ref_test_module1.dim new file mode 100644 index 0000000..b0d7d43 --- /dev/null +++ b/dim/spec/test_input/property_file_refs/ref_test_module1.dim @@ -0,0 +1,7 @@ +module: ref_test_module1 + +ref_test_module1_req1: + type: requirement + +ref_test_module1_req2: + type: requirement diff --git a/dim/spec/test_input/property_file_refs/ref_test_module2.dim b/dim/spec/test_input/property_file_refs/ref_test_module2.dim new file mode 100644 index 0000000..470b5b6 --- /dev/null +++ b/dim/spec/test_input/property_file_refs/ref_test_module2.dim @@ -0,0 +1,8 @@ +module: ref_test_module2 + +ref_test_module2_req1: + type: requirement + refs: ref_test_module1_req1 + +ref_test_module2_req2: + type: requirement diff --git a/dim/spec/test_input/relevant/module_ok.dim b/dim/spec/test_input/relevant/module_ok.dim new file mode 100644 index 0000000..fb7a5d5 --- /dev/null +++ b/dim/spec/test_input/relevant/module_ok.dim @@ -0,0 +1,68 @@ +module: ok + +ID_1: + text: nothing + +ID_2b: + tags: memory + +ID_2c: + tags: memory, functional_safety_mechanism + +ID_2d: + asil: QM + +ID_2e_safe: + asil: ASIL_A + +ID_2f_safe: + asil: ASIL_A + tags: memory + +ID_2g_safe: + asil: ASIL_A + tags: functional_safety_mechanism + +ID_2h: + asil: QM + tags: functional_safety_mechanism + +ID_2i: + asil: QM + tags: memory + +ID_2j: + asil: not_set + +ID_3a_cal: + cal: CAL_4 + +ID_3b: + tags: memory + +ID_3c: + tags: memory, cybersecurity_control + +ID_3d: + tags: confidentiality + +ID_3e: + tags: integrity + +ID_3f: + tags: availability + +ID_3g: + tags: authenticity + +ID_3h: + tags: authority + +ID_3i: + cal: QM + +ID_3j: + cal: not_set + +ID_4: + tags: authority, functional_safety_mechanism diff --git a/dim/spec/test_input/reqs/asil/default.dim b/dim/spec/test_input/reqs/asil/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/asil/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/asil/empty.dim b/dim/spec/test_input/reqs/asil/empty.dim new file mode 100644 index 0000000..fef024d --- /dev/null +++ b/dim/spec/test_input/reqs/asil/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_e: + asil: diff --git a/dim/spec/test_input/reqs/asil/invalid_type.dim b/dim/spec/test_input/reqs/asil/invalid_type.dim new file mode 100644 index 0000000..63f1436 --- /dev/null +++ b/dim/spec/test_input/reqs/asil/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + asil: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/asil/valid.dim b/dim/spec/test_input/reqs/asil/valid.dim new file mode 100644 index 0000000..2d48245 --- /dev/null +++ b/dim/spec/test_input/reqs/asil/valid.dim @@ -0,0 +1,16 @@ +module: Name1 + +id_v1: + asil: QM + +id_v2: + asil: QM(A) + +id_v3: + asil: ASIL_D + +id_v4: + asil: not_set + +id_v5: + asil: not_set diff --git a/dim/spec/test_input/reqs/cal/default.dim b/dim/spec/test_input/reqs/cal/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/cal/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/cal/empty.dim b/dim/spec/test_input/reqs/cal/empty.dim new file mode 100644 index 0000000..8c160a3 --- /dev/null +++ b/dim/spec/test_input/reqs/cal/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_e: + cal: diff --git a/dim/spec/test_input/reqs/cal/invalid_type.dim b/dim/spec/test_input/reqs/cal/invalid_type.dim new file mode 100644 index 0000000..83ec0ae --- /dev/null +++ b/dim/spec/test_input/reqs/cal/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + cal: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/cal/valid.dim b/dim/spec/test_input/reqs/cal/valid.dim new file mode 100644 index 0000000..9f8f424 --- /dev/null +++ b/dim/spec/test_input/reqs/cal/valid.dim @@ -0,0 +1,13 @@ +module: Name1 + +id_v1: + cal: CAL_4 + +id_v2: + cal: QM + +id_v3: + cal: not_set + +id_v4: + cal: not_set diff --git a/dim/spec/test_input/reqs/comment/default.dim b/dim/spec/test_input/reqs/comment/default.dim new file mode 100644 index 0000000..9f7615b --- /dev/null +++ b/dim/spec/test_input/reqs/comment/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + comment: diff --git a/dim/spec/test_input/reqs/comment/invalid_type.dim b/dim/spec/test_input/reqs/comment/invalid_type.dim new file mode 100644 index 0000000..ef00238 --- /dev/null +++ b/dim/spec/test_input/reqs/comment/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + comment: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/comment/valid.dim b/dim/spec/test_input/reqs/comment/valid.dim new file mode 100644 index 0000000..f3cf60e --- /dev/null +++ b/dim/spec/test_input/reqs/comment/valid.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + comment: This is a comment. diff --git a/dim/spec/test_input/reqs/comment_lang/default.dim b/dim/spec/test_input/reqs/comment_lang/default.dim new file mode 100644 index 0000000..52f4aa6 --- /dev/null +++ b/dim/spec/test_input/reqs/comment_lang/default.dim @@ -0,0 +1,7 @@ +module: Name1 + +ID_default1: + comment_german: + comment_french: bla + +ID_default2: diff --git a/dim/spec/test_input/reqs/comment_lang/no_string.dim b/dim/spec/test_input/reqs/comment_lang/no_string.dim new file mode 100644 index 0000000..f63f9ab --- /dev/null +++ b/dim/spec/test_input/reqs/comment_lang/no_string.dim @@ -0,0 +1,9 @@ +module: test + +test_id_1: + comment_german: + - ./cli.dim + - ./exporter.dim + - ./explorer.dim + - ./validator.dim + - ./verifier.dim diff --git a/dim/spec/test_input/reqs/comment_lang/not_specified.dim b/dim/spec/test_input/reqs/comment_lang/not_specified.dim new file mode 100644 index 0000000..331a337 --- /dev/null +++ b/dim/spec/test_input/reqs/comment_lang/not_specified.dim @@ -0,0 +1,4 @@ +module: Name1 + +ID_not: + comment_german: hey diff --git a/dim/spec/test_input/reqs/comment_lang/valid.dim b/dim/spec/test_input/reqs/comment_lang/valid.dim new file mode 100644 index 0000000..b8a1eab --- /dev/null +++ b/dim/spec/test_input/reqs/comment_lang/valid.dim @@ -0,0 +1,14 @@ +module: comment_lang +ESR_Test_1: + comment: | + juhu + juhu + comment_spanish: ole + +ESR_Test_2: + comment: mist + comment_english: damn + +ESR_Test_3: + comment: achso + comment_french: diff --git a/dim/spec/test_input/reqs/cr/default.dim b/dim/spec/test_input/reqs/cr/default.dim new file mode 100644 index 0000000..3350fb8 --- /dev/null +++ b/dim/spec/test_input/reqs/cr/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + change_request: diff --git a/dim/spec/test_input/reqs/cr/invalid_type.dim b/dim/spec/test_input/reqs/cr/invalid_type.dim new file mode 100644 index 0000000..41c6017 --- /dev/null +++ b/dim/spec/test_input/reqs/cr/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + change_request: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/cr/valid.dim b/dim/spec/test_input/reqs/cr/valid.dim new file mode 100644 index 0000000..d2115b8 --- /dev/null +++ b/dim/spec/test_input/reqs/cr/valid.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + change_request: This is a CR. diff --git a/dim/spec/test_input/reqs/developer/default.dim b/dim/spec/test_input/reqs/developer/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/developer/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/developer/default_config.dim b/dim/spec/test_input/reqs/developer/default_config.dim new file mode 100644 index 0000000..ca171f4 --- /dev/null +++ b/dim/spec/test_input/reqs/developer/default_config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: default.dim + category: module diff --git a/dim/spec/test_input/reqs/developer/invalid_type.dim b/dim/spec/test_input/reqs/developer/invalid_type.dim new file mode 100644 index 0000000..ccc05b5 --- /dev/null +++ b/dim/spec/test_input/reqs/developer/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + developer: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/developer/resolve_config.dim b/dim/spec/test_input/reqs/developer/resolve_config.dim new file mode 100644 index 0000000..b6b8de2 --- /dev/null +++ b/dim/spec/test_input/reqs/developer/resolve_config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: resolve_input.dim + category: input + - originator: CompanyName + files: resolve_module.dim + category: module diff --git a/dim/spec/test_input/reqs/developer/resolve_input.dim b/dim/spec/test_input/reqs/developer/resolve_input.dim new file mode 100644 index 0000000..8e70e87 --- /dev/null +++ b/dim/spec/test_input/reqs/developer/resolve_input.dim @@ -0,0 +1,7 @@ +module: test1 + +input_r: + type: requirement + +input_i: + type: information diff --git a/dim/spec/test_input/reqs/developer/resolve_module.dim b/dim/spec/test_input/reqs/developer/resolve_module.dim new file mode 100644 index 0000000..cb1fed0 --- /dev/null +++ b/dim/spec/test_input/reqs/developer/resolve_module.dim @@ -0,0 +1,7 @@ +module: test2 + +module_r: + type: requirement + +module_i: + type: information diff --git a/dim/spec/test_input/reqs/developer/valid.dim b/dim/spec/test_input/reqs/developer/valid.dim new file mode 100644 index 0000000..b61007e --- /dev/null +++ b/dim/spec/test_input/reqs/developer/valid.dim @@ -0,0 +1,12 @@ +module: Name1 + +id_v1: + developer: Hallo + +id_v2: + developer: + +id_v3: + developer: | + A + B diff --git a/dim/spec/test_input/reqs/enclosed/array.dim b/dim/spec/test_input/reqs/enclosed/array.dim new file mode 100644 index 0000000..2614403 --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/array.dim @@ -0,0 +1,7 @@ +module: enclosed + +enclosed: + - data/b.txt + - data/c.txt + +ID_Array: diff --git a/dim/spec/test_input/reqs/enclosed/backward.dim b/dim/spec/test_input/reqs/enclosed/backward.dim new file mode 100644 index 0000000..fe70990 --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/backward.dim @@ -0,0 +1,3 @@ +module: enclosed + +enclosed: .\data\a.txt diff --git a/dim/spec/test_input/reqs/enclosed/data/a.txt b/dim/spec/test_input/reqs/enclosed/data/a.txt new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/reqs/enclosed/data/b.txt b/dim/spec/test_input/reqs/enclosed/data/b.txt new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/reqs/enclosed/data/c.txt b/dim/spec/test_input/reqs/enclosed/data/c.txt new file mode 100644 index 0000000..e69de29 diff --git a/dim/spec/test_input/reqs/enclosed/default.dim b/dim/spec/test_input/reqs/enclosed/default.dim new file mode 100644 index 0000000..dad117e --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/default.dim @@ -0,0 +1,3 @@ +module: enclosed + +ID_0: diff --git a/dim/spec/test_input/reqs/enclosed/dot.dim b/dim/spec/test_input/reqs/enclosed/dot.dim new file mode 100644 index 0000000..d53dcab --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/dot.dim @@ -0,0 +1,3 @@ +module: enclosed + +enclosed: "./dot.dim" diff --git a/dim/spec/test_input/reqs/enclosed/dotdot.dim b/dim/spec/test_input/reqs/enclosed/dotdot.dim new file mode 100644 index 0000000..5cd3e45 --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/dotdot.dim @@ -0,0 +1,3 @@ +module: enclosed + +enclosed: "../enclosed/dotdot.dim" diff --git a/dim/spec/test_input/reqs/enclosed/empty_string.dim b/dim/spec/test_input/reqs/enclosed/empty_string.dim new file mode 100644 index 0000000..205ac91 --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/empty_string.dim @@ -0,0 +1,4 @@ +module: test + +enclosed: + - diff --git a/dim/spec/test_input/reqs/enclosed/notexist.dim b/dim/spec/test_input/reqs/enclosed/notexist.dim new file mode 100644 index 0000000..548928d --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/notexist.dim @@ -0,0 +1,4 @@ +module: test + +enclosed: + - module_non_existing.dim diff --git a/dim/spec/test_input/reqs/enclosed/string.dim b/dim/spec/test_input/reqs/enclosed/string.dim new file mode 100644 index 0000000..bd07af7 --- /dev/null +++ b/dim/spec/test_input/reqs/enclosed/string.dim @@ -0,0 +1,5 @@ +module: enclosed + +enclosed: data/a.txt + +ID_String: diff --git a/dim/spec/test_input/reqs/feature/default.dim b/dim/spec/test_input/reqs/feature/default.dim new file mode 100644 index 0000000..7bf04f0 --- /dev/null +++ b/dim/spec/test_input/reqs/feature/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + feature: diff --git a/dim/spec/test_input/reqs/feature/invalid_type.dim b/dim/spec/test_input/reqs/feature/invalid_type.dim new file mode 100644 index 0000000..e057877 --- /dev/null +++ b/dim/spec/test_input/reqs/feature/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + feature: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/feature/valid.dim b/dim/spec/test_input/reqs/feature/valid.dim new file mode 100644 index 0000000..15f9123 --- /dev/null +++ b/dim/spec/test_input/reqs/feature/valid.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + feature: This is a feature. diff --git a/dim/spec/test_input/reqs/id/comma.dim b/dim/spec/test_input/reqs/id/comma.dim new file mode 100644 index 0000000..a1bdc39 --- /dev/null +++ b/dim/spec/test_input/reqs/id/comma.dim @@ -0,0 +1,4 @@ +module: test + +ESR_Test,1: + text: This req has a comma. diff --git a/dim/spec/test_input/reqs/id/empty.dim b/dim/spec/test_input/reqs/id/empty.dim new file mode 100644 index 0000000..3025120 --- /dev/null +++ b/dim/spec/test_input/reqs/id/empty.dim @@ -0,0 +1 @@ +module: Name1 diff --git a/dim/spec/test_input/reqs/id/invalid_key.dim b/dim/spec/test_input/reqs/id/invalid_key.dim new file mode 100644 index 0000000..873a511 --- /dev/null +++ b/dim/spec/test_input/reqs/id/invalid_key.dim @@ -0,0 +1,4 @@ +module: test + +test_id: + - testkey diff --git a/dim/spec/test_input/reqs/id/invalid_short.dim b/dim/spec/test_input/reqs/id/invalid_short.dim new file mode 100644 index 0000000..219e510 --- /dev/null +++ b/dim/spec/test_input/reqs/id/invalid_short.dim @@ -0,0 +1,3 @@ +module: test + +test_key: test_value diff --git a/dim/spec/test_input/reqs/id/invalid_value.dim b/dim/spec/test_input/reqs/id/invalid_value.dim new file mode 100644 index 0000000..5ff4b87 --- /dev/null +++ b/dim/spec/test_input/reqs/id/invalid_value.dim @@ -0,0 +1,9 @@ +module: invalid_value +Files: + CompanyName: + files: + - ./cli.dim + - ./exporter.dim + - ./explorer.dim + - ./validator.dim + - ./verifier.dim diff --git a/dim/spec/test_input/reqs/id/only_id.dim b/dim/spec/test_input/reqs/id/only_id.dim new file mode 100644 index 0000000..defe300 --- /dev/null +++ b/dim/spec/test_input/reqs/id/only_id.dim @@ -0,0 +1,3 @@ +module: test + +test_id: diff --git a/dim/spec/test_input/reqs/metadata/data.dim b/dim/spec/test_input/reqs/metadata/data.dim new file mode 100644 index 0000000..7328737 --- /dev/null +++ b/dim/spec/test_input/reqs/metadata/data.dim @@ -0,0 +1,7 @@ +module: Name1 + +metadata: | + Test + ABC + +ID_1: diff --git a/dim/spec/test_input/reqs/metadata/default.dim b/dim/spec/test_input/reqs/metadata/default.dim new file mode 100644 index 0000000..946a6c0 --- /dev/null +++ b/dim/spec/test_input/reqs/metadata/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +ID_1: diff --git a/dim/spec/test_input/reqs/metadata/invalid_type.dim b/dim/spec/test_input/reqs/metadata/invalid_type.dim new file mode 100644 index 0000000..85b9e0f --- /dev/null +++ b/dim/spec/test_input/reqs/metadata/invalid_type.dim @@ -0,0 +1,4 @@ +module: metadata +metadata: + - abc + - def diff --git a/dim/spec/test_input/reqs/misc/default.dim b/dim/spec/test_input/reqs/misc/default.dim new file mode 100644 index 0000000..029b099 --- /dev/null +++ b/dim/spec/test_input/reqs/misc/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + miscellaneous: diff --git a/dim/spec/test_input/reqs/misc/invalid_type.dim b/dim/spec/test_input/reqs/misc/invalid_type.dim new file mode 100644 index 0000000..374c038 --- /dev/null +++ b/dim/spec/test_input/reqs/misc/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + miscellaneous: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/misc/valid.dim b/dim/spec/test_input/reqs/misc/valid.dim new file mode 100644 index 0000000..5d6a3ad --- /dev/null +++ b/dim/spec/test_input/reqs/misc/valid.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + miscellaneous: This is a miscellaneous. diff --git a/dim/spec/test_input/reqs/module/config.dim b/dim/spec/test_input/reqs/module/config.dim new file mode 100644 index 0000000..5dd7b49 --- /dev/null +++ b/dim/spec/test_input/reqs/module/config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: mod*.dim + disable_naming_convention_check: yes + category: software diff --git a/dim/spec/test_input/reqs/module/default.dim b/dim/spec/test_input/reqs/module/default.dim new file mode 100644 index 0000000..f9ebe6f --- /dev/null +++ b/dim/spec/test_input/reqs/module/default.dim @@ -0,0 +1,3 @@ +module: module + +ID_0: diff --git a/dim/spec/test_input/reqs/module/empty.dim b/dim/spec/test_input/reqs/module/empty.dim new file mode 100644 index 0000000..71d91c1 --- /dev/null +++ b/dim/spec/test_input/reqs/module/empty.dim @@ -0,0 +1 @@ +module: diff --git a/dim/spec/test_input/reqs/module/invalid_type.dim b/dim/spec/test_input/reqs/module/invalid_type.dim new file mode 100644 index 0000000..6698679 --- /dev/null +++ b/dim/spec/test_input/reqs/module/invalid_type.dim @@ -0,0 +1 @@ +module: [test, test2] diff --git a/dim/spec/test_input/reqs/module/mod1.dim b/dim/spec/test_input/reqs/module/mod1.dim new file mode 100644 index 0000000..946a6c0 --- /dev/null +++ b/dim/spec/test_input/reqs/module/mod1.dim @@ -0,0 +1,3 @@ +module: Name1 + +ID_1: diff --git a/dim/spec/test_input/reqs/module/mod2.dim b/dim/spec/test_input/reqs/module/mod2.dim new file mode 100644 index 0000000..a1b25ba --- /dev/null +++ b/dim/spec/test_input/reqs/module/mod2.dim @@ -0,0 +1,3 @@ +module: Name1 + +ID_2: diff --git a/dim/spec/test_input/reqs/module/without_module.dim b/dim/spec/test_input/reqs/module/without_module.dim new file mode 100644 index 0000000..ca8a1f3 --- /dev/null +++ b/dim/spec/test_input/reqs/module/without_module.dim @@ -0,0 +1,3 @@ +test_id_1: + text: New tags + tags: safety_req, integration, safety_mechanism, cybersecurity_control, diff --git a/dim/spec/test_input/reqs/refs/default.dim b/dim/spec/test_input/reqs/refs/default.dim new file mode 100644 index 0000000..a58cc29 --- /dev/null +++ b/dim/spec/test_input/reqs/refs/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + refs: diff --git a/dim/spec/test_input/reqs/refs/duplicate.dim b/dim/spec/test_input/reqs/refs/duplicate.dim new file mode 100644 index 0000000..589d025 --- /dev/null +++ b/dim/spec/test_input/reqs/refs/duplicate.dim @@ -0,0 +1,8 @@ +module: Name1 + +id_d: + refs: id_v3 ,id_v2, id_v3, id_v2 + +id_v2: + +id_v3: diff --git a/dim/spec/test_input/reqs/refs/invalid_type.dim b/dim/spec/test_input/reqs/refs/invalid_type.dim new file mode 100644 index 0000000..d0c5d59 --- /dev/null +++ b/dim/spec/test_input/reqs/refs/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + refs: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/refs/unresolved.dim b/dim/spec/test_input/reqs/refs/unresolved.dim new file mode 100644 index 0000000..846acac --- /dev/null +++ b/dim/spec/test_input/reqs/refs/unresolved.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v1: + refs: id_v2 diff --git a/dim/spec/test_input/reqs/refs/valid.dim b/dim/spec/test_input/reqs/refs/valid.dim new file mode 100644 index 0000000..16e5ff6 --- /dev/null +++ b/dim/spec/test_input/reqs/refs/valid.dim @@ -0,0 +1,9 @@ +module: Name1 + +id_v1: + refs: id_v3 + +id_v2: + refs: id_v3 ,id_v1 + +id_v3: diff --git a/dim/spec/test_input/reqs/rs/default_config.dim b/dim/spec/test_input/reqs/rs/default_config.dim new file mode 100644 index 0000000..d009d01 --- /dev/null +++ b/dim/spec/test_input/reqs/rs/default_config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: default_input.dim + category: input + - originator: CompanyName + files: default_module.dim + category: module diff --git a/dim/spec/test_input/reqs/rs/default_input.dim b/dim/spec/test_input/reqs/rs/default_input.dim new file mode 100644 index 0000000..680bc6f --- /dev/null +++ b/dim/spec/test_input/reqs/rs/default_input.dim @@ -0,0 +1,3 @@ +module: test1 + +input_r: diff --git a/dim/spec/test_input/reqs/rs/default_module.dim b/dim/spec/test_input/reqs/rs/default_module.dim new file mode 100644 index 0000000..1a2f674 --- /dev/null +++ b/dim/spec/test_input/reqs/rs/default_module.dim @@ -0,0 +1,3 @@ +module: test2 + +module_r: diff --git a/dim/spec/test_input/reqs/rs/empty.dim b/dim/spec/test_input/reqs/rs/empty.dim new file mode 100644 index 0000000..0c1c4a4 --- /dev/null +++ b/dim/spec/test_input/reqs/rs/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_empty: + review_status: diff --git a/dim/spec/test_input/reqs/rs/invalid_type.dim b/dim/spec/test_input/reqs/rs/invalid_type.dim new file mode 100644 index 0000000..c192b9c --- /dev/null +++ b/dim/spec/test_input/reqs/rs/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + review_status: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/rs/resolve_config.dim b/dim/spec/test_input/reqs/rs/resolve_config.dim new file mode 100644 index 0000000..b6b8de2 --- /dev/null +++ b/dim/spec/test_input/reqs/rs/resolve_config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: resolve_input.dim + category: input + - originator: CompanyName + files: resolve_module.dim + category: module diff --git a/dim/spec/test_input/reqs/rs/resolve_input.dim b/dim/spec/test_input/reqs/rs/resolve_input.dim new file mode 100644 index 0000000..680bc6f --- /dev/null +++ b/dim/spec/test_input/reqs/rs/resolve_input.dim @@ -0,0 +1,3 @@ +module: test1 + +input_r: diff --git a/dim/spec/test_input/reqs/rs/resolve_module.dim b/dim/spec/test_input/reqs/rs/resolve_module.dim new file mode 100644 index 0000000..1a2f674 --- /dev/null +++ b/dim/spec/test_input/reqs/rs/resolve_module.dim @@ -0,0 +1,3 @@ +module: test2 + +module_r: diff --git a/dim/spec/test_input/reqs/rs/unknown.dim b/dim/spec/test_input/reqs/rs/unknown.dim new file mode 100644 index 0000000..aa52b9f --- /dev/null +++ b/dim/spec/test_input/reqs/rs/unknown.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_unknown: + review_status: unknown diff --git a/dim/spec/test_input/reqs/rs/valid.dim b/dim/spec/test_input/reqs/rs/valid.dim new file mode 100644 index 0000000..1e92daf --- /dev/null +++ b/dim/spec/test_input/reqs/rs/valid.dim @@ -0,0 +1,16 @@ +module: Name1 + +id_accepted: + review_status: accepted + +id_rejected: + review_status: rejected + +id_unclear: + review_status: unclear + +id_not_reviewed: + review_status: not_reviewed + +id_not_relevant: + review_status: not_relevant diff --git a/dim/spec/test_input/reqs/sources/default.dim b/dim/spec/test_input/reqs/sources/default.dim new file mode 100644 index 0000000..5bf4155 --- /dev/null +++ b/dim/spec/test_input/reqs/sources/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + sources: diff --git a/dim/spec/test_input/reqs/sources/duplicate.dim b/dim/spec/test_input/reqs/sources/duplicate.dim new file mode 100644 index 0000000..f3bbe47 --- /dev/null +++ b/dim/spec/test_input/reqs/sources/duplicate.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + sources: b.cpp ,b.cpp, a.cpp, b.cpp diff --git a/dim/spec/test_input/reqs/sources/invalid_type.dim b/dim/spec/test_input/reqs/sources/invalid_type.dim new file mode 100644 index 0000000..0c35496 --- /dev/null +++ b/dim/spec/test_input/reqs/sources/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + sources: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/sources/valid.dim b/dim/spec/test_input/reqs/sources/valid.dim new file mode 100644 index 0000000..28c97b5 --- /dev/null +++ b/dim/spec/test_input/reqs/sources/valid.dim @@ -0,0 +1,7 @@ +module: Name1 + +id_v1: + sources: a.cpp + +id_v2: + sources: a.cpp ,b.cpp diff --git a/dim/spec/test_input/reqs/status/default.dim b/dim/spec/test_input/reqs/status/default.dim new file mode 100644 index 0000000..12f5f49 --- /dev/null +++ b/dim/spec/test_input/reqs/status/default.dim @@ -0,0 +1,10 @@ +module: Name1 + +id_r: + type: requirement + +id_i: + type: information + +id_h: + type: heading_0 diff --git a/dim/spec/test_input/reqs/status/empty.dim b/dim/spec/test_input/reqs/status/empty.dim new file mode 100644 index 0000000..7490a43 --- /dev/null +++ b/dim/spec/test_input/reqs/status/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_empty: + status: diff --git a/dim/spec/test_input/reqs/status/invalid_type.dim b/dim/spec/test_input/reqs/status/invalid_type.dim new file mode 100644 index 0000000..f0d8545 --- /dev/null +++ b/dim/spec/test_input/reqs/status/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + status: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/status/resolve.dim b/dim/spec/test_input/reqs/status/resolve.dim new file mode 100644 index 0000000..12f5f49 --- /dev/null +++ b/dim/spec/test_input/reqs/status/resolve.dim @@ -0,0 +1,10 @@ +module: Name1 + +id_r: + type: requirement + +id_i: + type: information + +id_h: + type: heading_0 diff --git a/dim/spec/test_input/reqs/status/unknown.dim b/dim/spec/test_input/reqs/status/unknown.dim new file mode 100644 index 0000000..3bd9679 --- /dev/null +++ b/dim/spec/test_input/reqs/status/unknown.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_unknown: + status: unknown diff --git a/dim/spec/test_input/reqs/status/valid.dim b/dim/spec/test_input/reqs/status/valid.dim new file mode 100644 index 0000000..c6f13af --- /dev/null +++ b/dim/spec/test_input/reqs/status/valid.dim @@ -0,0 +1,10 @@ +module: Name1 + +id_draft: + status: draft + +id_valid: + status: valid + +id_invalid: + status: invalid diff --git a/dim/spec/test_input/reqs/tags_attr/default.dim b/dim/spec/test_input/reqs/tags_attr/default.dim new file mode 100644 index 0000000..f57d6aa --- /dev/null +++ b/dim/spec/test_input/reqs/tags_attr/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + tags: diff --git a/dim/spec/test_input/reqs/tags_attr/duplicate.dim b/dim/spec/test_input/reqs/tags_attr/duplicate.dim new file mode 100644 index 0000000..d181099 --- /dev/null +++ b/dim/spec/test_input/reqs/tags_attr/duplicate.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_duplicate: + tags: memory, covered, memory diff --git a/dim/spec/test_input/reqs/tags_attr/invalid_type.dim b/dim/spec/test_input/reqs/tags_attr/invalid_type.dim new file mode 100644 index 0000000..2d1e86e --- /dev/null +++ b/dim/spec/test_input/reqs/tags_attr/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + tags: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/tags_attr/unknown.dim b/dim/spec/test_input/reqs/tags_attr/unknown.dim new file mode 100644 index 0000000..6fa66f3 --- /dev/null +++ b/dim/spec/test_input/reqs/tags_attr/unknown.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + tags: unknown diff --git a/dim/spec/test_input/reqs/tags_attr/valid.dim b/dim/spec/test_input/reqs/tags_attr/valid.dim new file mode 100644 index 0000000..60a7e90 --- /dev/null +++ b/dim/spec/test_input/reqs/tags_attr/valid.dim @@ -0,0 +1,9 @@ +module: Name1 + +id_v1: + tags: memory + +id_v2: + tags: functional_safety_mechanism, cybersecurity_control, confidentiality, integrity, availability, authenticity, authority, + covered, tested, legal, performance, memory, structural, configuration, calibration, established, sys, srs, swa, smd, process, test, + obd, emission_doc, emission_tailpipe, emission_performance, unit, interface, tool, non_functional diff --git a/dim/spec/test_input/reqs/tester/default.dim b/dim/spec/test_input/reqs/tester/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/tester/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/tester/default_config.dim b/dim/spec/test_input/reqs/tester/default_config.dim new file mode 100644 index 0000000..ca171f4 --- /dev/null +++ b/dim/spec/test_input/reqs/tester/default_config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: default.dim + category: module diff --git a/dim/spec/test_input/reqs/tester/invalid_type.dim b/dim/spec/test_input/reqs/tester/invalid_type.dim new file mode 100644 index 0000000..909998b --- /dev/null +++ b/dim/spec/test_input/reqs/tester/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + tester: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/tester/resolve_config.dim b/dim/spec/test_input/reqs/tester/resolve_config.dim new file mode 100644 index 0000000..b6b8de2 --- /dev/null +++ b/dim/spec/test_input/reqs/tester/resolve_config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: resolve_input.dim + category: input + - originator: CompanyName + files: resolve_module.dim + category: module diff --git a/dim/spec/test_input/reqs/tester/resolve_input.dim b/dim/spec/test_input/reqs/tester/resolve_input.dim new file mode 100644 index 0000000..8e70e87 --- /dev/null +++ b/dim/spec/test_input/reqs/tester/resolve_input.dim @@ -0,0 +1,7 @@ +module: test1 + +input_r: + type: requirement + +input_i: + type: information diff --git a/dim/spec/test_input/reqs/tester/resolve_module.dim b/dim/spec/test_input/reqs/tester/resolve_module.dim new file mode 100644 index 0000000..cb1fed0 --- /dev/null +++ b/dim/spec/test_input/reqs/tester/resolve_module.dim @@ -0,0 +1,7 @@ +module: test2 + +module_r: + type: requirement + +module_i: + type: information diff --git a/dim/spec/test_input/reqs/tester/valid.dim b/dim/spec/test_input/reqs/tester/valid.dim new file mode 100644 index 0000000..17f1cf7 --- /dev/null +++ b/dim/spec/test_input/reqs/tester/valid.dim @@ -0,0 +1,12 @@ +module: Name1 + +id_v1: + tester: Hallo + +id_v2: + tester: + +id_v3: + tester: | + A + B diff --git a/dim/spec/test_input/reqs/text/default.dim b/dim/spec/test_input/reqs/text/default.dim new file mode 100644 index 0000000..37b57f5 --- /dev/null +++ b/dim/spec/test_input/reqs/text/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +ID_default: diff --git a/dim/spec/test_input/reqs/text/no_string.dim b/dim/spec/test_input/reqs/text/no_string.dim new file mode 100644 index 0000000..bec08e8 --- /dev/null +++ b/dim/spec/test_input/reqs/text/no_string.dim @@ -0,0 +1,9 @@ +module: test + +test_id_1: + text: + - ./cli.dim + - ./exporter.dim + - ./explorer.dim + - ./validator.dim + - ./verifier.dim \ No newline at end of file diff --git a/dim/spec/test_input/reqs/text/valid.dim b/dim/spec/test_input/reqs/text/valid.dim new file mode 100644 index 0000000..36dc7df --- /dev/null +++ b/dim/spec/test_input/reqs/text/valid.dim @@ -0,0 +1,12 @@ +module: Name1 + +ID_singleLine: + text: Single line + +ID_multiLine: + text: | + Multi + line + +ID_empty: + text: diff --git a/dim/spec/test_input/reqs/text/valid_short.dim b/dim/spec/test_input/reqs/text/valid_short.dim new file mode 100644 index 0000000..d012912 --- /dev/null +++ b/dim/spec/test_input/reqs/text/valid_short.dim @@ -0,0 +1,8 @@ +module: test_module_1 + +test_id_h0: h0 H0 +test_id_h1: h1 H1 +test_id_h100: h100 H100 +test_id_info: | + info Short + information diff --git a/dim/spec/test_input/reqs/text_lang/default.dim b/dim/spec/test_input/reqs/text_lang/default.dim new file mode 100644 index 0000000..3af57a4 --- /dev/null +++ b/dim/spec/test_input/reqs/text_lang/default.dim @@ -0,0 +1,7 @@ +module: Name1 + +ID_default1: + text_german: + text_french: bla + +ID_default2: diff --git a/dim/spec/test_input/reqs/text_lang/no_string.dim b/dim/spec/test_input/reqs/text_lang/no_string.dim new file mode 100644 index 0000000..e885cf6 --- /dev/null +++ b/dim/spec/test_input/reqs/text_lang/no_string.dim @@ -0,0 +1,9 @@ +module: test + +test_id_1: + text_german: + - ./cli.dim + - ./exporter.dim + - ./explorer.dim + - ./validator.dim + - ./verifier.dim diff --git a/dim/spec/test_input/reqs/text_lang/not_specified.dim b/dim/spec/test_input/reqs/text_lang/not_specified.dim new file mode 100644 index 0000000..9fa0d34 --- /dev/null +++ b/dim/spec/test_input/reqs/text_lang/not_specified.dim @@ -0,0 +1,4 @@ +module: Name1 + +ID_not: + text_german: hey diff --git a/dim/spec/test_input/reqs/text_lang/valid.dim b/dim/spec/test_input/reqs/text_lang/valid.dim new file mode 100644 index 0000000..54b4fdb --- /dev/null +++ b/dim/spec/test_input/reqs/text_lang/valid.dim @@ -0,0 +1,15 @@ +module: test_lang + +ESR_Test_1: + text: | + juhu + juhu + text_spanish: ole + +ESR_Test_2: + text: mist + text_english: damn + +ESR_Test_3: + text: achso + text_french: diff --git a/dim/spec/test_input/reqs/ts/combined_none.dim b/dim/spec/test_input/reqs/ts/combined_none.dim new file mode 100644 index 0000000..67a8048 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/combined_none.dim @@ -0,0 +1,5 @@ +module: test + +test_id_1: + text: test_value + test_setups: none, on_target \ No newline at end of file diff --git a/dim/spec/test_input/reqs/ts/default.dim b/dim/spec/test_input/reqs/ts/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/ts/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/ts/default_config.dim b/dim/spec/test_input/reqs/ts/default_config.dim new file mode 100644 index 0000000..ca171f4 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/default_config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: default.dim + category: module diff --git a/dim/spec/test_input/reqs/ts/duplicate.dim b/dim/spec/test_input/reqs/ts/duplicate.dim new file mode 100644 index 0000000..f3b93bd --- /dev/null +++ b/dim/spec/test_input/reqs/ts/duplicate.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_duplicate: + test_setups: off_target, on_target, off_target diff --git a/dim/spec/test_input/reqs/ts/empty.dim b/dim/spec/test_input/reqs/ts/empty.dim new file mode 100644 index 0000000..bed2765 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + test_setups: \ No newline at end of file diff --git a/dim/spec/test_input/reqs/ts/invalid_type.dim b/dim/spec/test_input/reqs/ts/invalid_type.dim new file mode 100644 index 0000000..3481924 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + test_setups: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/ts/resolve_config.dim b/dim/spec/test_input/reqs/ts/resolve_config.dim new file mode 100644 index 0000000..ff263bb --- /dev/null +++ b/dim/spec/test_input/reqs/ts/resolve_config.dim @@ -0,0 +1,11 @@ +Config: + - originator: Customer + files: resolve_input.dim + category: input + - originator: CompanyName + files: resolve_module.dim + category: module + - originator: CompanyName + files: resolve_software.dim + disable_naming_convention_check: yes + category: software diff --git a/dim/spec/test_input/reqs/ts/resolve_input.dim b/dim/spec/test_input/reqs/ts/resolve_input.dim new file mode 100644 index 0000000..1048696 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/resolve_input.dim @@ -0,0 +1,15 @@ +module: test1 + +input_r: + type: requirement + +input_i: + type: information + +input_p: + type: requirement + tags: progress + +input_t: + type: requirement + tags: tool diff --git a/dim/spec/test_input/reqs/ts/resolve_module.dim b/dim/spec/test_input/reqs/ts/resolve_module.dim new file mode 100644 index 0000000..b438845 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/resolve_module.dim @@ -0,0 +1,15 @@ +module: test2 + +module_r: + type: requirement + +module_i: + type: information + +module_p: + type: requirement + tags: process + +module_t: + type: requirement + tags: tool diff --git a/dim/spec/test_input/reqs/ts/resolve_software.dim b/dim/spec/test_input/reqs/ts/resolve_software.dim new file mode 100644 index 0000000..4c7b6a7 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/resolve_software.dim @@ -0,0 +1,15 @@ +module: test3 + +software_r: + type: requirement + +software_i: + type: information + +software_p: + type: requirement + tags: process + +software_t: + type: requirement + tags: tool diff --git a/dim/spec/test_input/reqs/ts/unknown.dim b/dim/spec/test_input/reqs/ts/unknown.dim new file mode 100644 index 0000000..a042d28 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/unknown.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_unknown: + test_setups: unknown diff --git a/dim/spec/test_input/reqs/ts/valid.dim b/dim/spec/test_input/reqs/ts/valid.dim new file mode 100644 index 0000000..b559f40 --- /dev/null +++ b/dim/spec/test_input/reqs/ts/valid.dim @@ -0,0 +1,7 @@ +module: Name1 + +id_v1: + test_setups: none + +id_v2: + test_setups: off_target, on_target, manual diff --git a/dim/spec/test_input/reqs/type/default.dim b/dim/spec/test_input/reqs/type/default.dim new file mode 100644 index 0000000..8cc6a9b --- /dev/null +++ b/dim/spec/test_input/reqs/type/default.dim @@ -0,0 +1,3 @@ +module: Name1 + +id_d: diff --git a/dim/spec/test_input/reqs/type/empty.dim b/dim/spec/test_input/reqs/type/empty.dim new file mode 100644 index 0000000..badb19c --- /dev/null +++ b/dim/spec/test_input/reqs/type/empty.dim @@ -0,0 +1,4 @@ +module: empty_type + +ID_T1: + type: \ No newline at end of file diff --git a/dim/spec/test_input/reqs/type/heading101.dim b/dim/spec/test_input/reqs/type/heading101.dim new file mode 100644 index 0000000..c195cc6 --- /dev/null +++ b/dim/spec/test_input/reqs/type/heading101.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_h101: + type: heading_101 diff --git a/dim/spec/test_input/reqs/type/unknown.dim b/dim/spec/test_input/reqs/type/unknown.dim new file mode 100644 index 0000000..9cb8516 --- /dev/null +++ b/dim/spec/test_input/reqs/type/unknown.dim @@ -0,0 +1,4 @@ +module: Name1 + +ID_unknown: + type: unknown diff --git a/dim/spec/test_input/reqs/type/valid.dim b/dim/spec/test_input/reqs/type/valid.dim new file mode 100644 index 0000000..be902a7 --- /dev/null +++ b/dim/spec/test_input/reqs/type/valid.dim @@ -0,0 +1,16 @@ +module: Name1 + +id_r: + type: requirement + +id_i: + type: information + +id_h0: + type: heading_0 + +id_h1: + type: heading_1 + +id_h100: + type: heading_100 diff --git a/dim/spec/test_input/reqs/type/valid_short.dim b/dim/spec/test_input/reqs/type/valid_short.dim new file mode 100644 index 0000000..d012912 --- /dev/null +++ b/dim/spec/test_input/reqs/type/valid_short.dim @@ -0,0 +1,8 @@ +module: test_module_1 + +test_id_h0: h0 H0 +test_id_h1: h1 H1 +test_id_h100: h100 H100 +test_id_info: | + info Short + information diff --git a/dim/spec/test_input/reqs/vc/default.dim b/dim/spec/test_input/reqs/vc/default.dim new file mode 100644 index 0000000..91d67af --- /dev/null +++ b/dim/spec/test_input/reqs/vc/default.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_d: + verification_criteria: diff --git a/dim/spec/test_input/reqs/vc/empty.dim b/dim/spec/test_input/reqs/vc/empty.dim new file mode 100644 index 0000000..7a003e4 --- /dev/null +++ b/dim/spec/test_input/reqs/vc/empty.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_e: + verification_criteria: diff --git a/dim/spec/test_input/reqs/vc/invalid_type.dim b/dim/spec/test_input/reqs/vc/invalid_type.dim new file mode 100644 index 0000000..502f3d9 --- /dev/null +++ b/dim/spec/test_input/reqs/vc/invalid_type.dim @@ -0,0 +1,6 @@ +module: Name1 + +id_v: + verification_criteria: + - Invalid + - Type diff --git a/dim/spec/test_input/reqs/vc/valid.dim b/dim/spec/test_input/reqs/vc/valid.dim new file mode 100644 index 0000000..433303e --- /dev/null +++ b/dim/spec/test_input/reqs/vc/valid.dim @@ -0,0 +1,4 @@ +module: Name1 + +id_v: + verification_criteria: This is a VC. diff --git a/dim/spec/test_input/reqs/vc_lang/default.dim b/dim/spec/test_input/reqs/vc_lang/default.dim new file mode 100644 index 0000000..93a7e43 --- /dev/null +++ b/dim/spec/test_input/reqs/vc_lang/default.dim @@ -0,0 +1,7 @@ +module: Name1 + +ID_default1: + verification_criteria_german: + verification_criteria_french: bla + +ID_default2: diff --git a/dim/spec/test_input/reqs/vc_lang/no_string.dim b/dim/spec/test_input/reqs/vc_lang/no_string.dim new file mode 100644 index 0000000..f17eba4 --- /dev/null +++ b/dim/spec/test_input/reqs/vc_lang/no_string.dim @@ -0,0 +1,9 @@ +module: test + +test_id_1: + verification_criteria_german: + - ./cli.dim + - ./exporter.dim + - ./explorer.dim + - ./validator.dim + - ./verifier.dim diff --git a/dim/spec/test_input/reqs/vc_lang/not_specified.dim b/dim/spec/test_input/reqs/vc_lang/not_specified.dim new file mode 100644 index 0000000..fadc997 --- /dev/null +++ b/dim/spec/test_input/reqs/vc_lang/not_specified.dim @@ -0,0 +1,4 @@ +module: Name1 + +ID_not: + verification_criteria_german: hey diff --git a/dim/spec/test_input/reqs/vc_lang/valid.dim b/dim/spec/test_input/reqs/vc_lang/valid.dim new file mode 100644 index 0000000..843fd43 --- /dev/null +++ b/dim/spec/test_input/reqs/vc_lang/valid.dim @@ -0,0 +1,15 @@ +module: vc_lang + +ESR_Test_1: + verification_criteria: | + juhu + juhu + verification_criteria_spanish: ole + +ESR_Test_2: + verification_criteria: mist + verification_criteria_english: damn + +ESR_Test_3: + verification_criteria: achso + verification_criteria_french: diff --git a/dim/spec/test_input/resolved_function/config.dim b/dim/spec/test_input/resolved_function/config.dim new file mode 100644 index 0000000..6de22c0 --- /dev/null +++ b/dim/spec/test_input/resolved_function/config.dim @@ -0,0 +1,7 @@ +Config: + - originator: Customer + files: ./modules/Module1.dim + category: input + - originator: CompanyName + files: ./modules/Module2.dim + category: module diff --git a/dim/spec/test_input/resolved_function/modules/Module1.dim b/dim/spec/test_input/resolved_function/modules/Module1.dim new file mode 100644 index 0000000..31e96a1 --- /dev/null +++ b/dim/spec/test_input/resolved_function/modules/Module1.dim @@ -0,0 +1,23 @@ +module: Test_Test_Core + +RESOLVE_001: + text: Test req + refs: RESOLVE_003, RESOLVE_011 + +RESOLVE_002: + text: Test req + test_setups: on_target, manual + +RESOLVE_003: + text: Test req + review_status: accepted + tags: safety_mechanism + sources: abc.c + +RESOLVE_004: + text: Test req + tags: confidentiality, integrity, tested, covered + sources: abc.c, def.c,abc.c + +RESOLVE_005: + text: Test req \ No newline at end of file diff --git a/dim/spec/test_input/resolved_function/modules/Module2.dim b/dim/spec/test_input/resolved_function/modules/Module2.dim new file mode 100644 index 0000000..58ca32a --- /dev/null +++ b/dim/spec/test_input/resolved_function/modules/Module2.dim @@ -0,0 +1,4 @@ +module: Test_Test_Secure + +RESOLVE_011: + text: Test req diff --git a/dim/spec/test_input/same_id_different_files/Config.yml b/dim/spec/test_input/same_id_different_files/Config.yml new file mode 100644 index 0000000..378079e --- /dev/null +++ b/dim/spec/test_input/same_id_different_files/Config.yml @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - Input*.yml + category: module + diff --git a/dim/spec/test_input/same_id_different_files/Input1.yml b/dim/spec/test_input/same_id_different_files/Input1.yml new file mode 100644 index 0000000..16f96d2 --- /dev/null +++ b/dim/spec/test_input/same_id_different_files/Input1.yml @@ -0,0 +1,7 @@ +module: input_1 + +UniqueID: + text: great. + +SameID: + text: 1of2 diff --git a/dim/spec/test_input/same_id_different_files/Input2.yml b/dim/spec/test_input/same_id_different_files/Input2.yml new file mode 100644 index 0000000..7bad1a1 --- /dev/null +++ b/dim/spec/test_input/same_id_different_files/Input2.yml @@ -0,0 +1,4 @@ +module: input_1 + +SameID: + text: 2of2 diff --git a/dim/spec/test_input/same_id_same_file/Config.yml b/dim/spec/test_input/same_id_same_file/Config.yml new file mode 100644 index 0000000..820cee2 --- /dev/null +++ b/dim/spec/test_input/same_id_same_file/Config.yml @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: + - Input*.yml + category: module diff --git a/dim/spec/test_input/same_id_same_file/Input1.yml b/dim/spec/test_input/same_id_same_file/Input1.yml new file mode 100644 index 0000000..1623fd0 --- /dev/null +++ b/dim/spec/test_input/same_id_same_file/Input1.yml @@ -0,0 +1,8 @@ +UniqueID: + text: great. + +SameID: + text: 1of2 + +SameID: + text: 2of2 diff --git a/dim/spec/test_input/slash_in_modname/test_module_1.dim b/dim/spec/test_input/slash_in_modname/test_module_1.dim new file mode 100644 index 0000000..db0f8de --- /dev/null +++ b/dim/spec/test_input/slash_in_modname/test_module_1.dim @@ -0,0 +1,9 @@ +module: test/module + +test_id_1: + type: heading_1 + text: test + +test_id_2: + text: great again. + refs: test_id_3 diff --git a/dim/spec/test_input/software_configs/config.dim b/dim/spec/test_input/software_configs/config.dim new file mode 100644 index 0000000..6abe4e3 --- /dev/null +++ b/dim/spec/test_input/software_configs/config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: test_module.dim + disable_naming_convention_check: yes + category: module + diff --git a/dim/spec/test_input/software_configs/test_input.dim b/dim/spec/test_input/software_configs/test_input.dim new file mode 100644 index 0000000..27b4318 --- /dev/null +++ b/dim/spec/test_input/software_configs/test_input.dim @@ -0,0 +1,4 @@ +module: moduleA + +ESR-0001: + text: sample_text diff --git a/dim/spec/test_input/software_configs/with_category_software/config.dim b/dim/spec/test_input/software_configs/with_category_software/config.dim new file mode 100644 index 0000000..5c0dd4d --- /dev/null +++ b/dim/spec/test_input/software_configs/with_category_software/config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: test_module.dim + disable_naming_convention_check: yes + category: software diff --git a/dim/spec/test_input/software_configs/with_category_software/invalid_name_check_config.dim b/dim/spec/test_input/software_configs/with_category_software/invalid_name_check_config.dim new file mode 100644 index 0000000..bef7fee --- /dev/null +++ b/dim/spec/test_input/software_configs/with_category_software/invalid_name_check_config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: test_module.dim + disable_naming_convention_check: wrong + category: software diff --git a/dim/spec/test_input/software_configs/with_category_software/test_module.dim b/dim/spec/test_input/software_configs/with_category_software/test_module.dim new file mode 100644 index 0000000..9c7dff3 --- /dev/null +++ b/dim/spec/test_input/software_configs/with_category_software/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +ESR-0001: + text: sample text diff --git a/dim/spec/test_input/software_configs/with_category_software/with_name_check_no_config.dim b/dim/spec/test_input/software_configs/with_category_software/with_name_check_no_config.dim new file mode 100644 index 0000000..1242eab --- /dev/null +++ b/dim/spec/test_input/software_configs/with_category_software/with_name_check_no_config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: test_module.dim + disable_naming_convention_check: no + category: software diff --git a/dim/spec/test_input/software_configs/with_category_software/without_name_check_config.dim b/dim/spec/test_input/software_configs/with_category_software/without_name_check_config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_configs/with_category_software/without_name_check_config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/config.dim b/dim/spec/test_input/software_requirements/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/legacy/config.dim b/dim/spec/test_input/software_requirements/legacy/config.dim new file mode 100644 index 0000000..4c907cd --- /dev/null +++ b/dim/spec/test_input/software_requirements/legacy/config.dim @@ -0,0 +1,5 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software + disable_naming_convention_check: yes diff --git a/dim/spec/test_input/software_requirements/legacy/test_module.dim b/dim/spec/test_input/software_requirements/legacy/test_module.dim new file mode 100644 index 0000000..2265743 --- /dev/null +++ b/dim/spec/test_input/software_requirements/legacy/test_module.dim @@ -0,0 +1,13 @@ +module: moduleA + +feature#1_aspect#2: + text: sample text + +SRS_feature#1_aspect#2: + text: sample text + +SRS_feature#1_aspect#2_wrong: + text: sample text + +loremIpsum: + text: sample text diff --git a/dim/spec/test_input/software_requirements/missing_aspect/config.dim b/dim/spec/test_input/software_requirements/missing_aspect/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/missing_aspect/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/missing_aspect/test_module.dim b/dim/spec/test_input/software_requirements/missing_aspect/test_module.dim new file mode 100644 index 0000000..db0a83b --- /dev/null +++ b/dim/spec/test_input/software_requirements/missing_aspect/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +SRS_feature_: + text: sample text diff --git a/dim/spec/test_input/software_requirements/missing_feature/config.dim b/dim/spec/test_input/software_requirements/missing_feature/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/missing_feature/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/missing_feature/test_module.dim b/dim/spec/test_input/software_requirements/missing_feature/test_module.dim new file mode 100644 index 0000000..0f6725c --- /dev/null +++ b/dim/spec/test_input/software_requirements/missing_feature/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_missing-feature + +SRS__aspect: + text: sample text. diff --git a/dim/spec/test_input/software_requirements/module_with_invalid_chars/config.dim b/dim/spec/test_input/software_requirements/module_with_invalid_chars/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_with_invalid_chars/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/module_with_invalid_chars/test_module.dim b/dim/spec/test_input/software_requirements/module_with_invalid_chars/test_module.dim new file mode 100644 index 0000000..5cbd63b --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_with_invalid_chars/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_feature#1 + +SRS_req_asp: + text: sample_text diff --git a/dim/spec/test_input/software_requirements/module_with_multiple_underscores/config.dim b/dim/spec/test_input/software_requirements/module_with_multiple_underscores/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_with_multiple_underscores/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/module_with_multiple_underscores/test_module.dim b/dim/spec/test_input/software_requirements/module_with_multiple_underscores/test_module.dim new file mode 100644 index 0000000..e878f86 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_with_multiple_underscores/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_feature_aspect + +SRS_req_asp: + text: sample text diff --git a/dim/spec/test_input/software_requirements/module_without_feature/config.dim b/dim/spec/test_input/software_requirements/module_without_feature/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_without_feature/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/module_without_feature/test_module.dim b/dim/spec/test_input/software_requirements/module_without_feature/test_module.dim new file mode 100644 index 0000000..6f2b10a --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_without_feature/test_module.dim @@ -0,0 +1,4 @@ +module: SRSFeature + +SRS_req_asp: + text: sample text diff --git a/dim/spec/test_input/software_requirements/module_without_srs/config.dim b/dim/spec/test_input/software_requirements/module_without_srs/config.dim new file mode 100644 index 0000000..f906605 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_without_srs/config.dim @@ -0,0 +1,5 @@ + +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/module_without_srs/test_module.dim b/dim/spec/test_input/software_requirements/module_without_srs/test_module.dim new file mode 100644 index 0000000..53dde07 --- /dev/null +++ b/dim/spec/test_input/software_requirements/module_without_srs/test_module.dim @@ -0,0 +1,4 @@ +module: SRSFeature_feature + +SRS_req_asp: + text: sample text diff --git a/dim/spec/test_input/software_requirements/multiple_underscores/config.dim b/dim/spec/test_input/software_requirements/multiple_underscores/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/multiple_underscores/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/multiple_underscores/test_module.dim b/dim/spec/test_input/software_requirements/multiple_underscores/test_module.dim new file mode 100644 index 0000000..e4f86a0 --- /dev/null +++ b/dim/spec/test_input/software_requirements/multiple_underscores/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +SRS_feature-1_aspect-1_wrong: + text: sample text diff --git a/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/config.dim b/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/test_module.dim b/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/test_module.dim new file mode 100644 index 0000000..311d831 --- /dev/null +++ b/dim/spec/test_input/software_requirements/non_alphanumeric_in_aspect/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +SRS_feature-1_aspect#-1: + text: sample text diff --git a/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/config.dim b/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/test_module.dim b/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/test_module.dim new file mode 100644 index 0000000..f6cc6f7 --- /dev/null +++ b/dim/spec/test_input/software_requirements/non_alphanumeric_in_feature/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +SRS_feature@-1_aspect-1: + text: sample text diff --git a/dim/spec/test_input/software_requirements/only_srs/config.dim b/dim/spec/test_input/software_requirements/only_srs/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/only_srs/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/only_srs/test_module.dim b/dim/spec/test_input/software_requirements/only_srs/test_module.dim new file mode 100644 index 0000000..02185d2 --- /dev/null +++ b/dim/spec/test_input/software_requirements/only_srs/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +SRS_: + text: sample text diff --git a/dim/spec/test_input/software_requirements/start_without_srs/config.dim b/dim/spec/test_input/software_requirements/start_without_srs/config.dim new file mode 100644 index 0000000..eff1557 --- /dev/null +++ b/dim/spec/test_input/software_requirements/start_without_srs/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: software diff --git a/dim/spec/test_input/software_requirements/start_without_srs/test_module.dim b/dim/spec/test_input/software_requirements/start_without_srs/test_module.dim new file mode 100644 index 0000000..b8878cc --- /dev/null +++ b/dim/spec/test_input/software_requirements/start_without_srs/test_module.dim @@ -0,0 +1,4 @@ +module: SRS_moduleA + +feature-1_aspect-1: + text: sample text diff --git a/dim/spec/test_input/software_requirements/test_module.dim b/dim/spec/test_input/software_requirements/test_module.dim new file mode 100644 index 0000000..b953e1c --- /dev/null +++ b/dim/spec/test_input/software_requirements/test_module.dim @@ -0,0 +1,4 @@ +module: moduleA + +SRS_feature-1_aspect-1: + text: sample text diff --git a/dim/spec/test_input/software_requirements/without_software_category/config.dim b/dim/spec/test_input/software_requirements/without_software_category/config.dim new file mode 100644 index 0000000..4920f56 --- /dev/null +++ b/dim/spec/test_input/software_requirements/without_software_category/config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_module.dim + category: module diff --git a/dim/spec/test_input/software_requirements/without_software_category/test_module.dim b/dim/spec/test_input/software_requirements/without_software_category/test_module.dim new file mode 100644 index 0000000..90fa161 --- /dev/null +++ b/dim/spec/test_input/software_requirements/without_software_category/test_module.dim @@ -0,0 +1,10 @@ +module: SRS_moduleA + +feature#1_aspect#2: + text: sample text + +SRS_feature#1_aspect#2: + text: sample text + +SRS_feature#1_aspect#2_wrong: + text: sample text diff --git a/dim/spec/test_input/spaces_html/module.dim b/dim/spec/test_input/spaces_html/module.dim new file mode 100644 index 0000000..c9e9b46 --- /dev/null +++ b/dim/spec/test_input/spaces_html/module.dim @@ -0,0 +1,25 @@ +module: spaces_html + +Spaces_NoHtml_1: + text: " x x " + +Spaces_NoHtml_2: + text: " x x " + +Spaces_NoHtml_3: + text: " x x " + +Spaces_Html_1: + text: x x + +Spaces_Html_2: + text: x x + +Spaces_Html_3: + text: x x + +Tabs_NoHtml: + text: " x x " + +Tabs_Html: + text: " x x " diff --git a/dim/spec/test_input/spaces_html/output/Requirements.rst b/dim/spec/test_input/spaces_html/output/Requirements.rst new file mode 100644 index 0000000..c6a9524 --- /dev/null +++ b/dim/spec/test_input/spaces_html/output/Requirements.rst @@ -0,0 +1,162 @@ +:raw-html:`spaces_html` +======================= + +.. requirement:: Spaces_NoHtml_1 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x x` + +.. requirement:: Spaces_NoHtml_2 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x  x` + +.. requirement:: Spaces_NoHtml_3 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x   x` + +.. requirement:: Spaces_Html_1 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x x` + +.. requirement:: Spaces_Html_2 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x x` + +.. requirement:: Spaces_Html_3 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x x` + +.. requirement:: Tabs_NoHtml + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`x  x` + +.. requirement:: Tabs_Html + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`  x  x  ` diff --git a/dim/spec/test_input/stats_input/Config.dim b/dim/spec/test_input/stats_input/Config.dim new file mode 100644 index 0000000..7f5a1e0 --- /dev/null +++ b/dim/spec/test_input/stats_input/Config.dim @@ -0,0 +1,4 @@ +Config: + - originator: CompanyName + files: test_*.dim + category: module diff --git a/dim/spec/test_input/stats_input/test_module_1.dim b/dim/spec/test_input/stats_input/test_module_1.dim new file mode 100644 index 0000000..26c2897 --- /dev/null +++ b/dim/spec/test_input/stats_input/test_module_1.dim @@ -0,0 +1,49 @@ +module: test_module_1 + +test_id_1: + text: First Test Requirement + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + status: valid + +test_id_3: + text: Third Test Requirement + review_status: unclear + status: valid + +test_id_4: + text: Fourth Test Requirement + review_status: rejected + status: valid + +test_id_5: + text: Fifth Test Requirement + review_status: not_reviewed + status: valid + +test_id_6: + text: Sixth Test Requirement + review_status: accepted + tags: covered + status: valid + +test_id_7: + text: Seventh Test Requirement + review_status: accepted + tags: covered + status: valid + +test_id_8: + text: Eighth Test Requirement + review_status: accepted + tags: covered + status: valid + +test_id_9: + text: Ninth Test Requirement + review_status: accepted + status: valid + \ No newline at end of file diff --git a/dim/spec/test_input/stats_input/test_module_2.dim b/dim/spec/test_input/stats_input/test_module_2.dim new file mode 100644 index 0000000..053ecb8 --- /dev/null +++ b/dim/spec/test_input/stats_input/test_module_2.dim @@ -0,0 +1,13 @@ +module: test_module_2 + +test_id_10: + text: First Test Requirement + review_status: accepted + tags: covered + status: valid + +test_id_11: + text: Second Test Requirement + review_status: accepted + tags: covered + status: valid diff --git a/dim/spec/test_input/verification_methods/all_none.dim b/dim/spec/test_input/verification_methods/all_none.dim new file mode 100644 index 0000000..b1dfc12 --- /dev/null +++ b/dim/spec/test_input/verification_methods/all_none.dim @@ -0,0 +1,5 @@ +module: test_verification_methods + +ID_1: + test_setups: none + verification_methods: none, none diff --git a/dim/spec/test_input/verification_methods/all_none.dim.expected b/dim/spec/test_input/verification_methods/all_none.dim.expected new file mode 100644 index 0000000..7414740 --- /dev/null +++ b/dim/spec/test_input/verification_methods/all_none.dim.expected @@ -0,0 +1,4 @@ +document: test_verification_methods + +ID_1: + verification_methods: none diff --git a/dim/spec/test_input/verification_methods/none_test_setups.dim b/dim/spec/test_input/verification_methods/none_test_setups.dim new file mode 100644 index 0000000..0ea1d11 --- /dev/null +++ b/dim/spec/test_input/verification_methods/none_test_setups.dim @@ -0,0 +1,5 @@ +module: test_verification_methods + +ID_1: + verification_methods: off_target + test_setups: none diff --git a/dim/spec/test_input/verification_methods/none_verification_methods.dim b/dim/spec/test_input/verification_methods/none_verification_methods.dim new file mode 100644 index 0000000..c850881 --- /dev/null +++ b/dim/spec/test_input/verification_methods/none_verification_methods.dim @@ -0,0 +1,6 @@ +module: test_verification_methods + +ID_1: + verification_methods: none + test_setups: off_target + diff --git a/dim/spec/test_input/verification_methods/output/verification_methods/Requirement.csv b/dim/spec/test_input/verification_methods/output/verification_methods/Requirement.csv new file mode 100644 index 0000000..c1af673 --- /dev/null +++ b/dim/spec/test_input/verification_methods/output/verification_methods/Requirement.csv @@ -0,0 +1,7 @@ +Sep=, +id,document_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,verification_methods,status,review_status,comment,miscellaneous,sources,refs +"ID_1","verification_method_test","","requirement","Dim file should allow only verification_methods attribute, but when test_setups method is called on the requirement object it shall return the array that verification_methods attribute mentions in the Dim file","","","","","not_set","not_set","","","none","draft","not_reviewed","","","","" +"ID_2","verification_method_test","","requirement","","","","","","not_set","not_set","","","off_target, on_target","draft","not_reviewed","","","","" +"ID_3","verification_method_test","","requirement","","","","","","not_set","not_set","","","off_target","draft","not_reviewed","","","","" +"ID_4","verification_method_test","","requirement","","","","","","not_set","not_set","","","off_target, on_target","draft","not_reviewed","","","","" +"ID_5","verification_method_test","","requirement","","","","","","not_set","not_set","","","off_target, on_target, manual","draft","not_reviewed","","","","" diff --git a/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.json b/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.json new file mode 100644 index 0000000..26ac757 --- /dev/null +++ b/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.json @@ -0,0 +1,112 @@ +[ + { + "id": "ID_1", + "document_name": "verification_method_test", + "originator": "", + "type": "requirement", + "text": "Dim file should allow only verification_methods attribute, but when test_setups method is called on the requirement object it shall return the array that verification_methods attribute mentions in the Dim file", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "none", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ID_2", + "document_name": "verification_method_test", + "originator": "", + "type": "requirement", + "text": "", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "off_target, on_target", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ID_3", + "document_name": "verification_method_test", + "originator": "", + "type": "requirement", + "text": "", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "off_target", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ID_4", + "document_name": "verification_method_test", + "originator": "", + "type": "requirement", + "text": "", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "off_target, on_target", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + }, + { + "id": "ID_5", + "document_name": "verification_method_test", + "originator": "", + "type": "requirement", + "text": "", + "verification_criteria": "", + "feature": "", + "change_request": "", + "tags": "", + "asil": "not_set", + "cal": "not_set", + "developer": "", + "tester": "", + "verification_methods": "off_target, on_target, manual", + "status": "draft", + "review_status": "not_reviewed", + "comment": "", + "miscellaneous": "", + "sources": "", + "refs": "" + } +] diff --git a/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.rst b/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.rst new file mode 100644 index 0000000..5a91b1c --- /dev/null +++ b/dim/spec/test_input/verification_methods/output/verification_methods/Requirements.rst @@ -0,0 +1,94 @@ +:raw-html:`verification_method_test` +==================================== + +.. requirement:: ID_1 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: none + :verification_criteria: + + :raw-html:`Dim file should allow only verification_methods attribute, but when test_setups method is called on the requirement object it shall return the array that verification_methods attribute mentions in the Dim file` + +.. requirement:: ID_2 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: off_target, on_target + :verification_criteria: + +.. requirement:: ID_3 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: off_target + :verification_criteria: + +.. requirement:: ID_4 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: off_target, on_target + :verification_criteria: + +.. requirement:: ID_5 + :category: unspecified + :status: draft + :review_status: not_reviewed + :asil: not_set + :cal: not_set + :tags: + :comment: + :miscellaneous: + :refs: + :sources: + :feature: + :change_request: + :developer: + :tester: + :verification_methods: off_target, on_target, manual + :verification_criteria: diff --git a/dim/spec/test_input/verification_methods/single_none.dim b/dim/spec/test_input/verification_methods/single_none.dim new file mode 100644 index 0000000..ceae170 --- /dev/null +++ b/dim/spec/test_input/verification_methods/single_none.dim @@ -0,0 +1,7 @@ +module: test_verification_methods + +ID_1: + test_setups: none + +ID_2: + verification_methods: none diff --git a/dim/spec/test_input/verification_methods/single_none.dim.expected b/dim/spec/test_input/verification_methods/single_none.dim.expected new file mode 100644 index 0000000..647dfa9 --- /dev/null +++ b/dim/spec/test_input/verification_methods/single_none.dim.expected @@ -0,0 +1,7 @@ +document: test_verification_methods + +ID_1: + verification_methods: none + +ID_2: + verification_methods: none diff --git a/dim/spec/test_input/verification_methods/verification_methods.dim b/dim/spec/test_input/verification_methods/verification_methods.dim new file mode 100644 index 0000000..8eb9af2 --- /dev/null +++ b/dim/spec/test_input/verification_methods/verification_methods.dim @@ -0,0 +1,21 @@ +module: verification_method_test + +ID_1: + text: > + Dim file should allow only verification_methods attribute, + but when test_setups method is called on the requirement object + it shall return the array that verification_methods attribute + mentions in the Dim file + +ID_2: + verification_methods: off_target, on_target + +ID_3: + verification_methods: off_target,off_target + +ID_4: + verification_methods: | + off_target,on_target,off_target,on_target + +ID_5: + test_setups: off_target, on_target, manual diff --git a/dim/spec/test_input/verification_methods/verification_methods.dim.expected b/dim/spec/test_input/verification_methods/verification_methods.dim.expected new file mode 100644 index 0000000..ce8ab01 --- /dev/null +++ b/dim/spec/test_input/verification_methods/verification_methods.dim.expected @@ -0,0 +1,18 @@ +document: verification_method_test + +ID_1: + text: Dim file should allow only verification_methods attribute, but when test_setups method is + called on the requirement object it shall return the array that verification_methods + attribute mentions in the Dim file + +ID_2: + verification_methods: off_target, on_target + +ID_3: + verification_methods: off_target + +ID_4: + verification_methods: off_target, on_target + +ID_5: + verification_methods: off_target, on_target, manual diff --git a/dim/spec/test_input/with_custom_attributes/Config.dim b/dim/spec/test_input/with_custom_attributes/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/attributes.dim b/dim/spec/test_input/with_custom_attributes/attributes.dim new file mode 100644 index 0000000..d625a8a --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/attributes.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/Config.dim b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/attributes.dim b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/attributes.dim new file mode 100644 index 0000000..86120bd --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/attributes.dim @@ -0,0 +1,14 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false +type: + type: text + default: '' + diff --git a/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/test_module.dim b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/attributes_file_with_standard_attributes/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/Config.dim b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/attributes.dim b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/attributes.dim new file mode 100644 index 0000000..c196d92 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/attributes.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: unclear + allowed: + - + - true + - false diff --git a/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/test_module.dim b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/default_not_from_allowed_values/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/duplicate_attributes/Config.dim b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/duplicate_attributes/attributes.dim b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/attributes.dim new file mode 100644 index 0000000..d625a8a --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/attributes.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/with_custom_attributes/duplicate_attributes/custom_attributes.dim b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/custom_attributes.dim new file mode 100644 index 0000000..bb7f895 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/custom_attributes.dim @@ -0,0 +1,15 @@ +color: + type: multi + default: green + allowed: + - green + - red + - blue + - yellow +necessary: + type: single + default: red + allowed: + - red + - green + - blue diff --git a/dim/spec/test_input/with_custom_attributes/duplicate_attributes/test_module.dim b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/test_module.dim new file mode 100644 index 0000000..2f1f35e --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/duplicate_attributes/test_module.dim @@ -0,0 +1,17 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: red + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + color: red + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/invalid_requirements/Config.dim b/dim/spec/test_input/with_custom_attributes/invalid_requirements/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/invalid_requirements/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/invalid_requirements/attributes.dim b/dim/spec/test_input/with_custom_attributes/invalid_requirements/attributes.dim new file mode 100644 index 0000000..d625a8a --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/invalid_requirements/attributes.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/with_custom_attributes/invalid_requirements/test_module.dim b/dim/spec/test_input/with_custom_attributes/invalid_requirements/test_module.dim new file mode 100644 index 0000000..755b398 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/invalid_requirements/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: lorem + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/Config.dim b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/Config.dim new file mode 100644 index 0000000..561e720 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/Config.dim @@ -0,0 +1,6 @@ +Config: + - originator: CompanyName + files: + - test_module.dim + category: module +Attributes: attributes.dim diff --git a/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/attributes.dim b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/attributes.dim new file mode 100644 index 0000000..d625a8a --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/attributes.dim @@ -0,0 +1,10 @@ +cluster: + type: text + default: '' +necessary: + type: single + default: '' + allowed: + - + - true + - false diff --git a/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/custom_attributes.dim b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/custom_attributes.dim new file mode 100644 index 0000000..6044ca6 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/custom_attributes.dim @@ -0,0 +1,8 @@ +color: + type: multi + default: green + allowed: + - green + - red + - blue + - yellow diff --git a/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/test_module.dim b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/test_module.dim new file mode 100644 index 0000000..e68698d --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/multiple_attribute_files/test_module.dim @@ -0,0 +1,17 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + color: red + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/output/csv/Requirements.csv b/dim/spec/test_input/with_custom_attributes/output/csv/Requirements.csv new file mode 100644 index 0000000..8acd7a8 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/output/csv/Requirements.csv @@ -0,0 +1,5 @@ +Sep=, +id,module_name,originator,type,text,verification_criteria,feature,change_request,tags,asil,cal,developer,tester,test_setups,status,review_status,comment,miscellaneous,sources,refs,cluster,necessary +"test_id_1","test_module","CompanyName","requirement","First Test Requirement","","","","","not_set","not_set","CompanyName","CompanyName","off_target","invalid","accepted","","","","","1.6.5" +"test_id_2","test_module","CompanyName","requirement","Second Test Requirement","","","","covered","not_set","not_set","CompanyName","CompanyName","off_target","draft","accepted","","","","","","" +"test_id_3","test_module","CompanyName","requirement","Third Test Requirement","","","","","not_set","not_set","CompanyName","CompanyName","off_target","draft","unclear","","","","","","" diff --git a/dim/spec/test_input/with_custom_attributes/output/rst/Requirements.rst b/dim/spec/test_input/with_custom_attributes/output/rst/Requirements.rst new file mode 100644 index 0000000..1ca5f17 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/output/rst/Requirements.rst @@ -0,0 +1,41 @@ +:raw-html:`test_module` +======================= + +.. requirement:: test_id_1 + :category: module + :status: invalid + :review_status: accepted + :asil: not_set + :cal: not_set + :cluster: 1.6.5 + :necessary: false + :developer: CompanyName + :tester: CompanyName + :test_setups: off_target + + :raw-html:`First Test Requirement` + +.. requirement:: test_id_2 + :category: module + :status: draft + :review_status: accepted + :asil: not_set + :cal: not_set + :tags: covered + :developer: CompanyName + :tester: CompanyName + :test_setups: off_target + + :raw-html:`Second Test Requirement` + +.. requirement:: test_id_3 + :category: module + :status: draft + :review_status: unclear + :asil: not_set + :cal: not_set + :developer: CompanyName + :tester: CompanyName + :test_setups: off_target + + :raw-html:`Third Test Requirement` diff --git a/dim/spec/test_input/with_custom_attributes/reference_from_parent/test_module.dim b/dim/spec/test_input/with_custom_attributes/reference_from_parent/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/reference_from_parent/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/test_input/with_custom_attributes/test_module.dim b/dim/spec/test_input/with_custom_attributes/test_module.dim new file mode 100644 index 0000000..c7078c0 --- /dev/null +++ b/dim/spec/test_input/with_custom_attributes/test_module.dim @@ -0,0 +1,16 @@ +module: test_module + +test_id_1: + text: First Test Requirement + status: invalid + cluster: 1.6.5 + necessary: false + +test_id_2: + text: Second Test Requirement + review_status: accepted + tags: covered + +test_id_3: + text: Third Test Requirement + review_status: unclear diff --git a/dim/spec/zzz_dummy_spec.rb b/dim/spec/zzz_dummy_spec.rb new file mode 100644 index 0000000..8aba5ba --- /dev/null +++ b/dim/spec/zzz_dummy_spec.rb @@ -0,0 +1,9 @@ +require_relative 'framework/helper' + +module Dim + describe 'LastTestReached' do + it 'done', doc_refs: ['IGNORE'] do + # do nothing + end + end +end diff --git a/dim/version.txt b/dim/version.txt new file mode 100644 index 0000000..7ec1d6d --- /dev/null +++ b/dim/version.txt @@ -0,0 +1 @@ +2.1.0 diff --git a/documentation/.gitignore b/documentation/.gitignore new file mode 100644 index 0000000..a9a1de9 --- /dev/null +++ b/documentation/.gitignore @@ -0,0 +1,2 @@ +build +footer.yaml diff --git a/documentation/Makefile b/documentation/Makefile new file mode 100644 index 0000000..eda1088 --- /dev/null +++ b/documentation/Makefile @@ -0,0 +1,22 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) + +dist: Makefile + @ruby footer.rb + @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) + + @for tool in dox_style dox_util dox_trace dim ; do \ + ruby ../$$tool/documentation/footer.rb ; \ + $(MAKE) -C ../$$tool/documentation html ; \ + cp -r ../$$tool/documentation/build/html build/html/$$tool ; \ + done diff --git a/documentation/footer.rb b/documentation/footer.rb new file mode 100644 index 0000000..3910585 --- /dev/null +++ b/documentation/footer.rb @@ -0,0 +1,24 @@ +require 'time' +require 'yaml' + +$stdout.sync = true + +def parseTime(time) + # input e.g.: 2022-12-24 11:59:59 +0100 + DateTime.parse(time).new_offset(0).strftime("%Y-%m-%d %H:%M:%S") +end + +data = {} +file_dir = File.dirname(__FILE__) +Dir.chdir(file_dir) do + branch = `git branch --show-current`.strip + remote = `git remote get-url origin`.strip.gsub(/\/\/.*@/, '//') # assuming origin + folder = `git rev-parse --show-prefix`.strip.gsub(/\/$/, '') + time_sha1 = `git log -n 1 --pretty="format:%cd|%h" --date=iso -- . 2>&1`.split("|") + time = parseTime(time_sha1[0]) + sha1 = time_sha1[1] + + data["."] = "Based on #{remote}, folder #{folder}, from #{time}, commit #{sha1}." +end + +File.write(file_dir + "/footer.yaml", data.to_yaml) diff --git a/documentation/requirements.txt b/documentation/requirements.txt new file mode 100644 index 0000000..d02595c --- /dev/null +++ b/documentation/requirements.txt @@ -0,0 +1,9 @@ +Sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinx-copybutton==0.5.2 +sphinxcontrib-jquery==4.1 +Pygments==2.17.2 +docutils==0.20.1 +PyYAML==6.0.1 +packaging==21.3 ; python_version < "3.11" +packaging==23.2 ; python_version >= "3.11" diff --git a/documentation/source/conf.py b/documentation/source/conf.py new file mode 100644 index 0000000..34fd9ee --- /dev/null +++ b/documentation/source/conf.py @@ -0,0 +1,21 @@ +import sys +from pathlib import Path +from datetime import datetime + +EXTENSION_ROOT = Path("../..") +sys.path = [str(path.resolve()) for path in EXTENSION_ROOT.glob("dox_*")] + sys.path + +project = "Dox" +author = "Accenture" +copyright = ( + f"{datetime.now().year} Accenture. All rights reserved. " + f"Accenture proprietary and confidential material" +) + +version = "1.0.0" + +html_context = {"document_status_default": "Released", "data_classification_default": None} + +extensions = ["sphinxcontrib.jquery", "sphinx.ext.extlinks", "sphinx.ext.todo", "dox_style"] + +dox_style_footer = "footer.yaml" diff --git a/documentation/source/index.rst b/documentation/source/index.rst new file mode 100644 index 0000000..183db4c --- /dev/null +++ b/documentation/source/index.rst @@ -0,0 +1,41 @@ +Introduction +============ + +Dox supports software developers to write **requirements**, **architecture** and **software design** +for their projects. All specification elements can be linked to each other and to source code to get +a full **traceability**. + +Dox is the combination of the stand-alone Ruby gem **dim** and the three Python extensions for +`Sphinx `_ **dox_style**, **dox_util** and **dox_trace**. + +Overview +======== + +For the documentations of the individual tools, please click on the links below. + +.. list-table:: + :header-rows: 1 + + * - Tool Name + - Description + * - `dox_style `_ + - Provides a default configuration for Sphinx documentations. + It also checks several style conventions. + * - `dox_util `_ + - Collection of small convenience-features for Sphinx documentations. + * - `dox_trace `_ + - Provides specification directives to achieve traceability in Sphinx documentations. + * - `dim `_ + - A light-weight requirements tool based on YAML. + +Changelog +========= + +See https://github.com/esrlabs/dox/blob/master/CHANGELOG.md. + +Contributing +============ + +Contributions are welcome, please create pull requests! If you want to actively develop these tools, +please contact the owners of https://github.com/esrlabs/dox. + diff --git a/dox_style/LICENSE b/dox_style/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/dox_style/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/dox_style/MANIFEST.in b/dox_style/MANIFEST.in new file mode 100644 index 0000000..b6ed0b5 --- /dev/null +++ b/dox_style/MANIFEST.in @@ -0,0 +1,2 @@ +exclude tests/* +exclude MANIFEST.in diff --git a/dox_style/Makefile b/dox_style/Makefile new file mode 100644 index 0000000..0bcbeb7 --- /dev/null +++ b/dox_style/Makefile @@ -0,0 +1,2 @@ +unittest: + python -m unittest diff --git a/dox_style/README.md b/dox_style/README.md new file mode 100644 index 0000000..ad75ab6 --- /dev/null +++ b/dox_style/README.md @@ -0,0 +1,4 @@ +# Overview + +dox_style provides a default configuration for Sphinx documentations. +It also checks several style conventions. diff --git a/dox_style/documentation/.gitignore b/dox_style/documentation/.gitignore new file mode 100644 index 0000000..a9a1de9 --- /dev/null +++ b/dox_style/documentation/.gitignore @@ -0,0 +1,2 @@ +build +footer.yaml diff --git a/dox_style/documentation/Makefile b/dox_style/documentation/Makefile new file mode 100644 index 0000000..87a79a1 --- /dev/null +++ b/dox_style/documentation/Makefile @@ -0,0 +1,12 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_style/documentation/footer.rb b/dox_style/documentation/footer.rb new file mode 100644 index 0000000..8317ef1 --- /dev/null +++ b/dox_style/documentation/footer.rb @@ -0,0 +1,24 @@ +require 'time' +require 'yaml' + +$stdout.sync = true + +def parseTime(time) + # input e.g.: 2022-12-24 11:59:59 +0100 + DateTime.parse(time).new_offset(0).strftime("%Y-%m-%d %H:%M:%S") +end + +data = {} +file_dir = File.dirname(__FILE__) +Dir.chdir(file_dir + "/..") do + branch = `git branch --show-current`.strip + remote = `git remote get-url origin`.strip.gsub(/\/\/.*@/, '//') # assuming origin + folder = `git rev-parse --show-prefix`.strip.gsub(/\/$/, '') + time_sha1 = `git log -n 1 --pretty="format:%cd|%h" --date=iso -- . 2>&1`.split("|") + time = parseTime(time_sha1[0]) + sha1 = time_sha1[1] + + data["."] = "Based on #{remote}, folder #{folder}, from #{time}, commit #{sha1}." +end + +File.write(file_dir + "/footer.yaml", data.to_yaml) diff --git a/dox_style/documentation/requirements.txt b/dox_style/documentation/requirements.txt new file mode 100644 index 0000000..d02595c --- /dev/null +++ b/dox_style/documentation/requirements.txt @@ -0,0 +1,9 @@ +Sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinx-copybutton==0.5.2 +sphinxcontrib-jquery==4.1 +Pygments==2.17.2 +docutils==0.20.1 +PyYAML==6.0.1 +packaging==21.3 ; python_version < "3.11" +packaging==23.2 ; python_version >= "3.11" diff --git a/dox_style/documentation/source/conf.py b/dox_style/documentation/source/conf.py new file mode 100644 index 0000000..2339a76 --- /dev/null +++ b/dox_style/documentation/source/conf.py @@ -0,0 +1,25 @@ +import sys +from pathlib import Path +from datetime import datetime + +EXTENSION_ROOT = Path("../../..") +sys.path = [str(path.resolve()) for path in EXTENSION_ROOT.glob("dox_*")] + sys.path + +project = "dox_style" +author = "Accenture" +copyright = ( + f"{datetime.now().year} Accenture. All rights reserved. " + f"Accenture proprietary and confidential material" +) + +global __version__ +exec(open(f"../../{project}/version.py", "r").read(), globals()) +version = __version__ + +html_context = {"document_status_default": "Released", "data_classification_default": None} + +extensions = [ + "sphinxcontrib.jquery", + "dox_style", + "dox_util", +] diff --git a/dox_style/documentation/source/index.rst b/dox_style/documentation/source/index.rst new file mode 100644 index 0000000..058ce39 --- /dev/null +++ b/dox_style/documentation/source/index.rst @@ -0,0 +1,19 @@ +dox_style +========= + +This extension provides a standard configuration and theme enhancements for Sphinx documentations. +It also checks several style conventions. + +.. toctree:: + :maxdepth: 2 + :caption: User Documentation + + pages/user/config + pages/user/checks + +.. toctree:: + :maxdepth: 1 + :caption: Appendix + + pages/appendix/changelog + pages/appendix/extending diff --git a/dox_style/documentation/source/pages/appendix/changelog.rst b/dox_style/documentation/source/pages/appendix/changelog.rst new file mode 100644 index 0000000..95565bb --- /dev/null +++ b/dox_style/documentation/source/pages/appendix/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +0.2.0 +----- + +October 23, 2024 + +- Initial public release. diff --git a/dox_style/documentation/source/pages/appendix/extending.rst b/dox_style/documentation/source/pages/appendix/extending.rst new file mode 100644 index 0000000..9ecaeca --- /dev/null +++ b/dox_style/documentation/source/pages/appendix/extending.rst @@ -0,0 +1,13 @@ +Extending Checks +================ + +.. note:: + + This is a for maintainers of this extension. + +To extend the checks, inherit from the ``Check`` class and create an according ``Finding``. +Have a look at ``dox_style/checks/dummy.py`` for an easy example. + +Finally you need to register your check in the ``dox_style/checks/main.py`` by adding it to the +``all_checks`` dictionary. The keys of this dictionary are used to generate the corresponding +configuration options for ``conf.py``. diff --git a/dox_style/documentation/source/pages/user/checks.rst b/dox_style/documentation/source/pages/user/checks.rst new file mode 100644 index 0000000..be01403 --- /dev/null +++ b/dox_style/documentation/source/pages/user/checks.rst @@ -0,0 +1,102 @@ +Style Checks +============ + +This extension is capable of checking several style rules in configurable manner and hooks itself +up into the regular Sphinx build process. It's triggered by Sphinx as soon as all documents have +been discovered and filtered. Hence, only changed documents will be checked. + +Built-In Checks +--------------- + +The following checks are included and enabled by default: + +- - Whitespaces + + - ``trailing_whitespaces`` Trailing whitespaces are not allowed. + +- - Heading Syntax + + - ``heading_levels`` Enforces the style of heading underline characters. + - ``underline_length`` Headline underline length must match the length of the headline itself. + +- - Top-Level Headings + + - ``top_level_heading`` All documents must have a top-level heading. + - ``top_level_length`` Top-level heading must not exceed a configurable maximum length. + - ``top_level_modulename`` The top-level heading in *index.rst* of modules must start with the + module name. + - ``top_level_casing`` Module name in top-level heading must match the module name + in terms of capitalization. + +- - Include Directives + + - ``include_rst`` Includes must not point to an ``*.rst`` file + +Usage +----- + +To use the dox_style extension just register it in ``conf.py``. + +Configuration +------------- + +To configure the checks, specify the ``stylecheck`` variable in ``conf.py``. +Only non-default values need to be specified. + +The full list of options including defaults can be obtained by running + +.. code-block:: shell + + python -m dox_style + +from within the extension repository. + +Global Options +++++++++++++++ + ++ Excluding files from all checks: + + .. code-block:: py + + 'exclude': [] # default: [] + ++ Defining how many lines of context above/below the finding are show + + .. code-block:: py + + 'excerpt': 4 # default: 2 + +Check-Specific Options +++++++++++++++++++++++ + +Each check has its own key in the ``stylecheck`` variable and features at least the following +options for globally disabling this check and to exclude certain files from this particular check: + +.. code-block:: py + + 'trailing_whitespaces': {'enabled': True, 'exclude': []} + +All checks are enabled by default and their exclusion list is empty. + +Examples +-------- + +This is an example configuration: + +.. code-block:: py + + stylecheck = { + 'exclude': ['**/gptp/**'], + 'excerpt': 2, + 'trailing_whitespaces': {'exclude': ['**/3rdparty/**']}, + 'top_level_length': {'limit': 40}, + 'top_level_modulename': {'enabled': False} + } + +To disable all checks, use this configuration: + +.. code-block:: py + + stylecheck = { + 'exclude': ['*'], + } diff --git a/dox_style/documentation/source/pages/user/config.rst b/dox_style/documentation/source/pages/user/config.rst new file mode 100644 index 0000000..a5cb2f4 --- /dev/null +++ b/dox_style/documentation/source/pages/user/config.rst @@ -0,0 +1,58 @@ +Configuration +============= + +This extension **pre-configures** the Sphinx workspace with default settings and provides +common **styles** for HTML and LaTeX output. It significantly reduces copy/paste between different +Sphinx configuration files and harmonizes the look and feel of documentations. + +The following default configuration can be overwritten (if really needed!) by adding a file +*extend_conf.py* next to *conf.py*. This file must provide a function +*def extend_conf(config: dict)*. The loading order of the configurations is *conf.py*, then +this extension and finally *extend_conf.py*. + +Common +------ + +- Adds a check for duplicate labels, which does not work reliable in parallel builds, see also + https://github.com/sphinx-doc/sphinx/issues/4459 +- Enables PlantUML +- Makes glossary case insensitive + +HTML +---- + +- Sets `Read the Docs `_ as theme and changes + some default settings +- Makes the **navigation bar** in HTML output a little bit wider +- Allows up to six **navigation levels** in the navigation bar +- Makes navigation bar **sticky** +- **Wraps** text in tables by default +- Adds a small superscripted icon after **external links** +- Hides **previous/next** page buttons +- Removes the **Generated with Sphinx** text from the footer +- Adds the build date to the page footer +- Adds the build type (unofficial/offical) to the page footer +- Adds an optional :ref:`sphinx_footer_string` to the page footer +- Adds :ref:`sphinx_data_classification` +- Adds :ref:`sphinx_document_status` +- Adds :ref:`sphinx_text_colors` +- Adds :ref:`sphinx_table_colors` +- Adds **raw-html** role +- Removes the **integrity-check** for script files. |br| + This prevents problems with *cross-origin resource sharing* e.g. when trying to load jQuery. +- Replaces style for **download** role (e.g. download :download:`this page `) + +.. toctree:: + :maxdepth: 1 + :hidden: + + config/data_classification + config/document_status + config/text_colors + config/table_colors + config/footer_string + +LaTeX +----- + +- Configures LaTeX exporter to handle special **unicode characters** diff --git a/dox_style/documentation/source/pages/user/config/data_classification.rst b/dox_style/documentation/source/pages/user/config/data_classification.rst new file mode 100644 index 0000000..705c896 --- /dev/null +++ b/dox_style/documentation/source/pages/user/config/data_classification.rst @@ -0,0 +1,55 @@ +.. _sphinx_data_classification: + +Data Classification +=================== + +The default *data classification* is **Confidential** if not specified otherwise in ``conf.py`` +like this: + +.. code-block:: python + + html_context = {"data_classification_default": "Restricted"} + +To overwrite the classification of a document add the following directive at the top of the +rst-file: + +.. code-block:: rst + + :data_classification: + +** can be one of the following values: + +.. list-table:: + :widths: 20 80 + + * - .. rst-class:: header-label data-classification-restricted + + Restricted + - Sensitive information that should not be shared beyond those that need to know. + * - .. rst-class:: header-label data-classification-highlyconfidential + + Highly Confidential + - Sensitive Accenture, client, or customer personal data that can only be shared with a + specific business need. + * - .. rst-class:: header-label data-classification-confidential + + Confidential + - Sensitive data intended only to be shared internally across Accenture, or with external + parties if there is a specific business need. + * - .. rst-class:: header-label data-classification-unrestricted + + Unrestricted + - Non-sensitive information that is intended to be generally available to the public. + * - *None* + - *The data classification is hidden for the complete documentation.* + +Example: + +.. code-block:: rst + + :data_classification: Unrestricted + + Some Title + ========== + + Some text... diff --git a/dox_style/documentation/source/pages/user/config/document_status.rst b/dox_style/documentation/source/pages/user/config/document_status.rst new file mode 100644 index 0000000..da52bb7 --- /dev/null +++ b/dox_style/documentation/source/pages/user/config/document_status.rst @@ -0,0 +1,80 @@ +.. _sphinx_document_status: + +Document Status +=============== + +Lifecycle Model +--------------- + +Documents like guidelines or project documentations have a lifecycle. +This extension provides four different states for a Sphinx document: + +.. list-table:: + :widths: 8 92 + + * - .. rst-class:: header-label document-status-created + + Created + - The document is in a very early stage, incomplete and potentially includes wrong + information. + * - .. rst-class:: header-label document-status-draft + + Draft + - The document was reviewed and is already in a good shape. + Some parts may still be missing but the existing information is reliable. + * - .. rst-class:: header-label document-status-verified + + Verified + - The document is complete and trustworthy. No review findings are open. + It was also checked regarding formal aspects. + * - .. rst-class:: header-label document-status-released + + Released + - The document is approved and valid. + +Usually a document lifecycle also consists of a status like *Under Review*, but if pull requests +are reviewed within a review tool before being merged, this status is not explicitly needed for +published Sphinx files. + +The status can be changed at any time. But every status change should be reviewed within a review +tool before being merged. This also applies when deleting the document. + +A typical lifecycle looks like this: + +.. image:: document_status/document_lifecycle.drawio.png + :scale: 100% + :align: center + +Setting a State +--------------- + +To enable the documentation status label, set a default value in ``conf.py`` like this: + +.. code-block:: python + + html_context = {"document_status_default": "Draft"} + +To overwrite the status of a document add the following directive at the top of the rst-file: + +.. code-block:: rst + + :document_status: + +Example: + +.. code-block:: rst + + :document_status: Released + + Some Title + ========== + + Some text... + +Aliases +------- + +The following states are mapped automatically when using in RST files: + +- *Raw* --> *Created* +- *Valid* --> *Released* diff --git a/dox_style/documentation/source/pages/user/config/document_status/document_lifecycle.drawio.png b/dox_style/documentation/source/pages/user/config/document_status/document_lifecycle.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..e47a659e71bc8f4413f9ba5d7ca2f69e89190a5c GIT binary patch literal 19375 zcmeFZXH-;8uqZl!f&@YGAW;+qi9-&OGeeF85@*P9$Vsw-Ln{M{jF8J5vTOSzdNdpo>Y@+QH1x!v(li z(E>gooIo?TByb0G@bUb;_2lDW23jPLNIP>~b2!u*z$?qk&Ckxw2Q)K5<+YTR7`UW> zdpm1ebKoLpj<9w7GepYD+0hkRcm#v*8OdX~usR6XeTLC@#z`wbv z2cN!;mbV3;sscig7b$J3ZsR2Xr-z4!m(SBiP8&cVsR;A1MJPB)!*vi+rg~a#Qi2j1 zdOS8}>W)yjx`c|mrM`zcFH%p#M#;m~6e16kBBr2d|m7r@01~ho+gbq!W*dixtw$OctuI#H+z) z?cgE(N5dqwRrF;fOc7EDcWXH(6&@WkxPz0Oyp!G^N<2K(kZ@fYM=K?mp0%f{roNYr zlqpO=UrN?ZS3^U`TaTAt%}z_!SwYIx62h&h;VR3oX)Ozk)Y7n&wbMjuD9I?hXu&+7 zHn!d}NG(21CoW4nc>#Gd2~~u=p1Ontj{*<3y`G|#hPpe16Tz#ZqvzpTG*<>WVM_{)yPCi>3h?lmEG7kWZ)YJ4rKs}Ls zN~)5ae~_!lJ9_;g)!Gy3;o&H&pkhauygmJm3+Q9W( zZB?AStQ;In6;u@=DvpA-QV<1IGaU^FH7heG7h739Spj`%IjFapvkDido3e|GwwtC6 zln3c8V{2!x$j_zbBCDzI&L;r8TGq_j4X(lEVC%xor>rB#spqQ1&9CBSE6uCprK1bi zQgVRWKxK5`f*NYP&MF$tz*Wvk%9YbX(8(1Ffw}W*sObV&RG?m_=DM~Hx;BC^FAFHp zB53L&BdN^~;RF`NTAA7+B?Q#rT5dMp_F8Z)#Xr!B>NbLM9yWT` zdVIDTR-Q09Co34Yw}YG)x1*gZ#NAro38@D)_W)E}7OJc-sqQT8;K661=***QVddzo zD6a-nR&a+Y%ea~9+X*-;YMASrDd@PXTf4YPc&l+qY3NJ4>v_3ydumEKNT?v(q%3Vc z6wMSZxn1Sl?JS(tylh+nt0L@Ff&1j zsTa4bsV2({xTXE`h!yJHDc>%Bd4}E0ASAJ>S7B3cuAU?0aFUBsXw;&&)+|M{B>A=jW_`H zuV3Squ_h5n1A*v33epl1X>l`yK;dul5=@GHlU}e}K4K@i;O5y;65f%XyCYVWR|6VG=i0A+1 z(Sj}zuM!NUyO`tsuVYzJQ&|5w1Q;n#hrx;>k{9*p|6lljfFdBL|AF=&>_k1Fh^l+B zgNEGyLBk(X;E}%nm4d)~T&-}{z@ILY|CL;TEZYCSkR=`qL5c<#qY2=M(|~Y6e%;TK zW11dzPg+>s2i^3f`^EbFeECHl?1|I*knJE$5hMnJ;hIncIMQ3QCTA>@n{(-X>~6<< z783Xo^aG3YQR^8f0pt8ptN-lM(3^hUUtHqH@`M3TL6P^7gaLOo@2Z>7>=YMFk9+9N z03V}lWdv1lDvxDk*iH?a~Bj4vhu^zb`7z1Y{7t;%1-f6%RdZ=D9+;x9F* zsE>G_4*G6Iph^7!_Z4KxF~^jKn_valQxOt>f7Wh#K^-vqD&f-rAwC5LQ4CtgB>+Y^ z9|M74tZ<8ezl=aj>I&_BK>VZC0yK(t&C({&;N#0_BJXbs$tTz_i~A8^g;$C`M9^B5 zjfQyH4iRreSc4o$|00w62btktWRKu9)(XYv_f<)J&_yL4oUh{!Z9|ArkKf0+z4eb|r1He?Lz` zgHV_N;D*vN<_+JqwWK!hCH~W?^75l87e)}I6|Te?`~bfj`LSf_^bvK&{~h^%ri9Qr z>CisRA^|;Zr4tG=0dz&Kj*zhUA9Z-=(36yeb_DjsZRG%c#WkS^i3J#dIO=Y0r9hVN zuu=)J+XI#vbtOC}S@8bR;%{GGtXg2M^of%NT&k!;ygk%hm3%_+unwhOKXGytg0}+N z7H#*GUh5xd!ub!ts)chMI)ZY9u{j^Ek%Lqo5p(4by+P|xE)O~^*9C_hlanF5-Lz5t zc%7MO!T}*5cw`RzsQ&GOH_zP9Vtx$lkV)iiJD|%1W&%F~mhfEPM>}aLA%n5e2Z49d zecd4q`G*xF!+0ldj4;zIA6EcDSXJNolUfcoe;!p-}c%($hp(HAgbt>}aktcK*0qzu){-gkEp*Cvh5% zzG!;!^)qNGHD)ZU!l^TH?zms0%GoWwd5WdDI;v0Enb6FyrE|fM4oaaRsFXkMjQDu~ z2n|vL5YlKt%s8OfU!z(HgBX0K%ln3>i6_kEscFPC#d=jaw}HyZkPS6%ixuk8-Hb{A z2r{UqAhwJetW^~l30amYl7}4Ya!t7Zz9h9{KQp<&d`@F%xN~?_m0LbtA?y!<3c8qb zss89owyvLLq~l#vOHyL4%I`beV-6>$IUqm^B(@2*d>GY@>|V}gaPta@@fny zaVx8bE^9$~gYvf%ZGum|9V5$#ojbvKR) zsW*}I@Qvsi{k^oRW$TwB!tzogUMPN=Z~+TtdX=5lvgkE zg{h;@$abDc$`V%n&YWf>6>UFAe4s@AQSODq{DIx=RHH!J1B!^M%_7>5jwdAvc z^kgE*F?HgEpKqgYqHSdIj|r_4GYcn^UN?D-FNi&?c9CXvV$6P^cQ@mu#<{-)vy8%G;~fnBrmMhYvVoS`*?#kn>Zs2| zWW($AxC;gp^B!8fW{3@x6TyGE>yY-`*)6`iFw@GW67xK zDsaRIT#r$6x`5(FQC2=po{}M6U98#Y6mF-v){H5`9QCD2)P|15@Ws{d^+1NFie)j)L$O_X-Yg1l-J1?b_d)G_T*Gv_>0*zM z|0-Jf?BtPO%kLP{SC4B%7jhj5v%C8vE!d$Jj!qCeU7TLC1qm?`i zW9$nM#Oyy&Adbbp%`YH`@eKQ{y7{m~UBCFp`8=7PPUi`^_%8yno+n2{=CJ&|kEzy0 z&c}RBcs=dS#&m6BKbxeU8D;MhlRqd?pD}M--DKnXIrK-9+OzqW`oqPl{ePDsaUrIy za}9|zgwqwIcg6%!-(ih0n-rXP+gQstYn8#@h6&)B<5_q{tI0OjzXG4zk5mD~LN@0JgnY zC|VDixWCF!riYt-cOfg5xY#0NU?VIN+f14afleWXr3Q=KYL!QqFoQ6DfVhGf)Zx1$ zWNmI(0d4jxCG~ic9;pJe)6NIMpoJl{3Xy-nj{XeCqZS9ED~zYu_hPz|#8E?Nah?&7 z@HgM^ma^)YU=1YdHFlH%#@jp^C^)M@#M$xh|gCvOOq(KwNw4_nAyR}M27;>bj>QxsrDo@6oq4`$r&XF#GN?c3e@>|rU;|e z5R@?%L!k%I!}{N|LjwmE>0l@9o%L8O-BnpMy%{U&-lYcM`g*`Z0e}<1k|laT9{~xB z{Di^e%Z6f-+f5ZXM3$;J_t29eRAkzG{K(0CQjcO5qaMqkkl%y2S*?>YVgqyTu`=w0 z1o40C7idch4`zU7HneT{5ukXrSBz}Q_LchaN(jgh)UMjXHx1XdH?Z1aiVqzKEPbaD ziLHi}b2}>TR-B^uxbx>`_Z|ILTSsZfR~Cg0n7-F7rSCwGJ_cH!!+p4msr}M?v{*6r z+65>ZH1XB_znEKDn6b|=Mcu1*M$^b zUafr`y`JmLg4y{ej3|=CpzTnWp>qr0_p9-r`{jlC9#X9CRo=ZM&Ua;|ci4PVCU)k* zP9mxv6!)o!us$yoYfVV(g~gukCo)leJmvyhk)>ubgfSYJ6f3(K^Kew)H?cjrX#~WZ z*Khf3$-+aV`L_@9^K>|Ie^C!la;3!SGDaq@ma?CY4Wolf?Nh_7$H4?XkB<`SDI9Y* zirT9<*vSx8rrN}aXRh*gd3mmdYA_ zJRgtC(?nD~=&|*E=0JMR3(;9v>Y&t3H1SlQY|&8o;M+L*R?ks)<(M}0=%>uhVXCIH z>2}V8>4?m61d4JEc9Dt(_J_#|2acUJbbBBc;=5Q;_^vDrb2!(0l$-}{)sMX{*Tr!1 zmG<8$x;fq^=n<8FRh0BKv{J8m_pN!a?TM7K=Q0EK4OSATM_r_t7?tqRBqd*TF)F6l`6P9tPb1W-!4a9@R|Iq!&nFx}ob)r~;AZA*)CJE^Xs&Dd6k*ku*mYbmdH za*=0sDl_SDP?f~MUwJT_O-J+*i#iE=2JEC{!@PH)6MQuNI|gH|<%QH~jls_a4UpzN zb!TAG2oZ5Cr`EI#duPArv(0X+f;OVxGN6pk_)LpSbo$?Z=}Q?$bVeAZ4|-CaCoTpr z=FN;#v3-%p8|GS&nqYmo=46slk6n;bW^-@v`8vtaV)EUo&*A6EFpt>;VO7poPS9d% zG45BxB9sA_7e=Qm6*SL9kDIFWPM-`uE3zMuuQfH8<^FvIO|?BtpL0@K7}iisd_b}G z(RamV^?rqBe_&3>=wKzx3985#%}eVUCp6#Exzo;V6dLYTDoE<_s#@Gha)1KY20uN z5Pmi@$bZJ(oo?5jNyGP)zhYypyP7cxIe25?CV1>P*z0+8F~KxG+?_OLHI4l|>BDrL zje#!K*A^v|rfQF&bFWb<0#!K7__bOZ<bV!^J2R zw51%W?x)RUU(=G9V$Q>EFFyJLYwpfX!o62sWDaNcjgpyB(tMsVQ-EbP<-_Bhp=+6s zUw$frxmD_(9IxzRxJ;TAu38yrVQq+|1*is|Jm2cc$cXrT*C(D8Hc~wt^(E0}=(>nF z&N5Mi4U59kEPMO?+KZo_>ybB~%){0kK;N_{-uq#0&7f;AutC0&t>W1%XpZ=hASWlaV6u66~n;0I1|u2lh-7pHxGbEf^$Vjn3uJkuIF zG%Ik5BUrb3xD;S}F3Y2QXdW&$j5Vcb-cfA7`AkEa@THW<(rgtpk0;!F{aDYM#tP?f zts9f<6tLLRHCApz{rH=C_W!K3}a%JKQlh9^V zuP?>MMV_v~zTD|}u#i7%N4*-U)IBXZ%e1M22i7Z8U|+Z0FsNX?4Sj*?QL(M#TeVc( zM@2dbdfI7-@wP;EP8}p_eG=%yYtq(8B=ZHxO(BykPel5Y}uI}><6Y=Q#h>$#lV>-dzWfg`0jU_d^Fgxy3 zMGb92kLw|wyR9842tqby+-{gZCV-oeezHlmg++CK_@OY>c{d7zZ`Z7WV>tn znnr`SuULkzy@kH$`A(tXfQ5Zz9BUjl|x0$xY#xCaUt< zGT(d}i?=JpaH{1TH<6M;R)k zt$YiZ{O(8L?xm<-9^zi#gw~=|wTx}cXO~X&dg6ROX~dvJ_ESdfx=H2OC3ytn>-DP?PJT9m zjauxyz0b6XjW%j#v4^kq%P)=hW|*#!dM*!T>uP1_qslW9m}}qBE@u}~he>?tC8d~b zvKfCj^UB)G#*fNy=Eft}VufJh$Eh;TjyXrU+jvn7SNeWF-aZF9yXQNwSEp3di{X~f$%`rP zX)P|B_lj3kW!(}LftxNLW4GLv-Fr{jaAzd8@M?lkCj0B>w-G-CHcg1hTG&&V&qTFk-AQ6uPX?>{5P?#?(6N*%MgoCBg1XEBB{uelBX>yP8fe<3^@_DE6-+s~yz(bRLf;FZM(#DoJ}$ z7tOel;O%>o4ui3y4EjKs>^?u!gfD`D?323vg$-V`rE;(sf88gnd1XbCiq(-RawTJ% z#w~K;F;4on3uzura^EuV>9&cyt^DoyE%UO>_bbjr$FV0j&t4gH!R`mtwK^K)sWZrc zR%Z~C1Adca$;ZRAIv}G>#$F^t(QjA=vNcVh3pc(p&idoT!YPDb_--Xgp6rR zJyzOC$8F+DuJGmA=nF1YQY#UViB(G0!WQWlC?>sIM-F)~S8mA?{j)?PM$`2JhV!q~ zl6z?`%IB-|7TVYMX5LaT#pZ`q-Px-lm+u?83}llc^vxWvPNRF$QS@wiqDOHQZ)K=q zTX)aXs2ik1`4-|x<|6=|8~F&v62WV)=dQyc(Z<;U1<+niSgs=dtvMA?46m! zyuk7KLh?SlZVxsGdg!v@s^mkV?TaWQkg^- zcrDFv&LC$!QN+AoR=^l6I~CF#wbrRyK26FIX!`@P(Ep4rE$IIJlUwwT(xnX!*#s0Oh)+}U^V9vwCHdmP#L3<pth?mLA!G6R+Z|O(PivV)`2z_K=%vjJ^T2IP1l+`JQh@ zAi>G?`y`0vy5S2JDQLKJFdmV@Lb_4I-RKu3h2a;X%yQWq7G9e-y?zdiBYr9P zP^VtBM&nzYOnvenW|)^EIwQOXO0O(@E79X$nrM=v$d9uMA(RJuurWSiTxZD za0`tl&qZJhu^($0b20({Q|@TavG2hTFREyy#$kg*^A*59?sg%W84AIp+d=6LRmG|I zz7%W{sk8X9e^|VR;qX08T8Q$Mhz;|@bZOLz=^gUQ z>MYT!Gl^{Pb1vxpjUI{;*UYLtx3Fi70sXW!^O?apu7V*>t^s5wYxpAjD|_!*_MHvX zHwB#Y>{{6IKtG>8r3bcgX=!eblSa)xfzK>F`(}m6WOiaA`||-Cf3UQHDg*bX3y}u| zmX9}?aMaK;Z!Bq;pSvbS#92G2a|Sam-EXuR6V)tZJSo5vKyI|OsOTh~FsVkw-fm^n zSEolbhsN}5=vzox|PV<7cub+x`s zToK}XjB_&+IonXQy1t*i{;C!<5cXbPvwL-ZU%M-zv2rJ^jIHhR^m63|N`PzPD4u@p z*MorPpf^+$$Kq|Ya}T%Kd(?=|#|=Mb$QsxvbaydtZSQxQz)O!Ex-%9)Dd4N#gSM{n z$GL59SOB}&L#91G2vI0>>~qZF3u4o>fwN9g%FX&xU_mD2;y(vPRo)yA_&1JlG+jmn z!0k@*8PhHjMYf%PN^OwSjgO?XstO_kJEwG;3>wb!d~LGt;=3)26wa{Dpb{z}Z!RtL z%C0Le@i{a@R(QT$LV4gywQZCZyiT{lXUr|V?`2_X=;C<{oB+Umg@}td`d0`t3C%ol!OBibPRy#ALh5wc4jAUz8dZ zPM2fX9~+Q(nX!W3m@IZ!iB38Td7qNEbtV~O?q6l;D_0&E=wv^K$et~p7?IK#=>?xT zZoaRMu5rWWR{QiHwE)WzE~s|rOdv2R1CQb~CG2S<=XtsIo8>g1O053I>Rn0h)_rj` zO}|zYK2b-E>B5y><+C#LF2^UD)kexxmeiXoDqi~AR_U>QBMk0I8ahZsc7mN08J;ky z_O>jBwiiHS{NQr8m35skF2}4dzsYxTYErr8__SWO%wo-eKiqXo$|oD*a-A@tz63t~ zv}G{;?n}#fjf0YBE^J-{+84(htntBLZt@p(AS%Bh-YAiI{74k`X}>UXgDX$nLo@bG zz8H1US4^39`UPbLRJod&!A`NZt&iJ+;nX}~&3vRg@8AmpshQY0A0kA*8nU{?XucNA z#N6z2HFHyA3sK|sW!uVd*Tjs7)UIV~8L3j{C|IMbf7Psi)@<#u;W+1(C5ld3Gk&i` z#X}SG3=r?sna_OEuWiwv=1GvVUO3)&N5kk%g-Bi>(z)w1oLX5}7Jb!@d&3ywy=;QM zAQze4Y4$gMi3N_~a0uIUx=r-A-$9Yz6BT=Y?855C=xn-~)WgE}n>c(P%NmD4wpDF~ z$AW6~X$;P;1#F~*t(I!yAzxhWa9+d^s8DxsLm23*usmQVe>xTxQSe_ zWx$cmgHSpI6NvHaK8*|a-PnsdTm1BJ5@ADYF*P#0;>rUyziZ!XKRJ28;_Po2FwiB; zTlLdu(OZXct!w!6)3rCGqDJV@fV|25=7n>2k>Y(;xi$)p@>io;;M;YVy>XxX$) zKj+?vqO6*IrRB)y@fj0+v&h(OYyLdfG;*azQcv`aQd$Ru_^7xxJf>F=eoSIPzr zHQqq|Ql|Z=G?-!_y&O67aVaJ0^OeRedVwA-9!rrO_NHM~;!S+Pw#l3O^6Nr~^yG`3 zV~aFz{T-E#U;;?deZ3}H9F^f5a${@5k=*QJkNIhRt|0cy-Tf2b;e?ZY;(0c%#>5Ak{scZ{dyb0bj{mLtS=VWS_F%^)(go{+DjNChG0j-ESVX zvS)>_yH`~e!G17}xVi_Ie%Qb^)qr-qDk+s#BFi1Y%?I9EZBOgIq&PY4Llbpd39Ygp zZ{#FycJ)sl{Ys6Eo#?;ny4k z1ACf2!M}!S4tcW1%ygi}Y6>`ehfdzN(=}8EcGe=^Y0lsB>!=%D z>lhx!jmj`^-tOC?-X^%7RQ__jUSN;mE)$))NZ{e^j&z) zrUTxb8nGpJjH_OfT0U}yD@|TMJ7~p31m?SZB-JiEedzZO_B@Kyvx(yd}qvyR*HUg#GxletiGBF;`}uohvi4w9vx||JR}(J z=$SfB9c|o8!&A4*N5!r;Hvd7lU}|hWVLqq5Z6GA~>>;VY@4%?{GeYg*gCb>b-9k0O&VW8GzqX3VUWq`4{gs7LC-b-~U3KZm-nUqc!%dTfnDJS=&MQ3sJdCH-5 z>|HTCrM34}DKi40a+b@L*<%>^4-SC1SEb4EwBe|y_;KmAvF(*B-iX_C^VK*hZca=4 z4z$pqvuCK+pM&aKoR&V3@}4^;Q+nLIG``s?!RQnIXi5T^xHv>A&b8ds;iHYt3tH(N zhZrlIe^*tuk&fIImwPl^B^j}(b2!67O;`+MKHfyVI96>QdlMV0gC^TNIRtur#33{P zuvq4x#>v3%?VBRqq%lnl`A%Lw5Uqc%NvC>imc*Aq3fxOS;7f+O7L-^*FL8~|(W2$_ zX^i~6Vdr!gubeNPa>LJrMBlxM+2eWTb5petErnD2P@8jDT|Q!axU$lSG`NO4)+W4` zEZx5U>NCl!vFtJ%GnSy$4+h43MSG)13R>rNH|Mz#pJzRc-5FDnL;2_%#X5myJ zu%e*bga`9+V|RJ>@td!p)2Dkf!jTSEEVRS*A~KWSop9DK4i{VEcuACJBNcj)RX%Sz z1JpZV@@9w15)?zT63Y@;o&3Ltf zI3l49EIJ5h4KaJ11tj}0Ii2xBd;UHa0dk8IK2@gje3@Vqi~5vl)no!8V+)47&gg>S zediI^WJTeb`~>62{QC&x?B2C+v31pDq78Y+TG(;uf4E`Wvx~N`_MLbfQ6-wgcO9Y^ z`F1clCes9BVYU-0=1zuKcCq;ReB}x1-C}AXyLIG!3hb&T{ei&O8giI_@}O1!LxM95 z!X|lYgD2RiC`Smfp8}FUo1kI7E;y?`X4J{c2nb?YcxL!Bz@7v`gjN-ZF*Wd~`#|_M z%r2zg*`YJMjZyBLJI~}woA|51#G6-La3wm#CI}}2LJd}+dj}*YxkB)>I$uRv$Ei(6 z2C`}2`Yz0G6WK?3fv<@I6V`_{-Rg| zhN9ziJO(lgd(cUs;w5IL%U#$zf$eWfZR-lj9z3{;(?J5;&1X8 zs6)e#eD>&nWtO{!<%yOYds*W(-iQW1kACy4l0|6hWlmM(00!UlN3s=$P{#Ar3{h!C zh@A8J+rpfY=j=j1Uaoq)GSefRGzNVayQT{@%N~7qp~!?0zS6aB?@saIt#6BXkbjRy zs5~QXi!sqQt7~(eXeTi$fjm|5#q|eFDmf;V_7~JIC#i$;$t3hr_+7 z^yf(+Ls97A6+_!T`XCwqsq*wURrfciex?wzye?P`%l*q-9+ zK1Q);`xHW24R{#}4**Ar^@sG#8sR^q(;O*VC!&$u} zqQ3Jhl$_2)?0wau_@{IP8h1l|MLiz=8Z&@{-u^lMVAS{eRNcLsQBGkFZB*bM&6g~O z-rM@S%|iF{w`b(lg8t)eQtq=}MO;p|lF+zU9(bzuW{U? zu7;mXhTQ&P8pB83b$5vmYc+zX_|>;NBx<)xk?-H8CZV3Ytx!N2}92HEkS>k`sx- zZwX@Xe)rDJGKk*Hf}3&Rai(o1GWTIeghpF?DZzDDg^5ceRv*8>(dM>(=;HhTgyl?r zzP|ROX4angLy9vKEU9b3SU$k(t61x@L3GNOZYs5F=ozDpdU z_ZRkPcq*K-_v7`kUc-n~q?M!q%YIr%@e#v1#7+YxOp+&$nLFiSx=Y3&UYDx077N!m z#JUh{bLkACuvJp|;uV5t{m{ZL2=wtfiH~` zsAU3v0AC8J={IlwH+5|Hc>NprnAZh zNn5{|Q5vM7I^e7-(k}e!5R-^8+gL3E%7KfIz24u&z{TEvxcaKPJ@=91a^3V? zfR%e^wHmteBVc*`DPRy!IRl%x(~fcNa6{bbFi1$79<@4v7(fXwuB`O@fZh|@U#q22 zaL&C3Bsf6Bi1Y|?@e8zX8~VbPCDZj4lm;3B;Vo^#q#XdApr1MaB*6Wbh%^zUrG31O zYxLQmPj2So5#i%#U_29o0N3bfnV*cTDEjOu+Hh`+kkt3E$gb&*d;0^(0gg&Gus#+* zM9y`k5{Q@W`&BULdZ1ulXCm+0ss-eaeVdCz;)Q7q74SVyY9Y zKv&jQFHc;_fvU9g)q>TIfaT^5R@BNW%zLv7IZ%O>!->KGn}|gX0M1CJn^ugP78CDG z#1cYA+dU%10f<8c{1yT@#VP{8@k2h%8Dw()6+z~C3_B%n+VReaB3{Z3j}R^3=&Aj$ zU0;Ja=gt7%^qLAv@C`h0abiM(@&sXMqJ70~?U&%)~%{fLRLku5vt9FN?b@&bfUbMUF_fW)g znlXW_X(SdWQZS&tp+=@NqYcgq-#%{>;QA{vs&CN4azJZ>W`mdSTLb_?8~oo0?cIM& zIH;y)>In#_)n@=1LsUh$kaz*MpqE%CA|T~R!ivsCW3<@lZYqph=e3`GOj)ayzv*%A2 zHn}U7VasR{KwbKu1(e-nc6~@OaIq@Kc1FU0@f=+MSDZSa4Ri|X!8-H+8Ou)B5z^4& zn!F5<1qFk4?ZSA-FklasY@a@AMT}AZ72ei>+!bEsa$3t^($5e?KS-wA!8&3|U^e^Z zeb8;Edew)*{LLvPP(LUIWCoIV4C50;0gdOYsVjqji8%7$QupBj)`86f6zK;vHlaGo zRtYLn+*xSNCYViKqnTQ+t3Ce%?YpP{F1X>Qdk4M1f@=@~8|h*KKsSlmLcoAQDJCJ= zVHxiY77)!wA^Bx%ULOx8K37Tej6rpeLiG>Bq!p7#7td!p$p8Z-+Uth6_?E;QT)c>!MaTj#D-{i|J(kt~+3G58b8MmM6O&d^`IUYlbe;xpAz((R`kL6^KQXH0q2;D#u7{g&XW)|HlC& zwTU#39zNW-w)1uZZ!Wgn4O;w2a+=WAHLO*p(h8B~$~^AIv%ixjSop^pN;jnm+yK_F z>r+NdB#nqS3WMOK38kR(vx9BoR_bfNJ2?z2{J9q(k`NQ6zx;6L=U_dq{f8lZj0iHe z$381z&uQ54=@Czpd2JIM+k);_JWjn&IGbK;P3aj*(DAjY_B{BXXP7j#a*PSs{(hbQ;zK;Rkc!DA7 z)E;wA1nh=iTniv_96t+N*xA@_^ySU)dLQ6{9Yo;}i+lC>_K|>H7_wS!T4@6;oM$DK z4(*@X)(FRF$iGWxD%f={4N%nXIz^#P7M)VC&zQR0k%OWHtIxdKq+TN1t5b4`B~HB6 ze~ryi+SdX?K)lnxS2$a-uUDpmJ|NLsV5gjPk30J1fG>NSYa)0TqM+Za2*sp8Pv8I- z>q6w&0xiJxuBkW=54p&_tZ62MCB%XRibcB-4_dDV68d1$Pb**S)h}A~XNX*F zid$)DXk5R2`!=d0>px3XThB0*;u0s7Kx)tm~7e7C; zI6FIE{(PS~UZP9he74}zF(|l^*1y{QzTyEn%RxR~BBWUig=c^f5RQL^m@BXB2Q2;s zj}w+Vb^rnB(22*XAVWCvS)ehooO{!JdV2c29al0*ltSj9WqEmdo!2)bZeRD)X-h}p z{f1SW98)1O_>VnzsLRFxwT`iIru(?IuKhq?-?40PQGsO+DFP%A*usI=VIR^SK-y{s za*=8j)Y~_OB(Nq#`cYZdzDDCiU;2eU?DC!M&3ADg`0l%>(NkjfGd1=)CEELQY}lEq zq8GV~aDQHEmW3f$T+;L}-)`yg(W&!jbAW`OW>N=izcs@P4<;^oN>E(;3_w{@7?`QdWBWxAV=UKWFL_-z@i zD*IgQ?n2et*Vp%Q=#x~*bETw8m&tO&IxA5$bc!4FoShShz1~{P zyK>QpYxfPDI=TfX1#Z6$M1br-k2vLufsH=G8su_&o9$#dwd;b{hP}|qnC3Vl@vBkA zRxp7m)5UJ}Uo3bE*I| zzyDY*+SM?)c*B?!A0+#vf$I*>5sxzLs=XK##}y}z_8`0+Nd`RnPn=G^c5vz762=fVy|jP@GcM9%qPl-x%X%v+o+{MPWg zwNUnK)|C0UPpo1#(D-x@Nx$QM{%OF#36*ALwL;8$OmsLX5}C@OCEcULYONsJ)tvKnhH!#f z?}4B*LFnIkztH8FLM)hELU~}9l4@^uQ^`zE4dqo2m4ApMF=gu>ynd0n0$Q>;su~1} z51Qqd4)BVaz)z2=P1=G!QSv*memP%>xa0T!ZABEmH<=;gGqV08*#+k3=QsL$YqWl3 zJzzhkN`3~&`;-~Ch#sFz8jHb)vLtHt{nL-W-ki>2FnumCEh{XPPZ#kyH65!%T(Y8Q2u4@6uibT?#S!vT$=+>P zjc$5A7u+t@Pw{kUzAK5*qL2zTu50|Q$VW7RF{QV!Z*R0fby2{i6{PC{Ayc3P7SY+F zf6LDf0CcB|1BAG=lw$6@OSgU?3u?cx}cOpzMu51E_}p z-SxW7mWhadrxEG9NQNy;E$%%l+&ZEW`B9PJCAf_H@HoVR4g>TJL-Ca&3=cz%Uj-TaZl$}->=s<5YsO#M3+Cspe!z<*fb zo!RvwJEwZ%St1fRjQt83E&Q&Jx+5=+H)t*RQrCcW)_}6(qdk;El^ZsFcHf(c_gIV9 z_4D`v>E>}I2e!tCKZ1P#MaA+x>LL%e{?5z6@t!`^uslDXu`gda6(j#`LSUsmZ8Yw+^&)|vQX5(CD7P$}|$NA_CxNiEnGy3|q- z+5^U(><%_v8%##CpmY6m%wvFb@jGz-Ifh%DFn$YE$Z7j9K>JyH&3wFXV`^*y@y3s2 z?lgB!BfpEaR4cjcy3VAJA4jPQP3*EvPivGYR4CgLmZmI9!eM?9KpG_+&rhO;MSm1 z3UliDgXKb7n2ExeSSCI`zRr3y-#$C7(gXuLu2og|X@_+VkdC(JfK{4w0wH3{PCG8g z95G%5Bj;B0AJBcjQ$~hs|I4icsi&lfC%gH%dA+GY%Rm2Nm*)?=DB{H~fZbupkZpQZ z^OW-Rg+Q*j+n0&5SBXtl!`U4KBEN^inKkq63iOR<9@RU{+x(ezf~wiQjPDup01d9wYKt=?7C)PeV~$uA4)}MVbW;>Hqm%0G5#+FfB>OVZ}WRPB3t~9?t?v!_G}dk1?F4Okwp> z%fF=?Uricyo$Uowr1=5vUzFbM5KmWVVt+ z4l0~~tR!dYB?9NCc9}>wUo!-Hpd`np?HrE^H;{Q`lM1M{cratqd|p64a-QC^%X0y*Omzv2Oc~z=o?%X5JCeR&%^ID@z#Out4AcmDwAeSV1=Rcb0<*Te)II z#MC>=PcH(u>;rR%k4&_IP}+eLJWu8qpR?Rw2`rjV_xLn%B;VhdeEgiSpGBfc;Nc@}FJ4Mgi0( z<31;Rd8eV|zC7TT`(@FW4GYo~c1l`&x!~M??&L|!ds$nb^#VJKuYrYd{Sv|Rb1Xm4 zSR1{aZ*l$nl1rZVKfPCe{BT-y-c7C3MUPpGN>b|8+kP|ySAfvvpC$%u0| zn1OL{hQaNbq7nRTjD{Vc1bE%7rw4IB2hRbZ4a^cV+fM*XUZ{ygJMO@L=J|&Amp@*1 Sssnfe7lWs(pUXO@geCxe*Q^x) literal 0 HcmV?d00001 diff --git a/dox_style/documentation/source/pages/user/config/footer_string.rst b/dox_style/documentation/source/pages/user/config/footer_string.rst new file mode 100644 index 0000000..fadff0e --- /dev/null +++ b/dox_style/documentation/source/pages/user/config/footer_string.rst @@ -0,0 +1,48 @@ +.. _sphinx_footer_string: + +Footer String +============= + +The page footer can be extended by an additional string. + + +- Specify the ``dox_style_footer`` variable in ``conf.py`` which must refer to a YAML file. + + Example: + + .. code-block:: python + + dox_style_footer = 'source/general/docu/sphinx/extensions/dox_style/footer.yaml' + +- The YAML file must consist of key/value pairs. The keys must be relative paths from the root of + the documentation to folders or files (without the ending). The values are the strings which shall + be displayed. + + Example: + + .. code-block:: yaml + + modules/abc: Some text + modules/xyz: Can also include HTML tags + modules: All other modules... + general/docu/sphinx/extensions/dox_style/footer_string: Additional footer string for this guideline
with a newline. + ".": Default text + +- When building the documentation, the page names are compared with the keys, the best match wins. + The fallback for all pages is ``"."`` if available. In case no key matches, the additional footer + is not displayed (not all pages may need an additional footer string). + +Example (based on the YAML file above): + +.. code-block:: none + + modules/abc/doc/index.rst matches modules/abc + modules/foo/doc/bar.rst matches modules + tools/python/fasel/doc/user.rst matches "." + +.. note:: + + If the file specified with ``dox_style_footer`` does not exist, no error is raised. + This file may be generated (e.g. by calling "git log") which could take some time. + In this case it's recommended to generate this file only in official builds and make the + generation optional for local builds. diff --git a/dox_style/documentation/source/pages/user/config/table_colors.rst b/dox_style/documentation/source/pages/user/config/table_colors.rst new file mode 100644 index 0000000..c962286 --- /dev/null +++ b/dox_style/documentation/source/pages/user/config/table_colors.rst @@ -0,0 +1,219 @@ +.. _sphinx_table_colors: + +Colored Tables +============== + +| Use a list table with class ``colored`` and add containers for every cell which shall have a + color. +| Optionally specify ``spaced`` for a cell margin or ``centered`` to align the text horizontally in + the middle: + +.. code:: rst + + .. list-table:: + :class: colored [spaced] [centered] + + * - .. container:: -cell + + + - .. container:: -cell + + + +Color example: + +.. code:: rst + + .. list-table:: + :header-rows: 1 + :class: colored centered spaced + + * - Heading + - .. container:: green-cell + + Green + - .. container:: yellow-cell + + Yellow + - .. container:: orange-cell + + Orange + - .. container:: red-cell + + Red + - .. container:: blue-cell + + Blue + - .. container:: white-cell + + White + - .. container:: black-cell + + Black + - .. container:: grey-cell + + Grey + * - Regular Row + - .. container:: green-cell + + Green cell with some more words + - .. container:: yellow-cell + + Yellow + - .. container:: orange-cell + + Orange + - .. container:: red-cell + + Red + - .. container:: blue-cell + + Blue + - .. container:: white-cell + + White + - .. container:: black-cell + + Black + - .. container:: grey-cell + + Grey + +.. list-table:: + :header-rows: 1 + :class: colored centered spaced + + * - Heading + - .. container:: green-cell + + Green + - .. container:: yellow-cell + + Yellow + - .. container:: orange-cell + + Orange + - .. container:: red-cell + + Red + - .. container:: blue-cell + + Blue + - .. container:: white-cell + + White + - .. container:: black-cell + + Black + - .. container:: grey-cell + + Grey + * - Regular Row + - .. container:: green-cell + + Green cell with some more words + - .. container:: yellow-cell + + Yellow + - .. container:: orange-cell + + Orange + - .. container:: red-cell + + Red + - .. container:: blue-cell + + Blue + - .. container:: white-cell + + White + - .. container:: black-cell + + Black + - .. container:: grey-cell + + Grey + +Layout example: + +.. code:: rst + + .. list-table:: + :class: colored + + * - .. container:: orange-cell + + colored + - .. container:: green-cell + + text + + .. list-table:: + :class: colored spaced + + * - .. container:: orange-cell + + colored and spaced + - .. container:: green-cell + + text + + .. list-table:: + :class: colored centered + + * - .. container:: orange-cell + + colored and centered + - .. container:: green-cell + + text + + .. list-table:: + :class: colored spaced centered + + * - .. container:: orange-cell + + colored, spaced and centered + - .. container:: green-cell + + text + +.. list-table:: + :class: colored + + * - .. container:: orange-cell + + colored + - .. container:: green-cell + + text + +.. list-table:: + :class: colored spaced + + * - .. container:: orange-cell + + colored and spaced + - .. container:: green-cell + + text + +.. list-table:: + :class: colored centered + + * - .. container:: orange-cell + + colored and centered + - .. container:: green-cell + + text + +.. list-table:: + :class: colored spaced centered + + * - .. container:: orange-cell + + colored, spaced and centered + - .. container:: green-cell + + text diff --git a/dox_style/documentation/source/pages/user/config/text_colors.rst b/dox_style/documentation/source/pages/user/config/text_colors.rst new file mode 100644 index 0000000..973a1b7 --- /dev/null +++ b/dox_style/documentation/source/pages/user/config/text_colors.rst @@ -0,0 +1,32 @@ +.. _sphinx_text_colors: + +Text Colors +=========== + +| With this extension, the text color can be explicitly set. +| The colors *green*, *yellow*, *orange*, *red*, *blue*, *white*, *black* and *grey* are supported. + +.. list-table:: + :class: colored [spaced] [centered] + + * - .. container:: white-cell + + :green:`green` :yellow:`yellow` :orange:`orange` :red:`red` :blue:`blue` :white:`white` :black:`black` :grey:`grey` + * - .. container:: grey-cell + + :green:`green` :yellow:`yellow` :orange:`orange` :red:`red` :blue:`blue` :white:`white` :black:`black` :grey:`grey` + * - .. container:: black-cell + + :green:`green` :yellow:`yellow` :orange:`orange` :red:`red` :blue:`blue` :white:`white` :black:`black` :grey:`grey` + +Example: + +.. list-table:: + :header-rows: 1 + + * - RST + - HTML + * - .. code:: rst + + This is :red:`red text.` + - This is :red:`red text.` \ No newline at end of file diff --git a/dox_style/dox_style/__init__.py b/dox_style/dox_style/__init__.py new file mode 100644 index 0000000..2c5028a --- /dev/null +++ b/dox_style/dox_style/__init__.py @@ -0,0 +1,14 @@ +from .config.main import config_setup +from .checks.main import check_setup +from .version import __version__ + + +def setup(app): + config_setup(app) + check_setup(app) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/dox_style/dox_style/__main__.py b/dox_style/dox_style/__main__.py new file mode 100644 index 0000000..b1c2cc1 --- /dev/null +++ b/dox_style/dox_style/__main__.py @@ -0,0 +1,6 @@ +from pprint import pprint +from .checks.main import generate_options + +if __name__ == "__main__": + print("Available stylecheck options (and their defaults):\n") + pprint(generate_options(), sort_dicts=False, width=100, indent=4) diff --git a/dox_style/dox_style/checks/__init__.py b/dox_style/dox_style/checks/__init__.py new file mode 100644 index 0000000..d2b3c18 --- /dev/null +++ b/dox_style/dox_style/checks/__init__.py @@ -0,0 +1,2 @@ +from .finding import Finding +from .check import Check diff --git a/dox_style/dox_style/checks/check.py b/dox_style/dox_style/checks/check.py new file mode 100644 index 0000000..bcd5d72 --- /dev/null +++ b/dox_style/dox_style/checks/check.py @@ -0,0 +1,20 @@ +from . import Finding + + +class Check: + FINDING = Finding + + CONFIG = {} + + def __init__(self): + self._findings = [] + + @property + def findings(self): + return self._findings + + def run(self, file, lines): + raise NotImplementedError + + def add_finding(self, file, line, **kwargs): + self._findings.append(self.FINDING(file, line, **kwargs)) diff --git a/dox_style/dox_style/checks/dummy.py b/dox_style/dox_style/checks/dummy.py new file mode 100644 index 0000000..de81340 --- /dev/null +++ b/dox_style/dox_style/checks/dummy.py @@ -0,0 +1,23 @@ +from . import Check, Finding + + +class DummyFinding(Finding): + NAME = "DummyFinding" + + def msg(self): + return "This is some dummy finding message" + + +class DummyCheck(Check): + FINDING = DummyFinding + + CONFIG = { + "some": "config option", + } + + def run(self, file, lines): + # file: path to the document to check + # lines: content of that document read as list of lines + + # violation found in line 42, add a corresponding finding + self.add_finding(file, 42) diff --git a/dox_style/dox_style/checks/finding.py b/dox_style/dox_style/checks/finding.py new file mode 100644 index 0000000..ce7768d --- /dev/null +++ b/dox_style/dox_style/checks/finding.py @@ -0,0 +1,40 @@ +class Finding: + NAME = "Finding" + + def __init__(self, file, line, **kwargs): + self.file = file + self.line = line + + def msg(self): + return "" + + def excerpt_lines(self, n): + lines = [] + try: + with open(self.file, "r", encoding="utf-8") as rst_file: + all_lines = rst_file.readlines() + + if self.line > len(all_lines): + raise IndexError + + start = max(0, self.line - n - 1) + end = min(len(all_lines), self.line + n) + + for i in range(start, end): + lines.append((i + 1, all_lines[i])) + + except FileNotFoundError: + lines = [(self.line, self.file)] + except IndexError: + lines = [(self.line, self.file)] + return lines + + def as_str(self, show_excerpt=0): + display = f"[{self.NAME}] {self.msg()}\n" + if show_excerpt > 0: + for i, line in self.excerpt_lines(show_excerpt): + if i == self.line: + display += f"{i:3d} -> {line}" + else: + display += f"{i:3d}: {line}" + return display diff --git a/dox_style/dox_style/checks/heading_levels_check.py b/dox_style/dox_style/checks/heading_levels_check.py new file mode 100644 index 0000000..c73ee36 --- /dev/null +++ b/dox_style/dox_style/checks/heading_levels_check.py @@ -0,0 +1,47 @@ +from . import Check, Finding +from .utils import is_heading + + +class HeadingLevelsFinding(Finding): + NAME = "HeadingLevels" + + def __init__(self, file, line, expected_char, actual_char): + super().__init__(file, line) + self.expected_char = expected_char + self.actual_char = actual_char + + def msg(self): + return f"Heading must be {self.expected_char} instead of {self.actual_char}" + + +class HeadingLevelsCheck(Check): + FINDING = HeadingLevelsFinding + + CONFIG = {"characters": ["=", "-", "+", "~", "^", '"']} + + def __init__(self): + self.heading_characters = self.CONFIG["characters"] + super().__init__() + self.heading_levels = {c: i + 1 for i, c in enumerate(self.heading_characters)} + + def run(self, file, lines): + current_level = 0 + for i, line in enumerate(lines): + if is_heading(line): + if line[0] in self.heading_characters: + level = self.heading_levels[line[0]] + if level - current_level > 1: + self.add_finding( + file, + i + 1, + expected_char=self.heading_characters[current_level], + actual_char=line[0], + ) + current_level = level + else: + self.add_finding( + file, + i + 1, + expected_char=self.heading_characters[current_level], + actual_char=line[0], + ) diff --git a/dox_style/dox_style/checks/include_rst_check.py b/dox_style/dox_style/checks/include_rst_check.py new file mode 100644 index 0000000..f8b7229 --- /dev/null +++ b/dox_style/dox_style/checks/include_rst_check.py @@ -0,0 +1,20 @@ +from . import Check, Finding +import re + + +class IncludeRstFinding(Finding): + NAME = "IncludeRst" + + def msg(self): + return "Include-directive must not point to an *.rst file" + + +class IncludeRstCheck(Check): + FINDING = IncludeRstFinding + + include_rst_regex = re.compile(r"\.\.\s+include\s*::.*\.rst$") + + def run(self, file, lines): + for i, line in enumerate(lines): + if self.include_rst_regex.match(line): + self.add_finding(file, i + 1) diff --git a/dox_style/dox_style/checks/main.py b/dox_style/dox_style/checks/main.py new file mode 100644 index 0000000..745bbeb --- /dev/null +++ b/dox_style/dox_style/checks/main.py @@ -0,0 +1,112 @@ +import collections +from copy import deepcopy +from fnmatch import fnmatch +from sphinx.util import logging + +from .top_level_casing_check import TopLevelCasingCheck +from .top_level_heading_check import TopLevelHeadingCheck +from .top_level_length_check import TopLevelLengthCheck +from .top_level_modulename_check import TopLevelModuleNameCheck +from .trailing_whitespace_check import TrailingWhitespacesCheck +from .heading_levels_check import HeadingLevelsCheck +from .underline_length_check import UnderlineLengthCheck +from .include_rst_check import IncludeRstCheck + +logger = logging.getLogger(__name__) + + +all_checks = { + "trailing_whitespaces": TrailingWhitespacesCheck, + "heading_levels": HeadingLevelsCheck, + "underline_length": UnderlineLengthCheck, + "top_level_casing": TopLevelCasingCheck, + "top_level_heading": TopLevelHeadingCheck, + "top_level_length": TopLevelLengthCheck, + "top_level_modulename": TopLevelModuleNameCheck, + "include_rst": IncludeRstCheck, +} + + +global_options = { + "exclude": [], + "excerpt": 2, +} + + +common_check_options = { + "enabled": True, + "exclude": [], +} + + +def generate_options(): + options = global_options + for key, check in all_checks.items(): + options[key] = deepcopy(check.CONFIG) + options[key].update(common_check_options) + + return options + + +def updated_options_from_config(config): + options = generate_options() + + def update(d, u): + for k, v in u.items(): + if isinstance(v, collections.abc.Mapping): + d[k] = update(d.get(k, {}), v) + else: + d[k] = v + return d + + update(options, config) + + return options + + +def style_check(_app, env, docnames): + options = updated_options_from_config(env.config.stylecheck) + + enabled_checks = [] + for key, check in all_checks.items(): + if options[key]["enabled"]: + check.CONFIG = deepcopy(options[key]) + enabled_checks.append(check()) + + if not enabled_checks: + logger.warning("No stylechecks enabled") + + for filepath, docname in [(f"{env.srcdir}/{docname}.rst", docname) for docname in docnames]: + if any([fnmatch(docname, exclusion) for exclusion in options["exclude"]]): + continue + + try: + with open(filepath, "r", encoding="utf-8") as file: + lines = file.read().splitlines() + except FileNotFoundError: + logger.error(f"Cannot open {filepath}") + return + + for check in enabled_checks: + if any([fnmatch(docname, exclusion) for exclusion in check.CONFIG["exclude"]]): + continue + check.run(filepath, lines) + + num_findings = 0 + for check in enabled_checks: + for finding in check.findings: + num_findings += 1 + excerpt = env.config.stylecheck.get("excerpt", global_options["excerpt"]) + logger.info( + f"\n{finding.as_str(show_excerpt=excerpt)}", + location=(finding.file, finding.line), + color="red", + ) + + if num_findings > 0: + logger.warning(f"Found {num_findings} style violations") + + +def check_setup(app): + app.connect("env-before-read-docs", style_check) + app.add_config_value("stylecheck", generate_options(), "env") diff --git a/dox_style/dox_style/checks/top_level_casing_check.py b/dox_style/dox_style/checks/top_level_casing_check.py new file mode 100644 index 0000000..c92d81b --- /dev/null +++ b/dox_style/dox_style/checks/top_level_casing_check.py @@ -0,0 +1,22 @@ +from . import Check, Finding +from .utils import is_index, get_module, get_first_heading + + +class TopLevelCasingFinding(Finding): + NAME = "TopLevelCasing" + + def msg(self): + return "Module name has wrong case" + + +class TopLevelCasingCheck(Check): + FINDING = TopLevelCasingFinding + + def run(self, file, lines): + if not is_index(file): + return + module = get_module(file) + top_level_heading, i = get_first_heading(lines) + if top_level_heading and top_level_heading.lower().startswith(module.lower()): + if not top_level_heading.startswith(module): + self.add_finding(file, i + 1) diff --git a/dox_style/dox_style/checks/top_level_heading_check.py b/dox_style/dox_style/checks/top_level_heading_check.py new file mode 100644 index 0000000..3d32a69 --- /dev/null +++ b/dox_style/dox_style/checks/top_level_heading_check.py @@ -0,0 +1,20 @@ +from . import Check, Finding +from .utils import is_index, get_first_heading + + +class TopLevelHeadingFinding(Finding): + NAME = "TopLevelHeading" + + def msg(self): + return "Document has no heading" + + +class TopLevelHeadingCheck(Check): + FINDING = TopLevelHeadingFinding + + def run(self, file, lines): + if not is_index(file): + return + _, i = get_first_heading(lines) + if i == -1: + self.add_finding(file, 1) diff --git a/dox_style/dox_style/checks/top_level_length_check.py b/dox_style/dox_style/checks/top_level_length_check.py new file mode 100644 index 0000000..e3508ff --- /dev/null +++ b/dox_style/dox_style/checks/top_level_length_check.py @@ -0,0 +1,34 @@ +from . import Check, Finding +from .utils import is_index, get_first_heading + + +class TopLevelLengthFinding(Finding): + NAME = "TopLevelLength" + + def __init__(self, file, line, exp_length, act_length): + super().__init__(file, line) + self._exp_length = exp_length + self._act_length = act_length + + def msg(self): + return f"Title too long: {self._act_length} > {self._exp_length}" + + +class TopLevelLengthCheck(Check): + FINDING = TopLevelLengthFinding + + CONFIG = { + "limit": 40, + } + + def run(self, file, lines): + if not is_index(file): + return + top_level_heading, i = get_first_heading(lines) + if len(top_level_heading) > self.CONFIG["limit"]: + self.add_finding( + file, + i + 1, + exp_length=self.CONFIG["limit"], + act_length=len(top_level_heading), + ) diff --git a/dox_style/dox_style/checks/top_level_modulename_check.py b/dox_style/dox_style/checks/top_level_modulename_check.py new file mode 100644 index 0000000..1eb2e12 --- /dev/null +++ b/dox_style/dox_style/checks/top_level_modulename_check.py @@ -0,0 +1,25 @@ +from . import Check, Finding +from .utils import is_index, get_module, get_first_heading + + +class TopLevelModuleNameFinding(Finding): + NAME = "TopLevelModulName" + + def __init__(self, file, line, module_name): + super().__init__(file, line) + self.module_name = module_name + + def msg(self): + return f'Module name "{self.module_name}" not found' + + +class TopLevelModuleNameCheck(Check): + FINDING = TopLevelModuleNameFinding + + def run(self, file, lines): + if not is_index(file): + return + module = get_module(file) + top_level_heading, i = get_first_heading(lines) + if top_level_heading and not top_level_heading.lower().startswith(module.lower()): + self.add_finding(file, i + 1, module_name=module) diff --git a/dox_style/dox_style/checks/trailing_whitespace_check.py b/dox_style/dox_style/checks/trailing_whitespace_check.py new file mode 100644 index 0000000..c6d2e0b --- /dev/null +++ b/dox_style/dox_style/checks/trailing_whitespace_check.py @@ -0,0 +1,20 @@ +from . import Check, Finding +import re + + +class TrailingWhitespacesFinding(Finding): + NAME = "TrailingWhitespace" + + def msg(self): + return f"Line contains trailing whitespaces" + + +class TrailingWhitespacesCheck(Check): + FINDING = TrailingWhitespacesFinding + + trailing_whitespace_regex = re.compile(r".*\s+$") + + def run(self, file, lines): + for i, line in enumerate(lines): + if self.trailing_whitespace_regex.match(line): + self.add_finding(file, i + 1) diff --git a/dox_style/dox_style/checks/underline_length_check.py b/dox_style/dox_style/checks/underline_length_check.py new file mode 100644 index 0000000..8e11130 --- /dev/null +++ b/dox_style/dox_style/checks/underline_length_check.py @@ -0,0 +1,23 @@ +from . import Check, Finding +from .utils import is_heading + + +class UnderlineLengthFinding(Finding): + NAME = "UnderlineLength" + + def msg(self): + return f"Heading underline length does not match title length" + + +class UnderlineLengthCheck(Check): + FINDING = UnderlineLengthFinding + + def run(self, file, lines): + prev_line_length = -1 + + for i, line in enumerate(lines): + line_length = len(line) + if is_heading(line) and prev_line_length != line_length and prev_line_length != -1: + self.add_finding(file, i + 1) + + prev_line_length = line_length diff --git a/dox_style/dox_style/checks/utils.py b/dox_style/dox_style/checks/utils.py new file mode 100644 index 0000000..ed7f808 --- /dev/null +++ b/dox_style/dox_style/checks/utils.py @@ -0,0 +1,34 @@ +import re +from typing import Union + +heading_regex = re.compile(r"([=\-`:'\"~^_*+#<>])\1*$") +index_regex = re.compile(r".*/([^/]+)/doc/index.rst") + + +def is_heading(line: str) -> bool: + return heading_regex.match(line) is not None + + +def is_index(file: str) -> bool: + return index_regex.match(file) is not None + + +def get_module(file: str) -> Union[str, None]: + match = index_regex.match(file) + if match: + return match.group(1) + else: + return None + + +def get_first_heading(lines): + heading_candidate = None + for i, line in enumerate(lines): + if ( + is_heading(line) + and heading_candidate is not None + and len(line) >= len(heading_candidate) + ): + return heading_candidate + heading_candidate = line, i + return "", -1 diff --git a/dox_style/dox_style/config/_static/breadcrumbs.html b/dox_style/dox_style/config/_static/breadcrumbs.html new file mode 100644 index 0000000..82cff3a --- /dev/null +++ b/dox_style/dox_style/config/_static/breadcrumbs.html @@ -0,0 +1,76 @@ +

+ +
    + {% block breadcrumbs %} +
  • »
  • + {% for doc in parents %} +
  • {{ doc.title }} »
  • + {% endfor %} +
  • {{ title }}
  • + {% endblock %} + + {% block breadcrumbs_aside %} + +
  • + + + + {% if document_status_default is defined %} + {% set document_status_key = 'created' %} + + {% if meta is defined and meta is not none and 'document_status' in meta %} + {% set document_status_key = meta.get('document_status').split('\n')[0] %} + {% else %} + {% set document_status_key = document_status_default %} + {% endif %} + + {% set document_status_key = document_status_key.lower() %} + + {% if document_status_key == 'raw' %} + {% set document_status_key = 'created' %} + {% elif document_status_key == 'valid' %} + {% set document_status_key = 'released' %} + {% endif %} + + {% set document_status_value = document_status_key.title() %} + {% set document_status_key = document_status_key.replace(' ', '') %} + + {% if document_status_key not in ['created', 'draft', 'verified', 'released'] %} + {% set document_status_key = 'created' %} + {% set document_status_value = 'Invalid document status: ' + document_status_value %} + {% endif %} + + + {{ document_status_value }} + {% endif %} + + + + {% if data_classification_default is defined and data_classification_default is not none %} + {% set data_classification_key = 'restricted' %} + + {% if meta is defined and meta is not none and 'data_classification' in meta %} + {% set data_classification_key = meta.get('data_classification').split('\n')[0] %} + {% else %} + {% set data_classification_key = data_classification_default %} + {% endif %} + + {% set data_classification_value = data_classification_key.title() %} + {% set data_classification_key = data_classification_key.lower().replace(' ', '') %} + + {% if data_classification_key not in ['confidential', 'highlyconfidential', 'unrestricted', 'restricted'] %} + {% set data_classification_key = 'restricted' %} + {% set data_classification_value = 'Invalid data classification: ' + data_classification_value %} + {% endif %} + + + {{ data_classification_value }} + {% endif %} + +
  • + + {% endblock %} +
+ +
+
diff --git a/dox_style/dox_style/config/_static/colored_table.css b/dox_style/dox_style/config/_static/colored_table.css new file mode 100644 index 0000000..af79196 --- /dev/null +++ b/dox_style/dox_style/config/_static/colored_table.css @@ -0,0 +1,26 @@ +.green-cell { background-color:rgb( 33, 215, 38); height:100%; display:grid; align-items:center; } +.yellow-cell { background-color:rgb(251, 251, 40); height:100%; display:grid; align-items:center; } +.orange-cell { background-color:rgb(253, 149, 38); height:100%; display:grid; align-items:center; } +.red-cell { background-color:rgb(253, 13, 27); height:100%; display:grid; align-items:center; } +.blue-cell { background-color:rgb( 40, 36, 251); height:100%; display:grid; align-items:center; } +.white-cell { background-color:rgb(255, 255, 255); height:100%; display:grid; align-items:center; } +.black-cell { background-color:rgb( 0, 0, 0); height:100%; display:grid; align-items:center; } +.grey-cell { background-color:rgb(128, 128, 128); height:100%; display:grid; align-items:center; } + +table.docutils.spaced { border-spacing: 3px; border-collapse: separate; } + +table.docutils.centered { text-align: center; } +table.docutils.centered th { text-align: center; } + +table.docutils.colored { vertical-align: middle; } +table.docutils.colored th { padding: 0; margin: 0; vertical-align: middle; + height: 0; height: -moz-available; } +table.docutils.colored td { padding: 0; margin: 0; vertical-align: middle; + height: 0; height: -moz-available; } +table.docutils.colored th > * { padding: 8px 16px; } +table.docutils.colored td > * { padding: 8px 16px; } +table.docutils.colored th > * > * { margin: 0; } +table.docutils.colored td > * > * { margin: 0; } + +table.docutils.colored thead { height: 100%; } +table.docutils.colored tbody { height: 100%; } diff --git a/dox_style/dox_style/config/_static/colors.css b/dox_style/dox_style/config/_static/colors.css new file mode 100644 index 0000000..a66f0dc --- /dev/null +++ b/dox_style/dox_style/config/_static/colors.css @@ -0,0 +1,19 @@ +/* text colors + + Note: + - red same as restricted / created + - orange same as highlyconfidential / draft + - blue same as confidential / verified + - green same as unrestricted / released +*/ + +.green { color:rgb( 33, 215, 38); } +.yellow { color:rgb(251, 251, 40); } +.orange { color:rgb(253, 149, 38); } +.red { color:rgb(253, 13, 27); } +.blue { color:rgb( 40, 36, 251); } +.white { color:rgb(255, 255, 255); } +.black { color:rgb( 0, 0, 0); } +.grey { color:rgb(128, 128, 128); } + +.greyitalic { color:rgb(128, 128, 128); font-style: italic; } diff --git a/dox_style/dox_style/config/_static/footer.html b/dox_style/dox_style/config/_static/footer.html new file mode 100644 index 0000000..2c48287 --- /dev/null +++ b/dox_style/dox_style/config/_static/footer.html @@ -0,0 +1,16 @@ +{%- extends '!footer.html' -%} {%- block extrafooter -%} +
+

+ {%- if meta is defined and meta is not none and 'footer_string' in meta -%} + {{ meta.get('footer_string') }} + {%- endif -%} +

+ + {% if show_source and source_url_prefix %} + {{ _('View page source') }} + {% elif show_source and has_source and sourcename %} + {{ _('View page source') }} + {% endif %} + +
+{%- endblock -%} diff --git a/dox_style/dox_style/config/_static/header.css b/dox_style/dox_style/config/_static/header.css new file mode 100644 index 0000000..16fb2b7 --- /dev/null +++ b/dox_style/dox_style/config/_static/header.css @@ -0,0 +1,27 @@ +/* border around labels in the header with round corners, used for data + data classification and document status */ + +.header-label { + font-weight: bold; + border: solid 1px lightgray; + border-radius: 3px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + padding-left: 3px; + padding-right: 3px; + padding-top: 1px; + padding-bottom: 1px; + width: fit-content; +} + +/* label colors used in the header */ + +.data-classification-restricted { color:rgb(253, 13, 27); } +.data-classification-highlyconfidential { color:rgb(253, 149, 38); } +.data-classification-confidential { color:rgb( 40, 36, 251); } +.data-classification-unrestricted { color:rgb( 33, 215, 38); } + +.document-status-created { color:rgb(253, 13, 27); } +.document-status-draft { color:rgb(253, 149, 38); } +.document-status-verified { color:rgb( 40, 36, 251); } +.document-status-released { color:rgb( 33, 215, 38); } diff --git a/dox_style/dox_style/config/_static/rtd_theme_overrides.css b/dox_style/dox_style/config/_static/rtd_theme_overrides.css new file mode 100644 index 0000000..6abc220 --- /dev/null +++ b/dox_style/dox_style/config/_static/rtd_theme_overrides.css @@ -0,0 +1,57 @@ +@import "css/theme.css"; + +/* increase width of left menu bar and right content view larger than in RTD theme */ + +@media screen and (min-width: 768px) { + .wy-nav-content { + max-width: 1000px !important; + } + .wy-side-scroll { + width: 350px !important; + -ms-overflow-style: none; /* IE, Edge */ + scrollbar-width: none; /* Firefox */ + } + .wy-side-scroll::-webkit-scrollbar { display: none; } /* Chrome, Safari, Opera */ + .wy-side-nav-search { width: 350px !important; } + .wy-nav-side { width: 350px !important; } + .wy-menu-vertical { width: 350px !important; } + .wy-nav-content-wrap { margin-left: 350px !important; } +} + +/* wrap text in tables */ + +.wy-table-responsive table td, .wy-table-responsive table th { + white-space: normal; +} + +/* "Last updated" text in footer starts in a new line */ + +.lastupdated { + white-space: pre-line; + display: block; +} + +/* when setting size to 100% in rst files to make images "clickable", the height will be incorrect + without the following configuration */ + +img { + height: auto !important; +} + +/* centered images and figures should have a margin at the bottom */ + +.rst-content img.align-center:not(table) { margin-bottom: 24px; } +.rst-content figure.align-center:not(table) { margin-bottom: 24px; } + +/* overwrite the red default color of literals which looks like an error. */ + +.rst-content code.literal { color:black } + +/* overwrite the colors for "file" */ + +.literal.file { background: #FFFFFF; color:mediumpurple !important } + +/* overwrite the style for "download" role */ + +.rst-content code.download span:first-child:before { content: none !important; } +.rst-content code.download { color: unset !important; } diff --git a/dox_style/dox_style/config/label_check.py b/dox_style/dox_style/config/label_check.py new file mode 100644 index 0000000..4b292f1 --- /dev/null +++ b/dox_style/dox_style/config/label_check.py @@ -0,0 +1,64 @@ +from docutils import nodes +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def add_refid(std, docname, location, ref_id): + std["label_location"][ref_id] = location + if docname not in std["labels_in_document"]: + std["labels_in_document"][docname] = {ref_id} + else: + std["labels_in_document"][docname].add(ref_id) + + +def collect_labels(app, doctree): + std = app.env.domaindata["std"] + docname = app.env.docname + for node in doctree.traverse(nodes.target): + ref_id = node.get("refid") + # ignore duplicated labels for a single env, this will be checked by Sphinx internally + if ref_id: + location = docname + ".rst" + if ref_id in std["label_location"]: + location_other = std["label_location"][ref_id] + if location_other != location: + logger.warning(f"label {ref_id} defined in {location} and {location_other}") + else: + add_refid(std, docname, location, ref_id) + + +def purge_labels(_app, env, docname): + std = env.domaindata["std"] + if "labels_in_document" in std: + if docname in std["labels_in_document"] and "label_location" in std: + for ref_id in std["labels_in_document"][docname]: + std["label_location"].pop(ref_id, None) + std["labels_in_document"].pop(docname, None) + + +def prepare_labels(app, _env, _docnames): + std = app.env.domaindata["std"] + if "labels_in_document" not in std: + std["labels_in_document"] = {} + if "label_location" not in std: + std["label_location"] = {} + + +def merge_labels_parallel_build(_app, env, docnames, other): + std = env.domaindata["std"] + std_other = other.domaindata["std"] + + for docname in docnames: + if docname not in std_other["labels_in_document"]: + # no labels to merge + continue + for ref_id in std_other["labels_in_document"][docname]: + location_other = std_other["label_location"][ref_id] + if ref_id in std["label_location"]: + location = std["label_location"][ref_id] + if location_other != location: + logger.warning(f"label {ref_id} defined in {location} and {location_other}") + # else: label already there, can happen when rebuilding the documentation + else: + add_refid(std, docname, location_other, ref_id) diff --git a/dox_style/dox_style/config/main.py b/dox_style/dox_style/config/main.py new file mode 100644 index 0000000..6b51e4d --- /dev/null +++ b/dox_style/dox_style/config/main.py @@ -0,0 +1,156 @@ +import os +import warnings +import importlib.util + +from pathlib import Path +from datetime import datetime +import yaml +from yaml.loader import SafeLoader + +from .label_check import * + +logger = logging.getLogger(__name__) + + +def config_inited(app, config): + # suppress deprecated warnings in some Sphinx extensions + warnings.filterwarnings("ignore", category=DeprecationWarning, module="sphinxcontrib") + + # page footer + if config.dox_style_footer: + if os.path.isfile(config.dox_style_footer): + with open(config.dox_style_footer, "r") as f: + config["footer_string"] = yaml.load(f, Loader=SafeLoader) + + # HTML theme and options + config.html_theme = "sphinx_rtd_theme" + config.html_show_sphinx = False + config.html_show_sourcelink = True + config.html_style = "rtd_theme_overrides.css" + config.html_theme_options.update( + { + "style_external_links": True, + "sticky_navigation": False, + "prev_next_buttons_location": None, + "navigation_depth": 6, + } + ) + + # HTML additional files + static = Path.joinpath(Path(__file__).parent, "_static").as_posix() + config.html_static_path = [static] + config.templates_path = [static] + app.add_css_file("colors.css") + app.add_css_file("colored_table.css") + app.add_css_file("header.css") + + # data classification + if "data_classification_default" not in config.html_context: + config.html_context["data_classification_default"] = "Confidential" + + # latexpdf needs to know who certain unicode characters shall be rendered + if not config.latex_elements: + config.latex_elements = {} + if not "preamble" in config.latex_elements: + config.latex_elements["preamble"] = "" + config.latex_elements[ + "preamble" + ] += r""" + \DeclareUnicodeCharacter{25BA}{$\blacktriangleright$} + \DeclareUnicodeCharacter{25BC}{$\blacktriangledown$} + \DeclareUnicodeCharacter{25B2}{$\blacktriangle$} + \DeclareUnicodeCharacter{25C4}{$\blacktriangleleft$} + """ + if not "extrapackages" in config.latex_elements: + config.latex_elements["extrapackages"] = "" + config.latex_elements[ + "extrapackages" + ] += r""" + \usepackage{pmboxdraw} + """ + + # overwrite PlantUML path, needed for Windows + if "PLANTUML_DIR" in os.environ: + config.plantuml = "java -Xlog:disable -jar {}".format( + Path(os.getenv("PLANTUML_DIR")).joinpath("plantuml.jar").resolve() + ) + + # global definitions (important: do not use leading spaces) + if not config.rst_prolog: + config.rst_prolog = "" + config.rst_prolog += """ +.. role:: green +.. role:: yellow +.. role:: orange +.. role:: red +.. role:: blue +.. role:: white +.. role:: black +.. role:: grey +.. role:: greyitalic +.. role:: raw-html(raw) + :format: html +.. |br| replace:: :raw-html:`
` +""" + + # case-insensitive glossary + if "ref.term" not in config.suppress_warnings: + config.suppress_warnings.append("ref.term") + + ################ + + # At the end try to load a custom specific configuration file + # which can be used to overwrite all values set by this extension. + try: + extend_filename = Path(app.confdir) / "extend_conf.py" + if os.path.exists(extend_filename): + spec = importlib.util.spec_from_file_location("extend_conf", extend_filename) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + + module.extend_conf(config) + print("Custom configuration file loaded") + except (ImportError, TypeError): + logger.warning("extend_conf.py requires a function\n def extend_conf(config: dict)") + + +def get_footer_string(app, docname): + docpath = docname + while True: + if docpath in app.config["footer_string"]: + return app.config["footer_string"][docpath] + else: + pos = docpath.rfind("/") + if pos >= 0: + docpath = docpath[:pos] + elif docpath != ".": + docpath = "." + else: + return None + + +def add_extrafooter(app, _doctree, docname): + build_type = "official build" if "OFFICIAL_BUILD" in os.environ else "UNOFFICIAL BUILD" + build_time = datetime.today().strftime("%Y-%m-%d %H:%M:%S") + app.env.metadata[docname]["footer_string"] = ( + "Documentation from " + build_time + ", " + build_type + "." + ) + + if hasattr(app.config, "footer_string"): + ftext = get_footer_string(app, docname) + if ftext: + app.env.metadata[docname]["footer_string"] += "
" + ftext + + +def config_setup(app): + # config_inited must be called before any other extension, priority 0 is the highest priority + app.connect("config-inited", config_inited, priority=0) + + app.connect("doctree-resolved", add_extrafooter) + + app.connect("env-before-read-docs", prepare_labels) + app.connect("env-purge-doc", purge_labels) + app.connect("doctree-read", collect_labels) + app.connect("env-merge-info", merge_labels_parallel_build) + + app.add_config_value("dox_style_footer", None, "html") diff --git a/dox_style/dox_style/version.py b/dox_style/dox_style/version.py new file mode 100644 index 0000000..3ced358 --- /dev/null +++ b/dox_style/dox_style/version.py @@ -0,0 +1 @@ +__version__ = "0.2.1" diff --git a/dox_style/pyproject.toml b/dox_style/pyproject.toml new file mode 100644 index 0000000..7b0d06f --- /dev/null +++ b/dox_style/pyproject.toml @@ -0,0 +1,28 @@ +[build-system] +requires = ["setuptools >= 70.0.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "dox_style" +dynamic = ["version"] +authors = [ + { name="Accenture" }, +] +description = "Default configuration for documentations regarding style and common options. Includes also several style checks." +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", +] +license = {text = "Apache-2.0"} + +[project.urls] +Homepage = "https://github.com/esrlabs/dox" +Issues = "https://github.com/esrlabs/dox/issues" + +[tool.setuptools] +license-files = ["LICENSE"] +dynamic.version = {attr = "dox_style.version.__version__"} +package-data."*" = ['config/_static/*', "LICENSE"] diff --git a/dox_style/tests/__init__.py b/dox_style/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dox_style/tests/test_check.py b/dox_style/tests/test_check.py new file mode 100644 index 0000000..0afaeb8 --- /dev/null +++ b/dox_style/tests/test_check.py @@ -0,0 +1,39 @@ +import unittest + +from dox_style.checks import Check, Finding + + +class CheckTest(unittest.TestCase): + def test_run_raises_not_implemented_error(self): + check = Check() + + with self.assertRaises(NotImplementedError): + check.run("index.rst", []) + + +class ConcreteFinding(Finding): + NAME = "ConcreteFinding" + + def __init__(self, file, line, some_arg): + super().__init__(file, line) + self.some_arg = some_arg + + def msg(self): + return f"Custom message with {self.some_arg}" + + +class ConcreteCheck(Check): + FINDING = ConcreteFinding + + def run(self, file, lines): + self.add_finding(file, 42, some_arg="foobar") + + +class ConcreteCheckTest(unittest.TestCase): + def test_run_adds_finingnot_implemented_error(self): + lines = ["first", "second", "third"] + + check = ConcreteCheck() + check.run("index.rst", lines) + self.assertEqual(len(check.findings), 1) + self.assertIn("foobar", check.findings[0].as_str()) diff --git a/dox_style/tests/test_finding.py b/dox_style/tests/test_finding.py new file mode 100644 index 0000000..10b5b79 --- /dev/null +++ b/dox_style/tests/test_finding.py @@ -0,0 +1,88 @@ +import os +import unittest + +from tempfile import NamedTemporaryFile +from dox_style.checks import Finding + + +class FindingTest(unittest.TestCase): + def test_takes_filename_and_line(self): + finding = Finding(file="index.rst", line=42) + self.assertEqual(finding.file, "index.rst") + self.assertEqual(finding.line, 42) + + def test_as_str_is_a_descriptive_string(self): + finding = Finding(file="index.rst", line=42) + string = finding.as_str() + self.assertIn(Finding.NAME, string) + + def test_contains_excerpt_from_file(self): + with self.subTest("middle"): + try: + with NamedTemporaryFile(delete=False) as tmp_file: + tmp_file.write("first_line\nsecond_line\nthird_line".encode()) + finding = Finding(file=tmp_file.name, line=2) + string = finding.as_str(show_excerpt=1) + self.assertIn("first_line", string) + self.assertIn("second_line", string) + self.assertIn("third_line", string) + finally: + os.remove(tmp_file.name) + + with self.subTest("first"): + try: + with NamedTemporaryFile(delete=False) as tmp_file: + tmp_file.write("first_line\nsecond_line\nthird_line".encode()) + finding = Finding(file=tmp_file.name, line=1) + string = finding.as_str(show_excerpt=1) + self.assertIn("first_line", string) + self.assertIn("second_line", string) + self.assertNotIn("third_line", string) + finally: + os.remove(tmp_file.name) + + with self.subTest("last"): + try: + with NamedTemporaryFile(delete=False) as tmp_file: + tmp_file.write("first_line\nsecond_line\nthird_line".encode()) + finding = Finding(file=tmp_file.name, line=3) + string = finding.as_str(show_excerpt=1) + self.assertNotIn("first_line", string) + self.assertIn("second_line", string) + self.assertIn("third_line", string) + finally: + os.remove(tmp_file.name) + + def test_excerpt_contains_filename_if_file_not_found(self): + finding = Finding(file="non-existent", line=2) + string = finding.as_str(show_excerpt=1) + self.assertIn("non-existent", string) + + def test_excerpt_contains_filename_if_line_not_found(self): + try: + with NamedTemporaryFile(delete=False) as tmp_file: + tmp_file.write("first line\nsecond_line\nthird_line".encode()) + finding = Finding(file=tmp_file.name, line=999) + string = finding.as_str(show_excerpt=1) + self.assertIn(tmp_file.name, string) + finally: + os.remove(tmp_file.name) + + +class ConcreteFinding(Finding): + NAME = "ConcreteFinding" + + def __init__(self, file, line, some_arg): + super().__init__(file, line) + self.some_arg = some_arg + + def msg(self): + return f"Custom message with {self.some_arg}" + + +class ConcreteFindingTest(unittest.TestCase): + def test_concrete_test_finding(self): + finding = ConcreteFinding(file="index.rst", line=42, some_arg="foobar") + string = finding.as_str() + self.assertIn(ConcreteFinding.NAME, string) + self.assertIn("foobar", string) diff --git a/dox_style/tests/test_heading_levels.py b/dox_style/tests/test_heading_levels.py new file mode 100644 index 0000000..aa454b4 --- /dev/null +++ b/dox_style/tests/test_heading_levels.py @@ -0,0 +1,77 @@ +import unittest +from dox_style.checks.heading_levels_check import HeadingLevelsCheck, HeadingLevelsFinding + + +class TrailingWhitespaceTest(unittest.TestCase): + def test_good_heading_levels(self): + good_headings = [ + "Heading 1", + "=========", + "Heading 1.1", + "-----------", + "Heading 1.1.1", + "+++++++++++++", + "Heading 1.1.1.1", + "~~~~~~~~~~~~~~~", + "Heading 1.1.1.1.1", + "^^^^^^^^^^^^^^^^^", + "Heading 1.1.1.1.1.1", + '"""""""""""""""""""', + "Heading 1.1.1.1.1.2", + '"""""""""""""""""""', + "Heading 1.1.1.1.2", + "^^^^^^^^^^^^^^^^^", + "Heading 1.2", + "-----------", + "Heading 2", + "=========", + "Heading 2.1", + "-----------", + "Heading 2.2", + "-----------", + "Heading 2.2.1", + "+++++++++++++", + ] + + check = HeadingLevelsCheck() + check.run("goodFile.rst", good_headings) + self.assertListEqual(check.findings, []) + + def test_bad_heading_levels(self): + bad_headings = [ + "Heading 1", + "=========", + "Heading 1.1", + "-----------", + "Heading 1.1.1.1", + "~~~~~~~~~~~~~~~", + "Heading 1.1.1.1.1", + "^^^^^^^^^^^^^^^^^", + "Heading 1.1.1.1.1.1", + '"""""""""""""""""""', + "Heading 1.1.1.1.1.2", + '"""""""""""""""""""', + "Heading 1.1.1.1.2", + "^^^^^^^^^^^^^^^^^", + "Heading 1.2", + "-----------", + "Heading 2", + "=========", + "Heading 2.1", + "-----------", + "Heading 2.2.1.1.1", + "^^^^^^^^^^^^^^^^^", + ] + + findings = [ + HeadingLevelsFinding("badFile.rst", 6, expected_char="+", actual_char="~").as_str(True), + HeadingLevelsFinding("badFile.rst", 22, expected_char="+", actual_char="^").as_str( + True + ), + ] + + check = HeadingLevelsCheck() + check.run("badFile.rst", bad_headings) + + actual_findings = [f.as_str(True) for f in check.findings] + self.assertListEqual(actual_findings, findings) diff --git a/dox_style/tests/test_include_rst.py b/dox_style/tests/test_include_rst.py new file mode 100644 index 0000000..7fa355c --- /dev/null +++ b/dox_style/tests/test_include_rst.py @@ -0,0 +1,25 @@ +import unittest +from dox_style.checks.include_rst_check import IncludeRstCheck, IncludeRstFinding + + +class IncludeRstTest(unittest.TestCase): + def test_includes(self): + bad_headings = [ + ".. include:: x.rst", + "..include:: x.rst", + ". . include:: x.rst", + ".. include: : x.rst", + ".. include:: x.rstX", + ".. include :: x.rst", + ] + + findings = [ + IncludeRstFinding("badFile.rst", 1).as_str(True), + IncludeRstFinding("badFile.rst", 6).as_str(True), + ] + + check = IncludeRstCheck() + check.run("badFile.rst", bad_headings) + + actual_findings = [f.as_str(True) for f in check.findings] + self.assertListEqual(actual_findings, findings) diff --git a/dox_style/tests/test_top_level.py b/dox_style/tests/test_top_level.py new file mode 100644 index 0000000..18c29bc --- /dev/null +++ b/dox_style/tests/test_top_level.py @@ -0,0 +1,152 @@ +import unittest +from dox_style.checks.top_level_casing_check import TopLevelCasingCheck, TopLevelCasingFinding +from dox_style.checks.top_level_heading_check import ( + TopLevelHeadingCheck, + TopLevelHeadingFinding, +) +from dox_style.checks.top_level_length_check import TopLevelLengthCheck, TopLevelLengthFinding +from dox_style.checks.top_level_modulename_check import ( + TopLevelModuleNameCheck, + TopLevelModuleNameFinding, +) + + +class TopLevelModuleCasingTest(unittest.TestCase): + def test_correct_casing(self): + test_string = ["MyModule", "========", "Lorem ipsum"] + + check = TopLevelCasingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_incorrect_casing(self): + test_string = ["Mymodule", "========", "Lorem ipsum"] + + check = TopLevelCasingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + + asserted_result = [TopLevelCasingFinding("/path/to/MyModule/doc/index.rst", 1).as_str(True)] + findings = [x.as_str(True) for x in check.findings] + + self.assertListEqual(findings, asserted_result) + + def test_module_not_in_heading(self): + test_string = ["Some other top heading", "======================", "Lorem ipsum"] + + check = TopLevelCasingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_not_root_file(self): + test_string = ["Some other top heading", "======================", "Lorem ipsum"] + + check = TopLevelCasingCheck() + check.run("/path/to/MyModule/doc/subchapter/index.rst", test_string) + self.assertListEqual(check.findings, []) + + +class TopLevelHeadingTest(unittest.TestCase): + def test_correct_heading(self): + test_string = ["Heading", "======="] + + check = TopLevelHeadingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_no_heading(self): + test_string = ["This file has no heading", "42", "Lorem ipsum"] + + check = TopLevelHeadingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + + asserted_result = [ + TopLevelHeadingFinding("/path/to/MyModule/doc/index.rst", 1).as_str(True) + ] + findings = [x.as_str(True) for x in check.findings] + + self.assertListEqual(findings, asserted_result) + + def test_no_heading_underline_too_short(self): + test_string = ["Not a Heading", "==="] + + check = TopLevelHeadingCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_heading_in_no_root_file(self): + test_string = ["Heading", "======="] + + check = TopLevelHeadingCheck() + check.run("/path/to/MyModule/doc/subchapter/index.rst", test_string) + self.assertListEqual(check.findings, []) + + +class TopLevelLengthTest(unittest.TestCase): + def test_correct_heading(self): + test_string = ["Heading", "======="] + + check = TopLevelLengthCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_incorrect_length(self): + test_string = [ + "MyModule: this title is longer than 40 characters.", + "==================================================", + ] + + check = TopLevelLengthCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + + asserted_result = [ + TopLevelLengthFinding("/path/to/MyModule/doc/index.rst", 1, 40, 50).as_str(True) + ] + findings = [x.as_str(True) for x in check.findings] + + self.assertListEqual(findings, asserted_result) + + def test_heading_length_in_no_root_file(self): + test_string = [ + "Subchapter: This title is longer than 40 characters.", + "====================================================", + ] + + check = TopLevelLengthCheck() + check.run("/path/to/MyModule/doc/subchapter/index.rst", test_string) + self.assertListEqual(check.findings, []) + + +class TopLevelModuleNameTest(unittest.TestCase): + def test_correct_heading(self): + test_string = ["MyModule", "======="] + + check = TopLevelModuleNameCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_heading_with_wrong_casing(self): + test_string = ["MymOdule", "======="] + + check = TopLevelModuleNameCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + self.assertListEqual(check.findings, []) + + def test_heading_without_modulename(self): + test_string = ["Heading", "======="] + + check = TopLevelModuleNameCheck() + check.run("/path/to/MyModule/doc/index.rst", test_string) + + asserted_result = [ + TopLevelModuleNameFinding("/path/to/MyModule/doc/index.rst", 1, "MyModule").as_str(True) + ] + findings = [x.as_str(True) for x in check.findings] + + self.assertListEqual(findings, asserted_result) + + def test_heading_in_no_root_file(self): + test_string = ["Heading", "======="] + + check = TopLevelModuleNameCheck() + check.run("/path/to/MyModule/doc/subchapter/index.rst", test_string) + self.assertListEqual(check.findings, []) diff --git a/dox_style/tests/test_trailing_whitespace.py b/dox_style/tests/test_trailing_whitespace.py new file mode 100644 index 0000000..5e963d2 --- /dev/null +++ b/dox_style/tests/test_trailing_whitespace.py @@ -0,0 +1,27 @@ +import unittest +from dox_style.checks.trailing_whitespace_check import ( + TrailingWhitespacesCheck, + TrailingWhitespacesFinding, +) + + +class TrailingWhitespaceTest(unittest.TestCase): + def test_whitespaces(self): + test_string = [ + "", + "Lorem ipsum dolor sit amet, ", + "consectetur adipiscing elit,", + " ", + "sed do eiusmod tempor incididunt ut labore et dolore", + "magna aliqua.", + ] + + asserted_result = [ + TrailingWhitespacesFinding("index.rst", 2).as_str(True), + TrailingWhitespacesFinding("index.rst", 4).as_str(True), + ] + + check = TrailingWhitespacesCheck() + check.run("index.rst", test_string) + findings = [x.as_str(True) for x in check.findings] + self.assertListEqual(findings, asserted_result) diff --git a/dox_style/tests/test_underline_length_check.py b/dox_style/tests/test_underline_length_check.py new file mode 100644 index 0000000..58c90bc --- /dev/null +++ b/dox_style/tests/test_underline_length_check.py @@ -0,0 +1,35 @@ +import unittest +from dox_style.checks.underline_length_check import ( + UnderlineLengthFinding, + UnderlineLengthCheck, +) + + +class UnderlineLengthTest(unittest.TestCase): + def test_underline_lengths(self): + headings = [ + "Heading 1", + "=========", + "Heading 1.1", + "-----------", + "Heading 1.1.1", + "++++++++++++++", + "Lorem ipsum dolor sit amet", + "42", + "Heading 1.1.1.1", + "~~~~~~~~~~~~~~", + "Heading 1.1.1.1.1", + "^^^^^^^^^^^^^^^^^", + "Heading 2", + "=========", + ] + + asserted_result = [ + UnderlineLengthFinding("index.rst", 6).as_str(True), + UnderlineLengthFinding("index.rst", 10).as_str(True), + ] + + check = UnderlineLengthCheck() + check.run("index.rst", headings) + findings = [x.as_str(True) for x in check.findings] + self.assertListEqual(findings, asserted_result) diff --git a/dox_style/tests/test_utils.py b/dox_style/tests/test_utils.py new file mode 100644 index 0000000..75c4594 --- /dev/null +++ b/dox_style/tests/test_utils.py @@ -0,0 +1,33 @@ +import unittest +from dox_style.checks.utils import is_heading, is_index, get_module + + +class TrailingWhitespaceTest(unittest.TestCase): + def test_heading_regex(self): + self.assertTrue(is_heading("=====")) + self.assertTrue(is_heading("-")) + self.assertTrue(is_heading("''''''")) + self.assertTrue(is_heading("`````````")) + self.assertTrue(is_heading(":::::::::")) + self.assertTrue(is_heading('"""""')) + self.assertTrue(is_heading("~~~~~")) + self.assertTrue(is_heading("^^^^^")) + self.assertTrue(is_heading("______")) + self.assertTrue(is_heading("*****")) + self.assertTrue(is_heading("+++++++++")) + self.assertTrue(is_heading("#########")) + self.assertTrue(is_heading("<<<<<<<<<")) + self.assertTrue(is_heading(">>>>>>>>>")) + self.assertFalse(is_heading("==-==")) + self.assertFalse(is_heading("><><><")) + self.assertFalse(is_heading("----- Lorem Ipsum")) + self.assertFalse(is_heading("Lorem Ipsum #######")) + + def test_module_name(self): + self.assertTrue(is_index("/path/to/lib/ModuleName/doc/index.rst")) + self.assertFalse(is_index("/path/to/lib/ModuleName/doc/subdir/index.rst")) + self.assertFalse(is_index("/path/to/lib/ModuleName/doc/subchapter.rst")) + + self.assertEqual(get_module("/path/to/lib/ModuleName/doc/index.rst"), "ModuleName") + self.assertEqual(get_module("/path/to/lib/ModuleName/doc/subdir/index.rst"), None) + self.assertEqual(get_module("/path/to/lib/ModuleName/doc/subchapter.rst"), None) diff --git a/dox_trace/.gitignore b/dox_trace/.gitignore new file mode 100644 index 0000000..03ab640 --- /dev/null +++ b/dox_trace/.gitignore @@ -0,0 +1,4 @@ +build +.coverage +htmlcov +export_root diff --git a/dox_trace/LICENSE b/dox_trace/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/dox_trace/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/dox_trace/MANIFEST.in b/dox_trace/MANIFEST.in new file mode 100644 index 0000000..f811535 --- /dev/null +++ b/dox_trace/MANIFEST.in @@ -0,0 +1,2 @@ +exclude documentation/** +exclude MANIFEST.in diff --git a/dox_trace/README.md b/dox_trace/README.md new file mode 100644 index 0000000..4738e39 --- /dev/null +++ b/dox_trace/README.md @@ -0,0 +1,3 @@ +# Overview + +dox_trace adds specification directives to achieve traceability in Sphinx documentations. diff --git a/dox_trace/Rakefile.rb b/dox_trace/Rakefile.rb new file mode 100644 index 0000000..4088355 --- /dev/null +++ b/dox_trace/Rakefile.rb @@ -0,0 +1 @@ +require_relative 'spec/framework/testmain.rb' diff --git a/dox_trace/documentation/.gitignore b/dox_trace/documentation/.gitignore new file mode 100644 index 0000000..63ab5ab --- /dev/null +++ b/dox_trace/documentation/.gitignore @@ -0,0 +1,3 @@ +source/pages/requirements-generated +build +footer.yaml diff --git a/dox_trace/documentation/Makefile b/dox_trace/documentation/Makefile new file mode 100644 index 0000000..7066faa --- /dev/null +++ b/dox_trace/documentation/Makefile @@ -0,0 +1,14 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + ruby ../../dim/bin/dim export -i ../req/config.dim -o source/pages/requirements-generated -f rst + ruby createMapping.rb + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/documentation/createMapping.rb b/dox_trace/documentation/createMapping.rb new file mode 100644 index 0000000..f73c0d5 --- /dev/null +++ b/dox_trace/documentation/createMapping.rb @@ -0,0 +1,121 @@ +STDOUT.sync = true + +# get annotations from test cases +require_relative '../Rakefile.rb' +require 'json' +Dir.chdir("..") do + $dry_run = true + Rake.application['test:spec'].invoke() +end +f = File.read(File.dirname(__FILE__) + "/source/pages/requirements-generated/mapping.json") +refdReqs = JSON.parse(f) +testCases = {} +refdReqs.each do |id, tcs| + tcs.each do |tc| + testCases[tc["location"]] ||= [] + testCases[tc["location"]] << id if id != "" + end +end + +# get requirement IDs +require_relative '../../dim/lib/dim/loader.rb' +loader = Dim::Loader.new +loader.load(file: File.dirname(__FILE__) + "/../req/config.dim") +reqs = loader.requirements.values.select{|r| r.type == "requirement"} +reqIDs = reqs.map{|r| r.id} + +# write mapping page +File.open(File.dirname(__FILE__) + "/source/pages/requirements-generated/mapping.rst", "w") do |f| + f.puts "Test Case Mapping" + f.puts "=================" + f.puts "" + f.puts ".. list-table::" + f.puts " :width: 100%" + f.puts " :widths: 30 25 50" + f.puts " :header-rows: 1" + f.puts "" + f.puts " * - Requirements ID" + f.puts " - Test Case Location" + f.puts " - Test Case Description" + + reqIDs.each do |r| + f.puts " * - :ref:`#{r} <#{r}>`" + if refdReqs.include?(r) + refdReqs[r].each_with_index do |data, i| + f.puts " * -" if i > 0 + f.puts " - #{data["location"]}" + f.puts " - #{data["description"]}" + end + else + f.puts " - :red:`[missing]`" + f.puts " - :red:`[missing]`" + end + end +end + +# write stats page +File.open(File.dirname(__FILE__) + "/source/pages/requirements-generated/stats.rst", "w") do |f| + f.puts "Statistics" + f.puts "==========" + f.puts "" + f.puts "Requirements" + f.puts "------------" + f.puts "" + f.puts ".. list-table::" + f.puts " :width: 100%" + f.puts " :widths: 50 50" + f.puts "" + + f.puts " * - Total number of requirements" + f.puts " - #{reqs.length}" + + f.puts " * - Valid requirements" + f.puts " - #{reqs.count{|r| r.status == "valid"}}" + + reqs_covered = reqs.select{|r| r.tags.uniq.include?("covered")} + f.puts " * - Covered requirements" + f.puts " - #{reqs_covered.length}" + (reqs-reqs_covered).each do |r| + f.puts " |br|:red:`#{r.id}`" + end + + reqs_tested = reqs.select{|r| r.tags.uniq.include?("tested")} + f.puts " * - Tested requirements" + f.puts " - #{reqs_tested.length}" + (reqs-reqs_tested).each do |r| + f.puts " |br|:red:`#{r.id}`" + end + + reqIDs_mapped = reqIDs.select{|r| refdReqs.has_key?(r)} + f.puts " * - Requirements mapped to test cases" + f.puts " - #{reqIDs_mapped.length}" + (reqIDs-reqIDs_mapped).each do |id| + f.puts " |br|:red:`#{id}`" + end + f.puts "" + + f.puts "Test Cases" + f.puts "----------" + f.puts "" + f.puts ".. list-table::" + f.puts " :width: 100%" + f.puts " :widths: 50 50" + f.puts "" + f.puts " * - Total number of test cases" + f.puts " - #{testCases.length}" + f.puts " * - Test cases with valid requirement IDs" + not_valid = testCases.select{|loc, ids| ids.any? {|id| !reqIDs.include?(id)}} + f.puts " - #{testCases.length - not_valid.length}" + not_valid.each do |loc, ids| + f.puts " |br|:red:`#{loc}`" + end + invalid = testCases.select{|loc, ids| ids.any? {|id| !reqIDs.include?(id)}} + f.puts " * - Test cases without invalid requirement IDs" + f.puts " - #{testCases.length - invalid.length}" + invalid.each do |loc, ids| + f.puts " |br|:red:`#{loc}`" + ids.each do |id| + f.puts " |br|- :red:`#{id}`" if !reqIDs.include?(id) + end + end +end diff --git a/dox_trace/documentation/footer.rb b/dox_trace/documentation/footer.rb new file mode 100644 index 0000000..8317ef1 --- /dev/null +++ b/dox_trace/documentation/footer.rb @@ -0,0 +1,24 @@ +require 'time' +require 'yaml' + +$stdout.sync = true + +def parseTime(time) + # input e.g.: 2022-12-24 11:59:59 +0100 + DateTime.parse(time).new_offset(0).strftime("%Y-%m-%d %H:%M:%S") +end + +data = {} +file_dir = File.dirname(__FILE__) +Dir.chdir(file_dir + "/..") do + branch = `git branch --show-current`.strip + remote = `git remote get-url origin`.strip.gsub(/\/\/.*@/, '//') # assuming origin + folder = `git rev-parse --show-prefix`.strip.gsub(/\/$/, '') + time_sha1 = `git log -n 1 --pretty="format:%cd|%h" --date=iso -- . 2>&1`.split("|") + time = parseTime(time_sha1[0]) + sha1 = time_sha1[1] + + data["."] = "Based on #{remote}, folder #{folder}, from #{time}, commit #{sha1}." +end + +File.write(file_dir + "/footer.yaml", data.to_yaml) diff --git a/dox_trace/documentation/properties.yaml b/dox_trace/documentation/properties.yaml new file mode 100644 index 0000000..df1dd0d --- /dev/null +++ b/dox_trace/documentation/properties.yaml @@ -0,0 +1,7 @@ +_default_: { key3: value3 } +SMD_cpp2can: { asil: QM, cal: CAL_1 } +SWA: { developer: MyCompany } + +ID1: + key1: value1 + key2: value2 diff --git a/dox_trace/documentation/requirements.txt b/dox_trace/documentation/requirements.txt new file mode 100644 index 0000000..d02595c --- /dev/null +++ b/dox_trace/documentation/requirements.txt @@ -0,0 +1,9 @@ +Sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinx-copybutton==0.5.2 +sphinxcontrib-jquery==4.1 +Pygments==2.17.2 +docutils==0.20.1 +PyYAML==6.0.1 +packaging==21.3 ; python_version < "3.11" +packaging==23.2 ; python_version >= "3.11" diff --git a/dox_trace/documentation/source/conf.py b/dox_trace/documentation/source/conf.py new file mode 100644 index 0000000..5b2dea8 --- /dev/null +++ b/dox_trace/documentation/source/conf.py @@ -0,0 +1,58 @@ +import sys +from pathlib import Path +from datetime import datetime + +EXTENSION_ROOT = Path("../../..") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +project = "dox_trace" +author = "Accenture" +copyright = ( + f"{datetime.now().year} Accenture. All rights reserved. " + f"Accenture proprietary and confidential material" +) + +global __version__ +exec(open(f"../../{project}/version.py", "r").read(), globals()) +version = __version__ + +html_context = {"document_status_default": "Released", "data_classification_default": None} + +extensions = [ + "sphinxcontrib.jquery", + "dox_style", + "dox_trace", +] + +exclude_patterns = ["pages/requirements-generated/index*"] + +numfig = True + +dox_trace_allow_deprecated = True +dox_trace_allow_undefined_refs = True + +dox_trace_properties_file = "properties.yaml" + +dox_style_footer = "footer.yaml" + +# Note: the following option will be included to customAttributes.rst! +# START dox_trace_custom_attributes +dox_trace_custom_attributes = { + "custom_text": { + "directives": ["spec", "unit"], + "type": "text", + "default": "THIS IS THE DEFAULT VALUE", + }, + "custom_enum": { + "directives": ["spec", "unit"], + "type": "enum", + "default": ["x", "y"], + "export": "yes", + }, + "custom_refs": { + "directives": ["spec", "requirement"], + "categories": ["input"], + "type": "refs", + }, +} +# END dox_trace_custom_attributes diff --git a/dox_trace/documentation/source/index.rst b/dox_trace/documentation/source/index.rst new file mode 100644 index 0000000..1f0079b --- /dev/null +++ b/dox_trace/documentation/source/index.rst @@ -0,0 +1,95 @@ +dox_trace +========= + +dox_trace is a Sphinx extension to achieve traceability in software projects. + +.. figure:: pages/_static/trace.drawio.png + :scale: 100% + :align: center + +If you are new to this extension, please begin with **Getting Started**. This chapter provides an +introduction to this tool, explains how to install it and what is required to successfully integrate +*dox_trace* into the project's toolchain. + +The **User Documentation** is obviously the main source of information for users of this extension. +It describes details like the syntax and which values are calculated. + +Maintainers, testers, functional safety managers and whoever wants to know more about the internals +of this tool please refer to **Requirements**, **Architecture** and **Development of dox_trace**. + +.. toctree:: + :maxdepth: 1 + :caption: Getting Started + :hidden: + + pages/started/introduction + pages/started/installation + pages/started/integration + +.. toctree:: + :maxdepth: 1 + :caption: User Documentation + :hidden: + + pages/user/directives + pages/user/explicitAttributes + pages/user/customAttributes + pages/user/calcedValues + pages/user/parentValues + pages/user/newlines + pages/user/rawhtml + pages/user/properties + pages/user/traceability + pages/user/export + pages/user/config + pages/user/enclosed + pages/user/unintended + pages/user/backward + +.. toctree:: + :maxdepth: 1 + :caption: Examples + :hidden: + + pages/examples/specifications + pages/examples/report + pages/examples/undefined_refs + +.. toctree:: + :maxdepth: 1 + :caption: Requirements + :hidden: + + pages/requirements-generated/dox_trace/Requirements + pages/requirements-generated/mapping + pages/requirements-generated/stats + pages/requirements/reqConfig + +.. toctree:: + :maxdepth: 1 + :caption: Architecture + :hidden: + + pages/architecture/inout + pages/architecture/usecases + pages/architecture/static + pages/architecture/dynamic + pages/architecture/fmea + pages/architecture/legend + +.. toctree:: + :maxdepth: 1 + :caption: Development of dox_trace + :hidden: + + pages/development/ci + pages/development/bugTracking + pages/development/release + +.. toctree:: + :maxdepth: 1 + :caption: Appendix + :hidden: + + pages/appendix/changelog + pages/appendix/config diff --git a/dox_trace/documentation/source/pages/_static/example.png b/dox_trace/documentation/source/pages/_static/example.png new file mode 100644 index 0000000000000000000000000000000000000000..45db20ae153e5804e63b744b08779c3eb4bcbba9 GIT binary patch literal 2410 zcmd5;X*kr29{!JV(u@(x5Xu^2WJ!e6xX7L?i5dH3>@>=#=GZ&v;E)o9Y-NiX+gM_n zp;XFPk~3wWWN-$I_~*&pZnq7Z}+($e#`qjzvuTn@AH0m-*o4THc+rE7ytmM zo$Yy7006=F_I#0__BzI^_2b?EMZ4Nq0QH0NtUa(l*xb<^0GjSXcF@9m_+XSRDjER9 zUj4H`QX2M203h#U_n7+ zF;)LXI6qunL=%V!2(;$N!_dNt547YuYjwSx{UzK1zN|`%b!fOE0oax)l$uVa=O?8| zC5cBC%v=i0az%r>S9LWSYwCf`VI$KQLRuJ@0>EGFE1Z^s(WR1<_!yDs|HR|J68&Es z5J>izbEWSvU&)hwhF&DGd5!~xOlRm*RYH0N4`of@n}0!&@iB7 zz%r?hE-0EsVsrDk(VsfP;)#Zq(;lMNIXMU-wYzs-+~_fR>x2nmYpnK}W5jo_h_?B* zbXufU9<+6|LCmG;`-tRCifuV>bmw!s!Lp5DE$#8hIFHcSc9iMJ|e#dTcx z_~VhfaV0}C=6K!AwswNj5UWQcpWc(V6T2fYJdJ`^jm^689TB+#pRL|oDtD@_w(b;S zv^T~mk4t1}^Bh&}A-HN)ZGn{B(0Q$~E=D>!Z-MhPhVty#obrUxY2C7;yR)C ze30eD2)?*^gOf7A>l9`?}*#7ACP3sKj>qEDMB`(aSam{IwlZy0WldZ5Ro%|vC`ll}@RH?249d^$K~V!7ra_5*|D9bj<3o_Z zvpzcBIFB{gipMp_;vtVy3}GH`5GyMR1HL?4CcDzsQID+mB-I;bu5kR-_HQC^DcE|; zNksg5oQrRarq&Uagpfydq0M>94eK#g4_#rXc+LB%@PV_-Oq6fDB&~M+>zzitjsi)C zxBCTa?jPEOw7+*iO`KX8DfZs;YTr@(Sc~Jk&yjwaIhlJO`gQwcKTUbi&g$IA+u9-4 zT~@ruZNH*ZF`6a8PGm0pln4=WfF9Ohc+54jcdh4*c$dvL?lEwFQvG>7FFl=+Jtp`B zuKXvIMQsbyF=O~k7>lyHE6L;eZGG70ua0u%cJ~V{weys)6U2xKSg8^+QfL>)V{nQ? zoC<0Q@QC^_bM%nlme`W!PF)K-;CNfLamz3&`Bpu61+%BlZgXAg#lQ7MKI|gHR%x@` z$h208We=C8s{w*vrwEJ7cSFc6*j2xf@Y_?_x@APPpQ+8jfpJQ)dn=oq|0OcV(6us)yd-sD*XB5 zkJWVPZJBlL>55O{DEO4wgmH6`^D%lZ!zoU_H>hh+r>n-qO*o*{YP+TonV$DUMYH3Z#PwVTz~a;Qi+hpK;nlZ@ud=dxW? z)oL&#vv-1#ZKC8hNd$hTZ5_y!0tTsKqD$kI*L)VJnx+)W)L?Qa8`T17YmRGoccK83zP4@M%3 z;+*7s>MUK=UP)wk^Eu1e9D|5O=#v|(mkLpiU9+Twi~yk_EiKIrXD&mBkAky5kWZ4= zE%|Q&NHX{3Wwr4M#Gje!ClkX)bwOC@f$!>_Y?#I3xjhVHc*ID@ z#oh~B=*G*d#B|0UjKzB1oeDolc{Z~!jH7zXNS4qq{KA-dO??tXeG|X(I_d@1-8d8% zW;6OjM)$~uJS-uGF3n=bQnNPI;uH3{rc*J81_QfePlx!3zRVHtRybU!?e_odFO+@Z z`URM~fTDM)=o*;NGm~>pC~1S$C!3Z6{2_A$DGCAoZJhh+h;Aw^KuQQrwDeiEOIk__ z3{bEnDQh%(AG8etMO_O_Sxu#U0cU;?5)b>m(LPIGwWZS3ItpYPGiPp#tlabPp-ge_ z?uD58p&zePoRF{S;`V?AH>>!i<*Q`;fiJm7?;m~IkCyNRIxCFz4799^a0&szz)tbo zzOf-r& I3;)}H0Wa}divR!s literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/intro.drawio.png b/dox_trace/documentation/source/pages/_static/intro.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..3fb8c5cfa632fdd9d0dddd9c11b2a7ed2e7bcb00 GIT binary patch literal 26591 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 literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/module1/doc/index.rst b/dox_trace/documentation/source/pages/_static/module1/doc/index.rst new file mode 100644 index 0000000..3362b7b --- /dev/null +++ b/dox_trace/documentation/source/pages/_static/module1/doc/index.rst @@ -0,0 +1,6 @@ +:orphan: + +module1 +======= + +Documentation of module1. diff --git a/dox_trace/documentation/source/pages/_static/module1/include/source1.h b/dox_trace/documentation/source/pages/_static/module1/include/source1.h new file mode 100644 index 0000000..c6cac69 --- /dev/null +++ b/dox_trace/documentation/source/pages/_static/module1/include/source1.h @@ -0,0 +1 @@ +empty diff --git a/dox_trace/documentation/source/pages/_static/module1/include/source2.h b/dox_trace/documentation/source/pages/_static/module1/include/source2.h new file mode 100644 index 0000000..c6cac69 --- /dev/null +++ b/dox_trace/documentation/source/pages/_static/module1/include/source2.h @@ -0,0 +1 @@ +empty diff --git a/dox_trace/documentation/source/pages/_static/module2/doc/index.rst b/dox_trace/documentation/source/pages/_static/module2/doc/index.rst new file mode 100644 index 0000000..8099bc8 --- /dev/null +++ b/dox_trace/documentation/source/pages/_static/module2/doc/index.rst @@ -0,0 +1,6 @@ +:orphan: + +module2 +======= + +Documentation of module2. diff --git a/dox_trace/documentation/source/pages/_static/swa/appendix/legend.drawio.png b/dox_trace/documentation/source/pages/_static/swa/appendix/legend.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..432c1716e4eaa7bb194c34db1115fd0200ba3efa GIT binary patch literal 34868 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

aTlu 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 IfA!)20q_UD9RL6T literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/dynamic/dh_create.drawio.png b/dox_trace/documentation/source/pages/_static/swa/dynamic/dh_create.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..4d00229d03e306c469034a28d44d1c303b79d7ed GIT binary patch literal 29766 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 rI>8B9->);YVNM{H`p8<|)$=v}Q literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/dynamic/dh_export.drawio.png b/dox_trace/documentation/source/pages/_static/swa/dynamic/dh_export.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..4239a4d2aabfcd29da3d17c0d96a435f9bf3a061 GIT binary patch literal 49147 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 literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/overview/inout.drawio.png b/dox_trace/documentation/source/pages/_static/swa/overview/inout.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..70e4b7be9d3c7a62f9ab61c4427b7fc0de897c4f GIT binary patch literal 43133 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 SXU9|+fWXt$&t;ucLK6U7@wbuy literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/overview/static.drawio.png b/dox_trace/documentation/source/pages/_static/swa/overview/static.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..0d78976f18799a271eb9b53926859b5541c3027c GIT binary patch literal 163558 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⪚kaDj-je0z#7LIb{lW% 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 literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_export.drawio.png b/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_export.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..53510866796f39cb2bd2fcd3187d7af97cf61165 GIT binary patch literal 30689 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 literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_review.drawio.png b/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_review.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..2104f57fc99862a3f0dfc1cf0ed257b9955c7991 GIT binary patch literal 167960 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 z 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%0DX{2; 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 SHbx5J&(gx${O)qc!+!vfS$$Uk literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_view.drawio.png b/dox_trace/documentation/source/pages/_static/swa/usecases/usecase_view.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..942ea674d8741af2824ecc2b5ed73b8dad21f0eb GIT binary patch literal 31182 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 z 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 NYqHnT`O^0u|1U;PeuDr2 literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/_static/types.drawio.png b/dox_trace/documentation/source/pages/_static/types.drawio.png new file mode 100644 index 0000000000000000000000000000000000000000..6b4429730da0096f8aae38fad4562f0df98c85b1 GIT binary patch literal 29533 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 R_+I8JT}>m6Qj$aHe*?{CmLvcG literal 0 HcmV?d00001 diff --git a/dox_trace/documentation/source/pages/appendix/changelog.rst b/dox_trace/documentation/source/pages/appendix/changelog.rst new file mode 100644 index 0000000..32d6a71 --- /dev/null +++ b/dox_trace/documentation/source/pages/appendix/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +3.0.0 +----- + +October 23, 2024 + +- Initial public release. diff --git a/dox_trace/documentation/source/pages/appendix/config.rst b/dox_trace/documentation/source/pages/appendix/config.rst new file mode 100644 index 0000000..9413fcf --- /dev/null +++ b/dox_trace/documentation/source/pages/appendix/config.rst @@ -0,0 +1,48 @@ +.. _dox_trace_config: + +Configuration +============= + +Settings +-------- + +.. dox_trace_config:: + +Preview +------- + +Different specification types without any explicit value set: + +.. requirement:: Input_ConfigPreview_Requirement + :category: input + :ignore_in_export: + +.. information:: Input_ConfigPreview_Information + :category: input + :ignore_in_export: + +.. requirement:: SRS_ConfigPreview_Requirement + :category: software + :ignore_in_export: + +.. information:: SRS_ConfigPreview_Information + :category: software + :ignore_in_export: + +.. srs:: SRS_ConfigPreview_Srs + :ignore_in_export: + +.. spec:: SWA_ConfigPreview_Spec + :ignore_in_export: + +.. mod:: SWA_ConfigPreview_Mod + :ignore_in_export: + +.. interface:: SWA_ConfigPreview_Interface + :ignore_in_export: + +.. unit:: SMD_ConfigPreview_Unit + :ignore_in_export: + +.. interface:: SMD_ConfigPreview_Interface + :ignore_in_export: diff --git a/dox_trace/documentation/source/pages/architecture/dynamic.rst b/dox_trace/documentation/source/pages/architecture/dynamic.rst new file mode 100644 index 0000000..811cf6a --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/dynamic.rst @@ -0,0 +1,143 @@ +Dynamic Behaviour +================= + +.. _workflow: + +Main Workflow +------------- + +The main workflow is a sequence of five major steps which are explained in more detail in the +sections below. + +.. _workflow_main_fig: + +.. figure:: ../_static/swa/dynamic/workflow.drawio.png + :scale: 100% + :align: center + + Main workflow + +All input and output is directly accessed by the user of this tool except the **cache**. +The cache is created by Sphinx to increase the speed of incremental builds. Files which have not +changed since the last build usually don't have to be read again. *dox_trace* enriches the cache +with *specification* data to resolve references, perform consistency checks and export data to +*Dim*. + +In general, **exceptions** are not caught. If an exceptions occurs, Sphinx terminates and sets the +exit code to a value != 0 depending on the exception type. + +.. _setup_dox_trace: + +Setup dox_trace +--------------- + +.. figure:: ../_static/swa/dynamic/dh_setup.drawio.png + :scale: 100% + :align: center + + Setup dox_trace + +Setting up *dox_trace* is straightforward: + +- First, the source files are loaded by the Python interpreter. +- Afterwards Sphinx calls the *setup* function which is mandatory for every extension. This function + registers callbacks to certain Sphinx events, directives and roles. +- The first event is *config-inited* which allows to add additional stuff to the Sphinx + configuration. *dox_trace* registers a CSS and a Javascript file for the HTML output. +- If the *dox_trace* extension itself has changed, it is not ensured that the data in the cache is + still compatible, so *dox_trace* enforces a reload of all RST files. +- The cache, internally also called *environment*, is getting prepared by creating some data + structures which are used later by dox_trace. +- Data from RST files which are going to be read again is deleted from the cache. + +Parse RST Files +--------------- + +.. figure:: ../_static/swa/dynamic/dh_parse.drawio.png + :scale: 100% + :align: center + + Parse RST files + +After the *environment* is prepared in :ref:`setup_dox_trace`, the new and changed RST files can be +read: + +- Sphinx calls the registered classes and functions for the following elements found in RST files: + + - most importantly the *specification* directives: + + - ``.. requirement::`` + - ``.. information::`` + - ``.. srs::`` + - ``.. spec::`` + - ``.. mod::`` + - ``.. interface::`` + - ``.. unit::`` + + - the ``.. dox_trace_config::`` directive which generates a page to configure the appearance of + the *specifications* + - the ``.. traceability_report::`` directive which generates a traceability report + - the ``.. unresolved_refs::`` directive which generates a list of specifications with + unresolved references + - the ``.. prop::`` directive and ``:prop:`` role which display a property + - internally used roles to create nice literals in HTML output with type and ID of + *specifications* which can be linked by regular Sphinx references. + + These functions convert the data to "Docutils" nodes, the underlying document structure used by + Sphinx. + +- The Sphinx syntax for directives is very close to the comment syntax, which means a + *specification* may be commented out unintentionally. To avoid that, a check is implemented to + find comments which look similar to a *specification* directive. +- After all files are parsed, upstream and downstream references can be calculated. They are + injected into the already created "Docutils" node structure. +- Finally the data is stored in the cache. +- In parallel (multi-threaded) builds a separate cache section is created by Sphinx for every parsed + RST files to avoid critical sections. After reading all files, these sections must be merged. +- If an error occurs, a meaningful error message is printed out and the build is aborted. + +Check Consistency +----------------- + +.. figure:: ../_static/swa/dynamic/dh_check.drawio.png + :scale: 100% + :align: center + + Check consistency + +After all data is loaded, the following checks are performed: + +- References in Sphinx are internally converted to lower case, which means the references are + case insensitive. But when exporting to *Dim*, the case matters, so *dox_trace* ensures that the + case is always correct. +- *Specifications* can link to other *specifications* using their ``refs`` attribute. dox_trace + ensures that the targets are really *specifications* and not regular Sphinx anchors. +- Cyclic references are disallowed to avoid problems in further processing of the data like + generating metrics. + +If a check fails, a meaningful error message is printed out and the build is aborted. + +Generate HTML Output +-------------------- + +.. figure:: ../_static/swa/dynamic/dh_create.drawio.png + :scale: 100% + :align: center + + Generate HTML output + +This step is completely done by Sphinx, the *dox_trace* extension is not involved directly. In case +of an error, Sphinx prints an error message and aborts the build. + +Export to Dim +------------- + +.. figure:: ../_static/swa/dynamic/dh_export.drawio.png + :scale: 100% + :align: center + + Export to Dim + +If the Sphinx configuration includes a variable ``dox_trace_dim_root`` pointing to a valid +directory, *dox_trace* exports the *specification* data of srs, spec, mod, interface and unit to +*Dim* files. If an error occurs, a meaningful error message is printed out and the build is aborted. diff --git a/dox_trace/documentation/source/pages/architecture/fmea.rst b/dox_trace/documentation/source/pages/architecture/fmea.rst new file mode 100644 index 0000000..fcc63fc --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/fmea.rst @@ -0,0 +1,87 @@ +FMEA +==== + +The FMEA is done on the "first zoom level" of the architecture, the +:ref:`main workflow `. + +The relevant elements are annotated by oval labels, see also the :ref:`diagram legend `. + +Fault Model +----------- + +The following analysis is based on this generic *fault model* for activity diagrams: + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + :width: 100% + + * - Element Type + - Error ID + - Generic Error Description + * - Data storage + - DS1 + - Stored data changed before read operation + * - + - DS2 + - New data not stored / keeps old data / stuck at specific value + * - Data flow + - DF1 + - Transferred data changed + * - + - DF2 + - Transferred data lost + * - + - DF3 + - Data stored at / read from wrong location in data store + * - + - DF4 + - Data transferred to wrong data store + * - Processing + - PR1 + - Calculates wrong results + * - + - PR2 + - Processing is skipped + * - + - PR3 + - Processing too slow/fast + * - Control flow + - CF1 + - Control flow stops + * - + - CF2 + - Control flow proceeds to wrong process + +If more than one error is identified for the same element with the same error ID, a counter is +added, e.g. `PR1.1`, `PR1.2`, etc. + +In the following sections, references to files are shown which end with ``_spec.rb``. These files +are test files which can be found in the ``spec`` folder of the *dox_trace* extension, e.g. +``/spec/asil_spec.rb``. + +Generalized Errors +------------------ + +The following errors are analyzed generically and not on architectural element level. + +.. csv-table:: + :file: fmea/general.csv + :header-rows: 1 + :widths: 12 30 32 + :width: 100% + :delim: , + +.. _fmea_command_line_workflow: + +Main Workflow +------------- + +This analysis is done on the :numref:`workflow_main_fig` with the :ref:`use_cases` in mind. + +.. csv-table:: + :file: fmea/dynamic.csv + :header-rows: 1 + :widths: 5 5 25 35 25 + :width: 100% + :delim: , diff --git a/dox_trace/documentation/source/pages/architecture/fmea/dynamic.csv b/dox_trace/documentation/source/pages/architecture/fmea/dynamic.csv new file mode 100644 index 0000000..c827268 --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/fmea/dynamic.csv @@ -0,0 +1,69 @@ +Element ID,Error ID,Specific Error Description,Measures,References +p1,PR1.1,Cache is not prepared properly which could lead to undefined behaviour.,"- If the cache is not prepared properly, subsequent read and write calls will result in exceptions due to missing data structures which means Sphinx is terminated with exit code != 0. +- The verifier executes a complete build to avoid problems with incremental builds.","- Cache access is implicitly tested by almost every test case. +- :ref:`Integration Guide `" +,PR1.2,The version is not determined correctly which may lead in using incompatible cache data.,"This is only relevant if the extension is updated. + +- It's likely that an exception occurs due to incompatible cache data. +- The verifier executes a complete build to avoid problems with incremental builds. +- Tested by unit tests.",:ref:`Integration Guide ` +,PR2,Callbacks or directives are not registered which means the extension is not active.,"When trying to parse specifications, Sphinx will raise an exception due to unknown directives and terminate with exit code != 0.",":file:`*_spec.rb` +" +p2,PR1.1,Files are loaded incorrectly or not loaded completely.,"- In most cases syntax and consistency checks within the loader will recognize the errors and Sphinx will terminate with exit code != 0. +- Users have to review the output. +- Tested by unit tests.","- :file:`checks_spec.rb` +- :ref:`Integration Guide `" +,PR1.2,Wrong files are loaded.,"- In almost every case random files are neither syntactically correct nor consistent which will lead to loading errors. +- Users have to review the output.",:ref:`Integration Guide ` +,PR2,"If loading is skipped, no specifications are available for subsequent steps.",This is recognized by the user or latest by the reviewer in the code review tool because the HTML output and the Dim export will be empty.,:ref:`Integration Guide ` +p3,PR1,Consistency checks are passed even with inconsistent data.,"- In most cases inconsistent data will lead to exceptions in further processing of the data, e.g. due to unresolved references. +- Users have to review the output. +- Tested by unit tests.","- :file:`checks_spec.rb` +- :ref:`Integration Guide `" +,PR2,Consistency checks are not executed.,:greyitalic:`see p3/PR1`,:greyitalic:`n/a` +p4,PR1,HTML output is wrong.,"- Users have to review the output. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +,PR2,HTML output is missing or stored at wrong location.,"- Users have to review the output. +- Missing output is detected by the verifier. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +p5,PR1,Dim export is wrong.,"- Syntactically wrong Dim files are recognized by the verifier during the `dim check`. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +,PR2,Dim export is missing or stored at wrong location.,"- Users have to review the output. +- Recognized by the verifier during the `dim check`. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +p6,PR1,The exit code is set to a value != 0 instead of 0.,"- An exit code != 0 indicates an error. The code review tool will reject the commit. +- Tested by unit tests.","- In almost every unit test the exit code is checked. +- :ref:`Integration Guide `" +,PR2,The exit code is not set explicitly which means it can be != 0 instead of 0.,:greyitalic:`see p6/PR1`,:greyitalic:`n/a` +p7,PR1,The exit code is set to 0 instead of != 0.,Tested by unit tests.,In almost every unit test the exit code is checked. +,PR2,The exit code is not set explicitly which means it can be 0 instead of != 0.,:greyitalic:`see p7/PR1`,:greyitalic:`n/a` +"s1, s8",DS1.1,Wrong specification data is loaded.,"- In most cases syntax and consistency checks within the loader will recognize the errors and Sphinx will terminate with exit code != 0. +- Users have to review the output. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +,DS1.2,Files do not exist in the file system.,"If files do not exist, Sphinx will terminate with an exit code != 0.",:ref:`Integration Guide ` +,DS2,":greyitalic:`n/a, only read access`",:greyitalic:`n/a`,:greyitalic:`n/a` +s2,DS1,The cache is corrupted.,"- In most cases consistency checks will recognize the errors and Sphinx will terminate with exit code != 0. It is also likely that the Dim export will produce incorrect Dim files which is recognized by a `dim check`. +- Users have to review the output.",:ref:`Integration Guide ` +,DS2,The cache is not updated.,"- If the cache is not prepared properly, subsequent read and write calls will result in exceptions due to missing data structures which means Sphinx is terminated with exit code != 0. +- The verifier executes a complete build to avoid problems with incremental builds.",:ref:`Integration Guide ` +s3,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Existing HTML files are not updated.,:greyitalic:`see p4/PR2`,:greyitalic:`n/a` +s4,DS1.1,Dim export is missing or stored at wrong location.,:greyitalic:`see p5/PR1 and p5/PR2`,:greyitalic:`n/a` +,DS1.2,Properties file is not loaded.,"Fallback values of all attributes are either empty or `not_set`, which means this is identified by manual review or automatic checks.",:ref:`Integration Guide ` +,DS1.3,Other configuration parameters e.g. regarding backward compatibility are not as intended.,"- In most cases this will lead to a parsing error and Sphinx will terminate with exit code != 0. +- Users have to review the output.",:ref:`Integration Guide ` +,DS2,":greyitalic:`n/a, only read access`",:greyitalic:`n/a`,:greyitalic:`n/a` +s5,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Existing Dim files are not updated correctly.,:greyitalic:`see p5/PR1 and p5/PR2`,:greyitalic:`n/a` +s6,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Wrong exit code is used.,:greyitalic:`see p6/PR2 and p7/PR2`,:greyitalic:`n/a` +s7,DS1,":greyitalic:`n/a, only write access`",:greyitalic:`n/a`,:greyitalic:`n/a` +,DS2,Error messages are wrong or not visible on the console.,"- The user might miss the information, but the exit code != 0 indicates that something went wrong. The verifier will reject the commit. +- Tested by unit tests.","- :file:`*_spec.rb` +- :ref:`Integration Guide `" +,,,, diff --git a/dox_trace/documentation/source/pages/architecture/fmea/general.csv b/dox_trace/documentation/source/pages/architecture/fmea/general.csv new file mode 100644 index 0000000..7fdde6a --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/fmea/general.csv @@ -0,0 +1,6 @@ +Error ID,General Error Description,Measures +"DF1, DF2, DF3",Data is corrupted or lost during file access or wrong files are accessed.,"This tool runs without network access or memory queues. It is assumed that underlying layers like Python or the OS are qualified. Potential issues with data are analyzed in ""Data storage"" and ""Processing"" elements." +DF4,"Every data store type exists only once in the system, e.g. `RST files` cannot be stored in `Exit code`.",Trying to do something like this will lead to a program exception. dox_trace will terminate with an exit code != 0. +PR3,"dox_trace has no timing constraints. But a too slow execution might frustrate the user, so that the user removes the mandatory check on the code review tool.",It's mentioned in the :ref:`Integration Guide ` of dox_trace that the verifier from the code review tool is mandatory and must not be removed or skipped. +CF1,A complete stop of the control flow is usually no problem for a tool which runs offline and not on the target hardware. dox_trace is used for verifying changes on a code review tool. A stopped or terminated Sphinx build due to timeout must not lead to a merged commit.,"It's mentioned in the :ref:`Integration Guide ` of dox_trace that the verifier from the code review tool must exit successfully, otherwise the commit must be rejected." +CF2,This is a very generic problem and can lead to random errors.,"The likelihood is reduced to a minimum by intensive unit tests. To ensure that enough unit tests are written, the code coverage is 100%." diff --git a/dox_trace/documentation/source/pages/architecture/inout.rst b/dox_trace/documentation/source/pages/architecture/inout.rst new file mode 100644 index 0000000..a032e3a --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/inout.rst @@ -0,0 +1,33 @@ +Input / Output +============== + +.. _figuretest: + +.. figure:: ../_static/swa/overview/inout.drawio.png + :scale: 100% + :align: center + + Input / output + +*dox_trace* is a Sphinx extension, which means most of the input and output goes through the Sphinx +API. + +File System +----------- + +- Sphinx parses **RST files** which may contain *specifications*. For every found *specification*, + callbacks are executed which are registered by *dox_trace* during the init-phase of the extension. +- Attribute values for *specifications* can be predefined in a **properties file**. +- These *specifications* are converted to *Docutils* nodes and stored by Sphinx in a **cache**. +- The cache is used by *dox_trace* to resolve references and to export the data to **Dim files**. +- This export is only done if the optional configuration parameter ``dox_trace_dim_root`` is set + in the Sphinx **configuration**. +- Sphinx generates **HTML files** representing the RST files including the *specifications*. + +Shell +----- + +- *dox_trace* has no command line option, but the **exit code** of Sphinx is != 0 whenever it + detects an error. +- If an error is detected, *dox_trace* uses **console output** to provide more information about the + error. diff --git a/dox_trace/documentation/source/pages/architecture/legend.rst b/dox_trace/documentation/source/pages/architecture/legend.rst new file mode 100644 index 0000000..9cd569f --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/legend.rst @@ -0,0 +1,12 @@ +.. _legend: + +Diagram Legend +============== + +The following diagram elements are used: + +.. figure:: ../_static/swa/appendix/legend.drawio.png + :scale: 100% + :align: center + + Legend diff --git a/dox_trace/documentation/source/pages/architecture/static.rst b/dox_trace/documentation/source/pages/architecture/static.rst new file mode 100644 index 0000000..4fdb75b --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/static.rst @@ -0,0 +1,60 @@ +Classes and Functions +===================== + +Overview +-------- + +.. figure:: ../_static/swa/overview/static.drawio.png + :scale: 100% + :align: center + + Static overview + +| This diagram shows all files of the *dox_trace* extension. +| The colors shall help to identify which parts are used in which step of the :ref:`workflow`. + +Files +----- + +- **dox_trace/_static/dox_trace.css**: Some style sheets to layout *specifications*. +- **dox_trace/_static/dox_trace.js**: Javascript code used by the config directive. +- **dox_trace/_static/yaml.py**: Helper to load YAML files. +- **dox_trace/__init__.py**: Technically the entry point of the dox_trace extension, following the + Python standard. It wraps the unit test code coverage functionality around the *main.py* file. +- **dox_trace/backward_refs.py**: Upstream and downstream references to *specifications* can only be + calculated after all RST files are read, which means the data has to be injected into the + "Docutils" node-tree. +- **dox_trace/checks.py**: Contains additional consistency checks. +- **dox_trace/config.py**: Registers the CSS and Javascript files and provides a config directive + which makes it possible to hide/show groups of attributes on-the-fly in already generated HTML + files. +- **dox_trace/coverage.py** The content of this file is usually not part of the extension, it's + opted-in by the unit test to measure the code coverage. +- **dox_trace/dim_write.py**: Exports the *specifications* to Dim files. +- **dox_trace/directives.py**: Most of the source code of this extension can be found in this file. + It consists of the *specification* directives which convert the textual representations of the + *specifications* into "Docutils" nodes for further processing by Sphinx like generating the HTML + files. +- **dox_trace/enclosed.py**: Provides the *enclosed* directive to copy files to the output folder. +- **dox_trace/env.py**: Simplifies the access of the Sphinx cache. +- **dox_trace/helper.py**: Used to understand parts of the *specifications* which already uses Sphinx + syntax. +- **dox_trace/main.py** Connects to different Sphinx events and triggers additional checks as well + as the Dim export. +- **dox_trace/properties.py** Provides a role and a directive to use properties standalone outside + *specifications*. +- **dox_trace/report\*.py**: These file are used to generate the traceability report. +- **dox_trace/roles.py**: Consists of roles which are temporarily used for a nicer HTML output of the + *specifications*. +- **dox_trace/undefined_refs.py**: List of unresolved references can only be calculated after + all RST files are read, which means the data has to be injected into the "Docutils" node-tree. + +Sphinx API +---------- + +*dox_trace* uses callbacks from the Sphinx *Application API* and the *Event Callbacks API* as +annotated in the diagram above. Please refer to the official Sphinx documentation to get more +information about the Sphinx procedures, especially when which event happens during a build: + +- Application API: https://www.sphinx-doc.org/en/master/extdev/appapi.html +- Event Callbacks API: https://www.sphinx-doc.org/en/master/extdev/event_callbacks.html diff --git a/dox_trace/documentation/source/pages/architecture/usecases.rst b/dox_trace/documentation/source/pages/architecture/usecases.rst new file mode 100644 index 0000000..3636d79 --- /dev/null +++ b/dox_trace/documentation/source/pages/architecture/usecases.rst @@ -0,0 +1,66 @@ +.. _use_cases: + +Use Cases +========= + +This page shows how dox_trace is used from a black box perspective. + +Generating HTML +--------------- + +Existing RST files including *specifications* are converted to HTML by executing Sphinx. The +resulting HTML files can then be viewed in a browser. + +.. figure:: ../_static/swa/usecases/usecase_view.drawio.png + :scale: 100% + :align: center + + Generating HTML + +Calculating Metrics +------------------- + +*Specifications* in existing RST files are exported to Dim format by executing Sphinx. With Dim +files various metrics can be calculated using the Dim Ruby API. + +It's explicitly allowed to process the Dim files for any other purpose, not only for calculating +metrics. + +.. figure:: ../_static/swa/usecases/usecase_export.drawio.png + :scale: 100% + :align: center + + Calculating metrics + +.. _changing_specifications: + +Changing Specifications +----------------------- + +RST files are text files, which can be changed by any editor. This requires to verify the changes: + +- Most of the errors like using an unknown attribute or cyclic references can be found by executing + Sphinx and checking the exit code and if necessary the console output. +- The values of the attributes can be *syntactically* verified by exporting to Dim format and + running the Dim checks. +- The generated HTML can be used to double check that the content is *semantically* correct. + +.. figure:: ../_static/swa/usecases/usecase_change.drawio.png + :scale: 100% + :align: center + + Change specifications + +Publishing Changes +------------------ + +This is similar to the :ref:`changing_specifications` use case. Instead of a local verification and +a self-review, the changes are pushed to a code review tool to trigger an official verifier and let +others review the changes. If both is successfully completed, the changes are merged into the +corresponding Git branches. + +.. figure:: ../_static/swa/usecases/usecase_review.drawio.png + :scale: 100% + :align: center + + Publishing changes diff --git a/dox_trace/documentation/source/pages/development/bugTracking.rst b/dox_trace/documentation/source/pages/development/bugTracking.rst new file mode 100644 index 0000000..e261d0c --- /dev/null +++ b/dox_trace/documentation/source/pages/development/bugTracking.rst @@ -0,0 +1,7 @@ +.. _bug_tracking: + +Bug Tracking and Feature Planning +================================= + +Bugs and new features are handled directly in https://github.com/esrlabs/dox. +In case you have found a bug or if you have feature request, please open a ticket. diff --git a/dox_trace/documentation/source/pages/development/ci.rst b/dox_trace/documentation/source/pages/development/ci.rst new file mode 100644 index 0000000..36a896e --- /dev/null +++ b/dox_trace/documentation/source/pages/development/ci.rst @@ -0,0 +1,9 @@ +Continuous Integration +====================== + +*dox_trace* is developed in https://github.com/esrlabs/dox. + +Every commit must be approved by a non-author. + +The unit test of *dox_trace* covers 100% of the code. Whenever the code changes, an automatic +verifier ensures that all tests are still passing. In case of a failing test the commit is rejected. diff --git a/dox_trace/documentation/source/pages/development/release.rst b/dox_trace/documentation/source/pages/development/release.rst new file mode 100644 index 0000000..9ebc906 --- /dev/null +++ b/dox_trace/documentation/source/pages/development/release.rst @@ -0,0 +1,11 @@ +Release +======= + +After all desired features and bug fixes including documentation and unit tests are merged to the +repository, a new version of the *dox_trace* extension can be released. + +- Increment the version in ``version.py``. +- Document the changes in ``documentation/source/pages/changelog.rst``. +- Merge these files to the repository. +- Upload the documentation. +- Announce the new version. diff --git a/dox_trace/documentation/source/pages/examples/contents/derivation.inc b/dox_trace/documentation/source/pages/examples/contents/derivation.inc new file mode 100644 index 0000000..ab72985 --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/derivation.inc @@ -0,0 +1,39 @@ +.. requirement:: Customer_DeriveParent_1 + :category: input + :asil: ASIL_B + :feature: F1 + :refs: SRS_DeriveParent_1 + :developer: Abc AG + :status: valid + :review_status: accepted + + Generated by Dim. + +.. requirement:: SRS_DeriveParent_1 + :refs: SWA_DeriveParent_1 + :asil: ASIL_C + :category: software + :developer: Abc AG + :status: valid + + Generated by Dim. + +.. srs:: SRS_DeriveParent_2 + :refs: SWA_DeriveParent_1 + :asil: ASIL_D + + Self-written in RST. + +.. spec:: SWA_DeriveParent_1 + :status: valid + :refs: SMD_DeriveParent_1 + + Self-written in RST. + + "Upstream Asil" only from direct parent, "Derived Feature" from complete tree. + +.. unit:: SMD_DeriveParent_1 + :status: valid + :sources: ../_static/module1/include/source2.h + + The unit description. diff --git a/dox_trace/documentation/source/pages/examples/contents/image.inc b/dox_trace/documentation/source/pages/examples/contents/image.inc new file mode 100644 index 0000000..7aa6c2f --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/image.inc @@ -0,0 +1,11 @@ +.. spec:: SWA_example_abc + :refs: SMD_example_xy + :asil: ASIL_A + :tags: integrity, covered, tested + :verification_criteria: Do carefully abc... + + Example SWA content... + + .. image:: ../_static/example.png + + Please look at :ref:`SMD_example_xy`. \ No newline at end of file diff --git a/dox_trace/documentation/source/pages/examples/contents/information.inc b/dox_trace/documentation/source/pages/examples/contents/information.inc new file mode 100644 index 0000000..2a437fb --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/information.inc @@ -0,0 +1,3 @@ +.. information:: Input_example_info + + Some information. diff --git a/dox_trace/documentation/source/pages/examples/contents/invalid.inc b/dox_trace/documentation/source/pages/examples/contents/invalid.inc new file mode 100644 index 0000000..9a2ece8 --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/invalid.inc @@ -0,0 +1,4 @@ +.. unit:: SMD_example_inv + :status: invalid + + *invalid* and *rejected* specifications are struck through. diff --git a/dox_trace/documentation/source/pages/examples/contents/modules.inc b/dox_trace/documentation/source/pages/examples/contents/modules.inc new file mode 100644 index 0000000..018077a --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/modules.inc @@ -0,0 +1,16 @@ +.. mod:: SWA_mod_module1 + :location: pages/_static/module1 + :reuse: yes + :usage: production + :developer: Abc AG + :status: valid + + Best module ever. + +.. mod:: SWA_mod_module2 + :location: pages/_static/module2 + :reuse: no + :usage: production + :developer: Supplier X + + Does this and that. diff --git a/dox_trace/documentation/source/pages/examples/contents/unit2source.inc b/dox_trace/documentation/source/pages/examples/contents/unit2source.inc new file mode 100644 index 0000000..785d77d --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/contents/unit2source.inc @@ -0,0 +1,6 @@ +.. unit:: SMD_example_xy + :sources: ../_static/module1/include/source2.h + :asil: ASIL_A + :tags: integrity, covered, tested + + This unit does xy. \ No newline at end of file diff --git a/dox_trace/documentation/source/pages/examples/report.rst b/dox_trace/documentation/source/pages/examples/report.rst new file mode 100644 index 0000000..587fca7 --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/report.rst @@ -0,0 +1,33 @@ +.. _traceability_report: + +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: MyCompany + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: MyCompany + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: MyCompany + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: MyCompany + +Source Code +----------- + +.. traceability_report:: source diff --git a/dox_trace/documentation/source/pages/examples/specifications.rst b/dox_trace/documentation/source/pages/examples/specifications.rst new file mode 100644 index 0000000..2447832 --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/specifications.rst @@ -0,0 +1,77 @@ +Specifications +============== + +Specification With Image +------------------------ + +*rst:* + +.. literalinclude:: contents/image.inc + :language: rst + +*html:* + +.. include:: contents/image.inc + +Unit With Source File +--------------------- + +*rst:* + +.. literalinclude:: contents/unit2source.inc + :language: rst + +*html:* + +.. include:: contents/unit2source.inc + +Invalid Specification +--------------------- + +*rst:* + +.. literalinclude:: contents/invalid.inc + :language: rst + +*html:* + +.. include:: contents/invalid.inc + + +Information +----------- + +*rst:* + +.. literalinclude:: contents/information.inc + :language: rst + +*html:* + +.. include:: contents/information.inc + +Requirement Derivation +---------------------- + +*rst:* + +.. literalinclude:: contents/derivation.inc + :language: rst + +*html:* + +.. include:: contents/derivation.inc + + +Modules +------- + +*rst:* + +.. literalinclude:: contents/modules.inc + :language: rst + +*html:* + +.. include:: contents/modules.inc + diff --git a/dox_trace/documentation/source/pages/examples/undefined_refs.rst b/dox_trace/documentation/source/pages/examples/undefined_refs.rst new file mode 100644 index 0000000..dfdd2c2 --- /dev/null +++ b/dox_trace/documentation/source/pages/examples/undefined_refs.rst @@ -0,0 +1,18 @@ +.. _undefined_refs: + +Undefined References +==================== + +.. undefined_refs:: + +This documentation should have no undefined references, but for demonstration purposes, some +undefined references are added here intentionally. + +.. spec:: SWA_Spec_1 + :refs: Undefined_1, SWA_Spec_2, Undefined_2 + +.. spec:: SWA_Spec_2 + :refs: SWA_Spec_3, Undefined_3 + +.. spec:: SWA_Spec_3 + :refs: Undefined_4 diff --git a/dox_trace/documentation/source/pages/requirements/reqConfig.rst b/dox_trace/documentation/source/pages/requirements/reqConfig.rst new file mode 100644 index 0000000..ff171d5 --- /dev/null +++ b/dox_trace/documentation/source/pages/requirements/reqConfig.rst @@ -0,0 +1,16 @@ +Configuration +============= + +Settings +-------- + +.. dox_trace_config:: + +Preview +------- + +A tool requirement without any explicit value set: + +.. requirement:: Tool_Config_Preview + :category: software + :tags: tool diff --git a/dox_trace/documentation/source/pages/started/installation.rst b/dox_trace/documentation/source/pages/started/installation.rst new file mode 100644 index 0000000..6885240 --- /dev/null +++ b/dox_trace/documentation/source/pages/started/installation.rst @@ -0,0 +1,11 @@ +.. _installation: + +Installation +============ + +If not already done, please install *Python* and *Sphinx* first. *dox_trace* itself does not need to +be installed, but has to be available in the workspace, e.g. by cloning or copying it. + +.. note:: + + This page gets updated soon when *dox_trace* is available as package on PyPI. diff --git a/dox_trace/documentation/source/pages/started/integration.rst b/dox_trace/documentation/source/pages/started/integration.rst new file mode 100644 index 0000000..0f32c96 --- /dev/null +++ b/dox_trace/documentation/source/pages/started/integration.rst @@ -0,0 +1,146 @@ + +.. _integration: + +Integration +=========== + +Compatibility +------------- + +- Requires at least Python 3.8. +- Requires at least Sphinx 6.2. +- *dox_trace* is optimized for the `Read the Docs Sphinx Theme `_. + For convenience, use the *dox_style* extension enhances the original *RTD theme* by some nice + features. +- The officially supported platforms are *Windows*, *Linux* and *macOS*. + +Configuration +------------- + +To use the dox_trace extension in your workspace, you have to reference it in ``conf.py``: + +In the following example, the *dox_trace* extension was copied into an ``_ext`` folder, see also +:ref:`installation`. + +.. code:: python + + EXTENSION_ROOT = Path('_ext') + sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob('*')]) + extensions = [ + ..., + 'sphinxcontrib.jquery', + 'dox_trace' + ] + +*dox_trace* is using jQuery. ``sphinxcontrib.jquery`` needs to be added as extension to ``conf.py`` +as well. + +The extension can be configured with the following parameters: + +- ``dox_trace_custom_attributes``: definition of :ref:`custom attributes ` +- ``dox_trace_allow_undefined_refs``: allowing :ref:`references ` to non-existing + targets +- ``dox_trace_allow_deprecated``: enabling backward compatibility for + :ref:`specification ` types +- ``dox_trace_security_backward``: enabling backward compatibility for + :ref:`security ` attribute +- ``dox_trace_test_setups_backward``: enabling backward compatibility for + :ref:`test_setups ` attribute +- ``dox_trace_dim_root``: :ref:`exporting to Dim files ` + +Folder Structure +---------------- + +There is no limitation regarding the folder structure from tooling perspective, but please follow +project specific guidelines. +When exporting to Dim, the Sphinx folder structure is used to create Dim files, e.g.: + +.. code:: none + + a/b/c.rst --> a/b/c.dim + +File Structure +-------------- + +There is also no limitation regarding the file structure, but again, please follow project specific +guidelines. + +| The IDs for *srs* must start with ``SRS__``. +| The IDs for *spec* must start with ``SMD|SWA__``. +| The IDs for *mod* and *interface* must start with ``SWA__``. +| The IDs for *unit* must start with ``SMD__``. + +All IDs must contain exactly two ``_``. + +In earlier version of this extensions, the rules were less strict. It was only checked if the ID +starts with ``SMD|SWA_``. To re-enable this behavior, set the config variable +*dox_trace_tolerant_naming_convention* in *conf.py* to *True*: + +.. code-block:: python + + dox_trace_tolerant_naming_convention = True + +When exporting to Dim, a folder is injected into the path depending on the first element of the ID, +either ``srs``, ``swa`` or ``smd``. + +Example: + +.. code:: none + + /a/b/c.rst --> /swa/a/b/c.dim + +Specification Structure +----------------------- + +Follow the syntax described in the *User Documentation*. dox_trace will automatically check if the +syntax is correct during the build except attributes which have fixed enums values like *status* or +*asil*. These values are checked when exporting to Dim and running the ``dim check``. + +Verifier +-------- + +Include the documentation build in a verifier (no incremental build). Also export the specifications +to Dim files and run the ``dim check``. The verifier must reject the commit if: + +- the exit code is not 0 for Sphinx / Dim +- Sphinx / Dim hangs and is terminated due to a timeout + +This ensures that only syntactically correct and consistent files are merged to the repository. +It also helps to prevent safety and security issues. + +Review +------ + +Always review the HTML output to check that the specifications are displayed as expected. + +Always perform a sanity check of the Dim export, e.g. are files written, is something obvious +missing and do some spot checks. + +Official Builds +--------------- + +When building the official documentation (with or without a Dim export) always perform a complete +build, not an incremental build. Make sure that the ``build`` folder does not exist before starting +the build. + +Bugs +---- + +Bugs must be tracked on regular basis, see also :ref:`bug_tracking`. Evaluate if the reported +bugs have an impact on your project and take appropriate actions like updating *dox_trace* in that +project to a newer version. + +Version +------- + +It must be ensured that only the correct (qualified) version of this tool is used. + +- Log the version of *dox_trace* in the official CI-jobs. +- Compare this version with the version specified for the project. + +Training +-------- + +| All users of *dox_trace* must read this documentation. +| They have to be trained in the usage of this tool to fully understand all features which are needed + for their work. diff --git a/dox_trace/documentation/source/pages/started/introduction.rst b/dox_trace/documentation/source/pages/started/introduction.rst new file mode 100644 index 0000000..790e665 --- /dev/null +++ b/dox_trace/documentation/source/pages/started/introduction.rst @@ -0,0 +1,36 @@ +Introduction +============ + +Overview +-------- + +`Sphinx `_ is a tool to "create intelligent and beautiful documentation +with ease". It uses `reStructuredText `_ as its markup +language, and many of its strengths come from the power and straightforwardness of reStructuredText +and its parsing and translating suite, the `Docutils `_. +`Extensions `_ +can add or change functionality. + +.. image:: ../_static/intro.drawio.png + :scale: 100% + :align: center + +The *dox_trace* extension provides new directives for the RST files, the so called +**specifications**. + +Specifications are containers which can include any content like text, images or even headings. +These containers can be enriched with several attributes similar to **Dim**, e.g. *status*, *asil*, +or *refs*. All attributes have default values which are used if not specified explicitly. The only +mandatory attribute from tooling perspective to build the documentation is the *ID*. + +This ID acts as anchor and can be referenced by other specifications and regular Sphinx links. +These references are needed to get a full :ref:`traceability ` from requirements through +software architecture and detailed design down to code and tests. + +Feature Highlights +------------------ + +- :ref:`Specification ` directives for ``requirement``, ``information``, ``srs``, ``spec``, + ``mod``, ``interface`` and ``unit``. +- Generation of a :ref:`traceability report `. +- :ref:`Export ` to Dim. diff --git a/dox_trace/documentation/source/pages/user/backward.rst b/dox_trace/documentation/source/pages/user/backward.rst new file mode 100644 index 0000000..d117707 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/backward.rst @@ -0,0 +1,115 @@ +.. _backward_compatibility: + +Backward Compatibility +====================== + +.. _backward_compatibility_security: + +Security +-------- + +Security To Cal ++++++++++++++++ + +It is still possible to use the deprecated attribute ``security`` for specifications. +In case the specification has no ``cal`` attribute set, the value from ``security`` is taken over +with the following mapping: + +.. list-table:: + :header-rows: 1 + + * - security + - cal + * - yes + - CAL_4 + * - no + - QM + * - not_set + - not_set + * - *otherwise* + - *ignore* + +| For Dim export, at least Dim 2.0 is required, which supports ``cal`` natively. +| Alternatively, Dim 1.4 can be used with a custom attribute ``cal`` specified in the Dim config: + +.. code-block:: yaml + + cal: + type: single + default: 'not_set' + allowed: + - CAL_1 + - CAL_2 + - CAL_3 + - CAL_4 + - QM + - not_set + +Security Instead of Cal ++++++++++++++++++++++++ + +*dox_trace* provides a config parameter ``dox_trace_security_backward``. If set to *True*, the +attribute ``security`` is shown instead of ``cal`` and ``Upstream Security`` instead of +``Upstream Cal``. + +In case the specification has no ``security`` attribute set, the value from ``cal`` is taken over +with the following mapping: + +.. list-table:: + :header-rows: 1 + + * - cal + - security + * - CAL_1 + - yes + * - CAL_2 + - yes + * - CAL_3 + - yes + * - CAL_4 + - yes + * - QM + - no + * - not_set + - not_set + * - *otherwise* + - *ignore* + +| For Dim export, Dim 1.4 or below is required, which supports ``security`` natively. +| Alternatively, Dim 2.0 and above can be used with a custom attribute ``security`` specified in the + Dim config: + +.. code-block:: yaml + + security: + type: single + default: not_set + allowed: + - yes + - no + - not_set + +.. _backward_compatibility_test_setups: + +Test Setups +----------- + +Test Setups To Verification Methods ++++++++++++++++++++++++++++++++++++ + +It is still possible to use the deprecated attribute ``test_setups`` for specifications. +In case the specification has no ``verification_methods`` attribute set, the value from +``test_setups`` is taken over. + +For Dim export, at least Dim 2.0 is required, which supports ``verification_methods`` natively. + +Test Setups Instead of Verification Methods ++++++++++++++++++++++++++++++++++++++++++++ + +*dox_trace* provides a config parameter ``dox_trace_test_setups_backward``. If set to *True*, the +attribute ``test_setup`` is shown instead of ``verification_methods``. + +In case the specification has no ``test_setup`` attribute set, the value from +``verification_methods`` is taken over. + +For Dim export, Dim 1.4 or below is required, which supports ``test_setups`` natively. diff --git a/dox_trace/documentation/source/pages/user/calcedValues.rst b/dox_trace/documentation/source/pages/user/calcedValues.rst new file mode 100644 index 0000000..7a3f904 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/calcedValues.rst @@ -0,0 +1,102 @@ +Calculated Values +================= + +In addition to the *explicit* attributes, the following attributes are *calculated* and also shown +in the HTML output. + +The attribute *names* are displayed in grey color and bold font. +The attribute *values* are usually also displayed in grey color, but the font style can vary +depending on the content. + +.. rubric:: Self-Written Specification Types + +.. list-table:: + :width: 100% + :widths: 25 16 16 16 16 16 + :header-rows: 1 + + * - + - srs + - spec + - mod + - interface + - unit + * - :ref:`spec_additional_upstream_references` + - x + - x + - x + - x + - x + * - :ref:`spec_additional_downstream_references` + - x + - x + - + - x + - x + +.. rubric:: Generated Specification Types + +.. list-table:: + :width: 100% + :widths: 25 20 20 20 20 + :header-rows: 1 + + * - + - requirement |br| (input) + - information |br| (input) + - requirement |br| (software, system) + - information |br| (software, system) + * - :ref:`spec_additional_upstream_references` + - x + - x + - x + - x + * - :ref:`spec_additional_downstream_references` + - x + - x + - x + - x + +.. _spec_additional_upstream_references: + +Upstream References +------------------- + +Collection of (backward) :ref:`refs ` **to a higher** category and backward +:ref:`refs ` **to the same** category as the specification. +They are shown as clickable links. + +If no upstream reference is available, + +- ``-`` is shown if + + - specification is struck through OR + - tag *tool* is set OR + - category is *input* is set OR + - type is *information*, + +- otherwise ``[missing]``. + +An :ref:`example ` can be found on the :ref:`spec_trace` page. + +.. _spec_additional_downstream_references: + +Downstream References +--------------------- + +Collection of (backward) :ref:`refs ` **to a lower** category and explicit +:ref:`refs ` **to the same** category as the specification. +They are shown as clickable links or in red if a target does not exist. + +If no downstream reference is available, + +- ``-`` is shown if + + - specification is struck through OR + - tag *covered* is set OR + - type is *information* or *unit* OR + - type is *interface and category is *module*, + +- ``[missing]`` otherwise. + +An :ref:`example ` can be found on the :ref:`spec_trace` page. diff --git a/dox_trace/documentation/source/pages/user/config.rst b/dox_trace/documentation/source/pages/user/config.rst new file mode 100644 index 0000000..ff019c0 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/config.rst @@ -0,0 +1,25 @@ +.. _dox_trace_configuration: + +Configuration +============= + +To include the configuration options, add the ``.. dox_trace_config::`` directive to your +documentation, e.g.: + +.. literalinclude:: ../appendix/config.rst + :language: rst + +*Type*, *ID* and the content are always shown. With ``.. dox_trace_config::``, it is possible to +change the **visibility** of the other attributes as follows: + +- *Show all* +- *Hide empty* +- *Hide empty and "[missing]"* +- *Hide all* + +For this documentation the :ref:`configuration ` can be found in the appendix. + +Note, the setting is **stored globally for each project** (based on the *project* value in +conf.py) in the browser-storage. Due to security reasons the browser-storage is bound to +*protocol://host:port*, this means a local build and a documentation on a server can have a +different setting. diff --git a/dox_trace/documentation/source/pages/user/customAttributes.rst b/dox_trace/documentation/source/pages/user/customAttributes.rst new file mode 100644 index 0000000..1a4566c --- /dev/null +++ b/dox_trace/documentation/source/pages/user/customAttributes.rst @@ -0,0 +1,82 @@ +.. _dim_custom_attr: + +Custom Attributes +================= + +The :ref:`dim_attr` can be extended by custom attributes using the *dox_trace_custom_attributes* +option in ``conf.py``. + +Syntax +------ + +.. code:: python + + dox_trace_custom_attributes = { + : { + "directives": , # mandatory + "categories": , # mandatory if directives include "requirement" or "information" + "type": "text|enum|refs", # mandatory + "default": , # optional, defaults to "" or [], depending on type + "export": "yes|no" # optional, defaults to "no" + } + ... + } + +*dox_trace_custom_attributes* must be a hash with: + +- key: name of the attribute +- value: parameter of the attribute + +The names must be unique and not conflict with :ref:`dim_attr`. + +Parameters +---------- + +**directives** is mandatory; it lists all specification :ref:`spec_types` for which the attribute +shall be available. It must be a non-empty list of strings. + +**categories** is mandatory if the *directives* parameter includes *requirement* or *information*. +It must be a non-empty list of strings containing *input*, *system* and/or *software*. + +**type** is mandatory; must be one of *text*, *enum* and *refs*. + +- *text*: Attribute value interpreted as **RST syntax**. +- *enum*: Comma separated **textual** string list. +- *refs*: Comma separated list of **Sphinx references**. The references are not considered for + calculating downstream or upstream references. + +**default** is optional; used if the attribute is not set explicitly in specifications. + +**export** is optional; setting to "yes" enables the export to Dim files. Note, that the Dim +configuration must also support this attribute. + +Values +------ + +An attribute value is one of the following (in that particular order): + +- explicitly set in the specifications +- defined in the :ref:`properties files ` +- taken from the **default** parameter +- ``""`` or ``[]``, depending on the **type** + +The output is formatted according to the type. Empty attributes are rendered as ``-``. + +Example +------- + +conf.py: + +.. literalinclude:: ../../conf.py + :start-after: START dox_trace_custom_attributes + :end-before: END dox_trace_custom_attributes + :language: python + +RST file: + +.. literalinclude:: customAttributesExample.inc + :language: rst + +Rendered output: + +.. include:: customAttributesExample.inc diff --git a/dox_trace/documentation/source/pages/user/customAttributesExample.inc b/dox_trace/documentation/source/pages/user/customAttributesExample.inc new file mode 100644 index 0000000..741e838 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/customAttributesExample.inc @@ -0,0 +1,15 @@ +.. requirement:: CRS_CustomAttribute_Requirement + :category: input + +.. spec:: SWA_CustomAttribute_Spec + :custom_text: + |br| + This is *italic text*, + - some bullet + - points and ... + .. note:: + ... a small note! + :custom_enum: a, b, c + :custom_refs: SMD_CustomAttribute_Unit, CRS_CustomAttribute_Requirement, dim_custom_attr + +.. unit:: SMD_CustomAttribute_Unit diff --git a/dox_trace/documentation/source/pages/user/directives.rst b/dox_trace/documentation/source/pages/user/directives.rst new file mode 100644 index 0000000..d88c41a --- /dev/null +++ b/dox_trace/documentation/source/pages/user/directives.rst @@ -0,0 +1,183 @@ +.. _spec: + +Specification Directives +======================== + +.. _spec_types: + +Types +----- + +Five types are provided for manually written specifications: + +- ``srs`` A **software requirement**, usually derived to specs. A srs needs to be tested. +- ``spec`` An **architectural** or **design specification**, e.g. a use case or resource usage. + It does not directly link to source code but needs to be refined and linked to other specs, mods, + interfaces or units. A spec needs to be tested. +- ``mod`` A **software module**. This element has an informative nature, it links to the module + documentation and provides a brief description of the module. It does not need to be tested + directly. +- ``interface`` An **interface** between two modules in the architecture. Needs to be linked to + the caller unit, the callee unit and if applicable to the interface unit. Interface tests are + obligatory. |br| *The usage in software module design is deprecated.* +- ``unit`` A **single functionality**, which is not split any further, usually a + class or a function. It refers to source code and is tested. + +Two additional types of are not intended to be used manually. They are generated by Dim when +exporting data to reStructuredText. + +- ``requirement`` An **input requirement**, **system requirement** or a **software requirement**. + Requirements have to be linked to the software architecture and software module design. + Note, that software requirements in Dim are deprecated, write them in Sphinx directly as *srs*. +- ``information`` Additional **non-binding** information. + +See :ref:`spec_trace` chapter for information about how to connect these elements. + +.. figure:: ../_static/types.drawio.png + :scale: 100% + :align: center + +If you use ``interface`` with an ID starting with ``SMD_``, an error will be raised during the +build. To skip that check, set the variable *dox_trace_allow_deprecated* in ``conf.py`` to *True*: + +.. code-block:: python + + dox_trace_allow_deprecated = True + +Syntax +------ + +To create a specification, use one of the following the directives: + +- ``.. srs:: `` +- ``.. spec:: `` +- ``.. mod:: `` +- ``.. interface:: ``. +- ``.. unit:: `` + +The **description** is placed into the **content** part of the directive. It can be **simple text** +or any other **complex Sphinx syntax** including headings. +In the following example many :ref:`attributes ` are shown automatically, which are +explained in further sections on this guideline page. + +The ID is rendered as HTML link to itself, so the anchor can be simply copied from the address bar +of the browser and e.g. pasted into a ticket. + +**Example** + +*rst:* + +.. code-block:: rst + + .. srs:: SRS_topic_aspect + + Description of the **srs**. + + .. mod:: SWA_mod_name + + Description of the **mod**. + + .. spec:: SWA_feature_id1 + + Description of the **spec**. + + .. image:: ../_static/example.png + + .. interface:: SWA_feature_id2 + + Description of + + the **interface**. + + .. unit:: SMD_module_classX + + Description of + the **unit**. + +*html:* + +.. srs:: SRS_topic_aspect + + Description of the **srs**. + +.. mod:: SWA_mod_name + + Description of the **mod**. + +.. spec:: SWA_feature_id1 + + Description of the **spec**. + + .. image:: ../_static/example.png + +.. interface:: SWA_feature_id2 + + Description of + + the **interface**. + +.. unit:: SMD_module_classX + + Description of + the **unit**. + +.. _naming_convention: + +Naming Convention of IDs +------------------------ + +The naming convention of IDs is independent from the type. The names must be **unique**. +Use short but concise strings. + +- **Software Requirements:** ``SRS__`` +- **Software Architecture:** ``SWA__`` |br| + For mods use: ``SWA_mod_`` +- **Software Module Design:** ``SMD__`` |br| + For units use the class name and/or method name: + ``SMD__::`` + +Examples: + +.. code-block:: rst + + .. srs:: SRS_Deployment_FunctionalSafety + + .. mod:: SWA_mod_xcpEthernetAdapter + + .. spec:: SWA_XCP_Paging + + .. unit:: SMD_xcp_XcpSlave + + .. unit:: SMD_xcp_XcpSlave::dispatcher + +Sphinx Links +------------ + +The specifications can be **referenced** from any other location using the regular Sphinx ``ref``. +Note, that a ``ref`` is only a simple link to navigate through the documentation. The default +display name is the last part of ID. + +**Example** + +*rst:* + +.. code-block:: rst + + Links to + :ref:`SMD_module_classX`, + :ref:`SRS_topic_aspect ` and + :ref:`some text `. + +*html:* + +.. list-table:: + :width: 100% + :header-rows: 0 + + * - Links to + :ref:`SMD_module_classX`, + :ref:`SRS_topic_aspect ` and + :ref:`some text `. + +To add references for :ref:`traceability `, +use the :ref:`spec_attr_refs` attribute of the specification directives. diff --git a/dox_trace/documentation/source/pages/user/enclosed.rst b/dox_trace/documentation/source/pages/user/enclosed.rst new file mode 100644 index 0000000..15811c8 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/enclosed.rst @@ -0,0 +1,31 @@ +Enclosed Files +============== + +Sphinx does not recognize files which are referenced in a non-Sphinx syntax, e.g. in raw-html: + +.. code-block:: rst + + .. spec:: + + Some text: :raw-html:`` + + .. spec:: + + Implement the following: + :raw-html:`download table` + +To make these files available in the output folder, add an ``enclosed`` directive to the RST-file: + +.. code-block:: rst + + .. enclosed:: + + folder/image1.png + table.xlsx + +Add one file per line without comma or bullet points. + +.. note:: + + This directive is a workaround if you need to generate RST files from HTML sources. + If possible, use regular Sphinx syntax instead to avoid this workaround. diff --git a/dox_trace/documentation/source/pages/user/explicitAttributes.rst b/dox_trace/documentation/source/pages/user/explicitAttributes.rst new file mode 100644 index 0000000..2b9299d --- /dev/null +++ b/dox_trace/documentation/source/pages/user/explicitAttributes.rst @@ -0,0 +1,528 @@ +.. _dim_attr: + +Standard Attributes +=================== + +The different :ref:`specification types ` support different attributes. + +None of the attributes is mandatory from tooling perspective, but they have default values which +can differ depending on the ID, type, etc. + +In general the syntax is as follows: + +.. code-block:: rst + + .. :: + :: + :: + + + +Similar to the content, the values can be **simple text** or any other **complex Sphinx syntax** +like images, lists, blocks and even headings. + +Many attributes are the same as for **Dim**, especially regarding the allowed values. +Sphinx itself does not complain (yet) if e.g. an incorrect status value is set, but it's recognized +when :ref:`exported ` and loaded by Dim. + +The attribute *names* are displayed in black color and bold font. +The attribute *values* are usually also displayed in black color, but the font style can vary +depending on the content. + +Note: it is recommended to do that export and "dim check" in the verifier of a project to avoid +broken attributes. + +.. rubric:: Self-Written Specification Types + +.. list-table:: + :width: 100% + :widths: 20 16 16 16 16 16 + :header-rows: 1 + + * - + - srs + - spec + - mod + - interface + - unit + * - :ref:`spec_attr_status` + - x + - x + - x + - x + - x + * - :ref:`spec_attr_review_status` + - \(x) + - \(x) + - \(x) + - \(x) + - \(x) + * - :ref:`spec_attr_asil` + - x + - x + - x + - x + - x + * - :ref:`spec_attr_cal` + - x + - x + - x + - x + - x + * - :ref:`spec_attr_reuse` + - + - + - x + - + - + * - :ref:`spec_attr_usage` + - + - + - x + - + - + * - :ref:`spec_attr_tags` + - x + - x + - + - x + - x + * - :ref:`spec_attr_developer` + - x + - x + - x + - x + - x + * - :ref:`spec_attr_tester` + - x + - x + - + - \(x) + - x + * - :ref:`spec_attr_verification_methods` + - x + - x + - + - \(x) + - x + * - :ref:`spec_attr_verification_criteria` + - x + - x + - + - \(x) + - x + * - :ref:`spec_attr_comment` + - + - + - + - + - + * - :ref:`spec_attr_miscellaneous` + - + - + - + - + - + * - :ref:`spec_attr_feature` + - + - + - + - + - + * - :ref:`spec_attr_change_request` + - + - + - + - + - + * - :ref:`spec_attr_sources` + - \(x) + - \(x) + - + - \(x) + - x + * - :ref:`spec_attr_refs` + - x + - x + - + - x + - x + * - :ref:`spec_attr_location` + - + - + - x + - + - + * - :ref:`spec_attr_category` + - + - + - + - + - + +.. rubric:: Generated Specification Types + +.. list-table:: + :width: 100% + :widths: 20 20 20 20 20 + :header-rows: 1 + + * - + - requirement |br| (input) + - information |br| (input) + - requirement |br| (software, system) + - information |br| (software, system) + * - :ref:`spec_attr_status` + - x + - x + - x + - x + * - :ref:`spec_attr_review_status` + - x + - \(x) + - \(x) + - \(x) + * - :ref:`spec_attr_asil` + - x + - x + - x + - x + * - :ref:`spec_attr_cal` + - x + - x + - x + - x + * - :ref:`spec_attr_reuse` + - + - + - + - + * - :ref:`spec_attr_usage` + - + - + - + - + * - :ref:`spec_attr_tags` + - x + - x + - x + - x + * - :ref:`spec_attr_developer` + - x + - + - x + - + * - :ref:`spec_attr_tester` + - x + - + - x + - + * - :ref:`spec_attr_verification_methods` + - x + - + - x + - + * - :ref:`spec_attr_verification_criteria` + - x + - + - x + - + * - :ref:`spec_attr_comment` + - x + - x + - + - + * - :ref:`spec_attr_miscellaneous` + - x + - x + - + - + * - :ref:`spec_attr_feature` + - x + - x + - + - + * - :ref:`spec_attr_change_request` + - x + - x + - + - + * - :ref:`spec_attr_sources` + - \(x) + - \(x) + - \(x) + - \(x) + * - :ref:`spec_attr_refs` + - x + - x + - x + - x + * - :ref:`spec_attr_location` + - + - + - + - + * - :ref:`spec_attr_category` + - \(-) + - \(-) + - \(-) + - \(-) + + +- Empty cell = attribute not available and never shown in HTML output +- ``x`` = shown in HTML output +- ``(x)`` = shown in HTML output under certain conditions, see below +- ``(-)`` = attribute available, but not shown in HTML output + +.. _spec_attr_status: + +status +------ + +Default value: ``draft`` + +If *status* is set to ``invalid``, the requirement will be struck through. + +.. _spec_attr_review_status: + +review_status +------------- + +| Only shown for input requirements (not software requirements) or if the value is != ``accepted``. +| Default value: ``accepted``. + +If *review_status* is set to ``rejected`` or ``not_relevant``, the requirement will be struck +through. + +.. _spec_attr_asil: + +asil +---- + +Default value: ``not_set`` + +.. _spec_attr_cal: + +cal +--- + +Default value: ``not_set`` + +.. _spec_attr_reuse: + +reuse +----- + +| Describes if the module is (partly) reused or developed from scratch. + Use a short string without new lines, e.g. "yes" and "no". +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_usage: + +usage +----- + +| Describes in which environment the module is used. + Use a short string without new lines, e.g. "production", "debug", "testing" +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_tags: + +tags +---- + +| A string with comma separated values. +| Default value is empty string which is displayed as ``-``. + +| If type is *unit*, the tag *unit* is added automatically to the export. +| If type is *interface*, the tag *interface* is added automatically to the export. +| If type is *mod* and the attribute location points to an existing module documentation, the tag + *covered* is added automatically to the export. + +.. _spec_attr_developer: + +developer +--------- + +| The value can be any string. +| Default value is empty string with is displayed as: + + - ``-`` if specification is struck through + - ``[missing]`` otherwise + +.. _spec_attr_tester: + +tester +------ + +| The value can be any string. +| Default value is empty string with is displayed as: + + - ``-`` if *verification_methods* is *none* or specification is struck through + - ``[missing]`` otherwise + +The attribute is ignored if type is interface **and** ID starts with SMD\_. + +.. _spec_attr_verification_methods: + +verification_methods +-------------------- + +Default value: + + - ``off_target`` if type is *srs*, *spec* or *unit* **and** ID starts with SMD\_ + - ``on_target`` if type is *srs*, *spec*, *interface* or *unit* **and** ID starts with SWA\_ + - ``none`` otherwise + +The attribute is ignored if type is *interface* **and** ID starts with SMD\_. + +.. _spec_attr_verification_criteria: + +verification_criteria +--------------------- + +| Attribute is ignored if type is *interface* and ID starts with SMD\_. +| The value can be any string. +| Default value is empty string with is displayed as: + + - ``[missing]`` if + + - type is *srs* or *requirements* and category is not *input* **and** + - *tool* is not in *tags* **and** + - specification is not struck through + + - ``-`` otherwise + +.. _spec_attr_comment: + +comment +------- + +| This attribute is ignored except for input requirements. +| The value can be any string. +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_miscellaneous: + +miscellaneous +------------- + +| This attribute is ignored except for input requirements. +| The value can be any string. +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_feature: + +feature +------- + +| This attribute is ignored except for input requirements. +| The value can be any string. +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_change_request: + +change_request +-------------- + +| This attribute is ignored except for input requirements. +| The value can be any string. +| Default value is empty string which is displayed as ``-``. + +.. _spec_attr_sources: + +sources +------- + +*sources* is a comma separated string of relative filenames. It links software detailed design +to the source code. + +The filenames must be specified **relative** from the **module root** (identified by the doc-folder +in which the rst-file is placed). Alternatively relative to the rst file itself. These files must +exist, a check is done when building with Sphinx. + +This attribute is shown if: + +- the attribute is not empty OR +- the type is *unit* OR +- the type is *interface* and the ID starts with SMD\_ + +Default value is empty string which is displayed as: + +- ``-`` if tag *covered* is set or specification is struck through +- ``[missing]`` otherwise + +Example: + +.. code-block:: rst + + # modules/safety/safeCom/doc/api/public.rst + # modules/safety/safeCom/include/PublicApi.h + + # relative from module root + .. unit:: SMD_example_id1 + :sources: include/PublicApi.h + + # relative from current rst file + .. unit:: SMD_example_id2 + :sources: ../../include/PublicApi.h + +.. _spec_attr_refs: + +refs +---- + +| *refs* is a comma separated string of :ref:`specification IDs `. + References must **exist** and link to **other specifications**. +| This attribute is not shown directly but integrated to :ref:`spec_additional_upstream_references` + and :ref:`spec_additional_downstream_references`. + +Example: + +.. code-block:: rst + + .. spec:: SWA_exampleFeature_id1 + :refs: SMD_exampleModule_id2, SMD_exampleModule_id3 + +To allow references to non-existing specifications, set the variable +*dox_trace_allow_undefined_refs* in ``conf.py`` to *True*. With this setting, all undefined references +are displayed in red in :ref:`spec_additional_downstream_references` and no warning is printed +during the build. + +.. code-block:: python + + dox_trace_allow_undefined_refs = True + +To create a list of undefined references, add the directive ``.. undefined_refs::`` e.g. to the +appendix. See :ref:`undefined_refs` for an example. + +Undefined references are not :ref:`exported to Dim `. + +.. _spec_attr_location: + +location +-------- + +| Links to the module documentation. Define the path from Sphinx root to module root. + If the module documentation ``/doc/index.rst`` exists, an HTML link will be created, + otherwise the string is displayed as is. +| Default value is empty string which is displayed as: + +- ``-`` if specification is struck through +- ``[missing]`` otherwise + +Example: + +.. code-block:: rst + + .. mod:: SWA_mod_exampleModule + :location: ecu1/core2/modules/exampleModule + +.. _spec_attr_category: + +category +-------- + +This value is usually **not set manually**, it's set by the RST export of Dim. Possible values are +*input*, *system* and *software*. Requirements are handled slightly different depending on the +category, e.g. it affects the :ref:`spec_attr_review_status` visibility. diff --git a/dox_trace/documentation/source/pages/user/export.rst b/dox_trace/documentation/source/pages/user/export.rst new file mode 100644 index 0000000..6278460 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/export.rst @@ -0,0 +1,41 @@ +.. _spec2dim: + +Export to Dim Files +=================== + +To enable the export, add the configuration option *dox_trace_dim_root* to ``conf.py``. This option +specifies the path to the *Dim* export folder. If the option is not set, the export is disabled. + +Example: + +.. code-block:: python + + dox_trace_dim_root = "../some/folder" + +Only the types ``srs``, ``spec``, ``mod``, ``interface`` and ``unit`` are exported. +When exporting to Dim, a folder is injected into the path depending on the first element of the ID, +either ``srs``, ``swa`` or ``smd``: + + - ``/srs//*.dim`` + - ``/swa//*.dim`` + - ``/smd//*.dim`` + +All Dim files in ``/`` will be deleted prior to the export, except for +categories which have no specification to export. E.g. if no ``srs`` is specified, the folder +``/srs`` will not be deleted. + +The following data is extracted: + +- The **document** name is derived from the ID of the first specification of the RST file, e.g. + *SMD_moduleName_Spec1* becomes *SMD_moduleName*. +- The IDs of the specifications will be used as **Dim IDs**. +- The **content** and the attribute **verification_criteria** are replaced in the export with: + *See Sphinx documentation.* +- The **tags** *unit* and *interface* are added to *tags* for unit and interface specifications + and exported accordingly. +- All other **attributes** are exported as specified or with their default values. + +Notes: + +- Usually, the exported files are not committed. +- They do not follow the Dim formatting scheme. diff --git a/dox_trace/documentation/source/pages/user/newlines.rst b/dox_trace/documentation/source/pages/user/newlines.rst new file mode 100644 index 0000000..b7313cd --- /dev/null +++ b/dox_trace/documentation/source/pages/user/newlines.rst @@ -0,0 +1,42 @@ +Newlines in Attributes +====================== + +For **attributes** there is a **limitation** in Sphinx, you cannot add empty lines, e.g. to +start a bullet list. In order to compensate that, newlines are *preserved*. + +For example the following code does not work: + +.. code-block:: rst + + .. :: + :: + My list + + - ... + - ... + + This is block text which + is rendered in one line. + +Instead, write it like this: + +.. code-block:: rst + + .. :: + :: + My list + - ... + - ... + This is block text which is rendered in one line. + +In order **not to preserve a newline**, end the line with a backslash: + +.. code-block:: rst + + .. :: + :: + A long text \ + without preserved \ + newlines. + +This does not apply to the **content** of the specification. diff --git a/dox_trace/documentation/source/pages/user/parentValues.rst b/dox_trace/documentation/source/pages/user/parentValues.rst new file mode 100644 index 0000000..39d0a27 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/parentValues.rst @@ -0,0 +1,148 @@ +Upstream and Derived Values +=========================== + +As additional information, values from direct and indirect upstream references are accumulated +and shown to ease consistency reviews. + +The attribute *names* are displayed in grey color and bold font. +The attribute *values* are usually also displayed in grey color, but the font style can vary +depending on the content. + +.. rubric:: Self-Written Specification Types + +.. list-table:: + :width: 100% + :widths: 20 16 16 16 16 16 + :header-rows: 1 + + * - + - srs + - spec + - mod + - interface + - unit + * - :ref:`spec_upstream_asil` + - x + - x + - x + - x + - x + * - :ref:`spec_upstream_cal` + - x + - x + - x + - x + - x + * - :ref:`spec_upstream_tags` + - x + - x + - x + - x + - x + * - :ref:`spec_derived_feature` + - x + - x + - + - x + - x + * - :ref:`spec_derived_cr` + - x + - x + - + - x + - x + +.. rubric:: Generated Specification Types + +.. list-table:: + :width: 100% + :widths: 20 20 20 20 20 + :header-rows: 1 + + * - + - requirement |br| (input) + - information |br| (input) + - requirement |br| (software, system) + - information |br| (software, system) + * - :ref:`spec_upstream_asil` + - + - + - x + - x + * - :ref:`spec_upstream_cal` + - + - + - x + - x + * - :ref:`spec_upstream_tags` + - + - + - x + - x + * - :ref:`spec_derived_feature` + - + - + - x + - + * - :ref:`spec_derived_cr` + - + - + - x + - + +.. _spec_upstream_asil: + +Upstream Asil +------------- + +| A comma separated list of all :ref:`spec_attr_asil` values of **direct** upstream references. +| Duplicated entries will be removed. +| Upstream references to *information* and struck through specifications are ignored. +| Will not be shown for input requirements. +| Example: ``ASIL_A, ASIL_B, not_set``. + +.. _spec_upstream_cal: + +Upstream Cal +------------ + +| A comma separated list of all :ref:`spec_attr_cal` values of **direct** upstream references. +| Duplicated entries will be removed. +| Upstream references to *information* and struck through specifications are ignored. +| Will not be shown for input requirements. +| Example: ``CAL_2, not_set``. + +.. _spec_upstream_tags: + +Upstream Tags +------------- + +| A comma separated list of all :ref:`spec_attr_tags` values of **direct** upstream references. +| Duplicated entries will be removed. +| Upstream references to *information* and struck through specifications are ignored. +| Will not be shown for input requirements. +| Example: ``srs, swa, smd, memory, obd, covered``. + +.. _spec_derived_feature: + +Derived Feature +--------------- + +| A comma separated list of all :ref:`spec_attr_feature` values of **direct** and **indirect** + upstream references. +| Duplicated entries will be removed. +| Upstream references to *information* and struck through specifications are ignored. +| Will not be shown for input requirements. +| Example: ``Feature 1, Feature 2``. + +.. _spec_derived_cr: + +Derived Change Request +---------------------- + +| A comma separated list of all :ref:`spec_attr_change_request` values of **direct** and + **indirect** upstream references. +| Duplicated entries will be removed. +| Upstream references to *information* and struck through specifications are ignored. +| Will not be shown for input requirements. +| Example: ``CR 1, CR 2``. diff --git a/dox_trace/documentation/source/pages/user/properties.rst b/dox_trace/documentation/source/pages/user/properties.rst new file mode 100644 index 0000000..ff55c1d --- /dev/null +++ b/dox_trace/documentation/source/pages/user/properties.rst @@ -0,0 +1,169 @@ +.. _properties: + +Properties +========== + +Properties, also called characteristics, are defined at a **single** location but can be used in +**several** places. + +YAML Format +----------- + +The properties are defined in an external ``YAML`` file like this: + +.. code:: yaml + + SMD_cpp2can: + asil: QM + reuse: yes + SMD_safeNvM: + asil: ASIL_B + reuse: no + cal: CAL_2 + +You can write the information also in one line, it's just syntactic sugar: + +.. code:: yaml + + SMD_cpp2can: { asil: QM, reuse: yes } + SMD_safeNvM: { asil: ASIL_B, reuse: no, cal: CAL_2 } + +Multi-line strings are also supported: + +.. code:: yaml + + SWA_mod_abcAdapter: + content: | + This module is about + + - this + - that + +| A referenced but missing property will lead to an error! +| It is possible to define default values with the special ID ``_default_``. + +Sphinx Configuration +-------------------- + +Configure the filename of the properties in ``conf.py``: + +.. code:: + + properties_file = '/properties.yaml' + +Specification Usage +------------------- + +It is possible to overwrite the default values for attributes of specifications. + +The property ID is matched in the following order: + +- Equal to the complete specification ID, e.g. *SMD_cpp2can_abc* +- Equal to the specification ID until one character before the second "_", e.g. *SMD_cpp2can* +- Equal to the specification ID until one character before the first "_", e.g. *SMD* +- Equal to *_default_* + +If + +- a specification in an RST file does not specify an attribute explicitly and +- the ID is found in the properties file and +- the attribute is defined for this ID in the properties file + +then the corresponding value is used instead of the standard default value defined in +:ref:`dim_attr` and :ref:`dim_custom_attr`. This applies to all explicit attributes as well as for +the content of the specifications. + +Example: + +**properties.yaml:** + +.. code:: yaml + + SMD_cpp2can: { asil: QM, cal: CAL_1 } + SWA: { developer: MyCompany } + +**RST:** + +.. code:: rst + + .. spec:: SMD_cpp2can_abc + :cal: CAL_4 + + .. spec:: SWA_featureX_abc + +**HTML:** + +.. spec:: SMD_cpp2can_abc + :cal: CAL_4 + +.. spec:: SWA_featureX_abc + +Standalone Usage +---------------- + +Properties can be used as a *role* or as a *directive*: + +- role: ``:prop:`:``` +- directive: ``.. prop:: :`` + +These are the main differences: + +.. list-table:: + :header-rows: 1 + + * - Role + - Directive + * - Inline text + - Separate block + * - Single-line + - Multi-line + * - Value interpreted as string + - Value interpreted as RST + * - Styled with CSS + - Rendered by Sphinx + +Example: + +**properties.yaml:** + +.. code:: yaml + + _default_: { key3: value3 } + + ID1: + key1: value1 + key2: value2 + +**RST:** + +.. code:: rst + + The values: :prop:`ID1:key1`, :prop:`ID1:key2`, :prop:`ID1:key3` + + .. list-table:: + :header-rows: 1 + + * - Key + - Value + * - key1 + - .. prop:: ID1:key1 + * - key2 + - .. prop:: ID1:key2 + * - key3 + - .. prop:: ID1:key3 + +**HTML:** + +:prop:`ID1:key1`, :prop:`ID1:key2`, :prop:`ID1:key3` + +.. list-table:: + :header-rows: 1 + + * - Key + - Value + * - key1 + - .. prop:: ID1:key1 + * - key2 + - .. prop:: ID1:key2 + * - key3 + - .. prop:: ID1:key3 diff --git a/dox_trace/documentation/source/pages/user/rawhtml.rst b/dox_trace/documentation/source/pages/user/rawhtml.rst new file mode 100644 index 0000000..14420a7 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/rawhtml.rst @@ -0,0 +1,65 @@ +HTML in Attributes +================== + +Custom Roles +------------ + +Textual attributes and the content of specifications are parsed with Sphinx, so it is possible to +use any predefined role, which can be interpreted as HTML: + +**RST**: + +.. code-block:: rst + + .. requirement:: Req1 + :feature: -> feature1 :custom-role:`
` -> feature2 + + This is the :custom-role:`` requirement :custom-role:``. + +This is **not recommended** for self-written specifications. + +Sphinx Syntax +------------- + +For self-written specifications, use regular Sphinx syntax: + +**RST**: + +.. code-block:: rst + + .. requirement:: Req2 + :feature: -> feature1 + -> feature2 + + This is the **requirement**. + +**HTML**: + +.. requirement:: Req2 + :feature: -> feature1 + -> feature2 + + This is the **requirement**. + +Auto-Generation +--------------- + +Specifications may be auto-generated like done by **Dim**. If an attribute or the content starts +with ``:raw-html:``` and ends with `````, the string between the backticks is treated as HTML. Is it +not a real role, which means there is no need to define this role in Sphinx, just use this pattern: + +**RST**: + +.. code-block:: rst + + .. requirement:: Req3 + :feature: :raw-html:`
-> feature1
-> feature2` + + :raw-html:`This is the requirement.` + +**HTML**: + +.. requirement:: Req3 + :feature: :raw-html:`
-> feature1
-> feature2` + + :raw-html:`This is the requirement.` diff --git a/dox_trace/documentation/source/pages/user/traceability.rst b/dox_trace/documentation/source/pages/user/traceability.rst new file mode 100644 index 0000000..2323a86 --- /dev/null +++ b/dox_trace/documentation/source/pages/user/traceability.rst @@ -0,0 +1,167 @@ +.. _spec_trace: + +Traceability +============ + +References can be specified using the :ref:`refs ` attribute. Backward references +are calculated automatically. These references are shown as :ref:`spec_trace_up_down`. + +Categories +---------- + +*dox_trace* handles the following categories in top-down order: + +.. list-table:: + :header-rows: 1 + + * - Level + - Category + - Specification Types + - Restrictions + * - 5 + - Input Requirement + - requirement / information + - :ref:`spec_attr_category` set to *input* + * - 4 + - System Requirement + - requirement / information + - :ref:`spec_attr_category` set to *system* + * - 3 + - Software Requirement + - requirement / information / srs + - for requirement / information: :ref:`spec_attr_category` set to *software* + * - 2 + - Architecture + - spec / mod / interface + - for spec: :ref:`IDs ` starting with *SWA_* + * - 1 + - Module + - spec / unit + - for spec: :ref:`IDs ` starting with *SMD_* + +.. _spec_trace_up_down: + +Upstream and Downstream References +---------------------------------- + +| :ref:`spec_additional_upstream_references` are (backward) :ref:`refs ` + **to a higher** category and backward :ref:`refs ` **to the same** category. +| :ref:`spec_additional_downstream_references` are (backward) :ref:`refs ` + **to a lower** category and explicit :ref:`refs ` **to the same** category. + +Example: + +.. code-block:: rst + + .. srs:: SRS_stream_id1 + + .. spec:: SWA_stream_id2 + :refs: SRS_stream_id1, SWA_stream_id3, SMD_stream_id4 + + .. spec:: SWA_stream_id3 + + .. unit:: SMD_stream_id4 + +.. srs:: SRS_stream_id1 + +.. spec:: SWA_stream_id2 + :refs: SRS_stream_id1, SWA_stream_id3, SMD_stream_id4 + +.. spec:: SWA_stream_id3 + +.. unit:: SMD_stream_id4 + +.. _spec_trace_cyclic: + +Cyclic References +----------------- + +*dox_trace* checks automatically for cyclic references. +A cyclic reference will result in a build error, so it cannot be overlooked if accidentally added. + +Cyclic references can only occur on the same level. + +References to Source Files +-------------------------- + +References to :ref:`sources ` can be specified in the *unit* directive. + +Example: + +.. code-block:: rst + + .. unit:: SMD_trace_file + :sources: ../_static/module1/include/source1.h + +.. unit:: SMD_trace_file + :sources: ../_static/module1/include/source1.h + +.. _dox_trace_ref_from_sources: + +References From Source Files +---------------------------- + +Source files are not touched to add backward references. Instead, a list which maps files back to +specifications can be generated in the traceability report. + +.. _generate_traceability_report: + +Generating Traceability Report +------------------------------ + +A traceability report can be generated by adding the ``traceability_report`` directive to an RST +file: + +.. code-block:: rst + + .. traceability_report:: + :developer: + +- The ```` can be *input*, *software*, *architecture*, *module* or *source*. +- The developer ```` is used to select the entries which shall be shown in the report. + It is very common, that the developer is misspelled in the specifications regarding whitespaces + and capitalization. Therefore the filtering is tolerant here: + + - case insensitive + - a space in the matches to 0 or more spaces and underscores + + Example: + + .. code-block:: rst + + .. traceability_report:: software + :developer: Abc AG + + matches + + .. srs:: SRS_Feature_Name1 + :developer: Abc AG + + .. srs:: SRS_Feature_Name2 + :developer: ABC_AG + + .. srs:: SRS_Feature_Name3 + :developer: AbcAG + + The developer option is not relevant for the category *source*. + +*This* documentation also contains a :ref:`traceability_report`, which is specified as follows: + +.. literalinclude:: ../examples/report.rst + :language: rst + +For each category, several tables are generated. These tables are predefined and are not meant +to be a replacement for e.g. a project status report. Rather, they shall give an overview what is +included in the documentation, where references are already specified and where not. + +Test Case References +-------------------- + +Test case references are not added to the Sphinx documentation. Instead, test cases should be +annotated with specification IDs which can be evaluated by an extra tool with the following +approach: + +- export the specifications to *Dim* +- using *Dim* Ruby API to read the specifications +- parsing the test cases +- generating a report diff --git a/dox_trace/documentation/source/pages/user/unintended.rst b/dox_trace/documentation/source/pages/user/unintended.rst new file mode 100644 index 0000000..c86d9dd --- /dev/null +++ b/dox_trace/documentation/source/pages/user/unintended.rst @@ -0,0 +1,47 @@ +.. _unintended_comments: + +Unintended Comments +=================== + +It is pretty easy to accidentally write a comment instead of a specification, e.g.: + +.. code-block:: rst + + .. spec: + + --> Should be ".. spec::" + + .. :mod + + --> Should be ".. mod::" + + .. interface + + --> Should be ".. interface::" + + .. :unit: + + --> Should be ".. unit::" + + .. srs.. + + --> Should be ".. srs::" + +This extensions forbids the strings ``srs``, ``spec``, ``mod``, ``interface`` and ``unit`` in the *first* +line of a comment if there are **no other non-word characters** in this line. + +Allowed comments: + +.. code-block:: rst + + .. + A nice module. + --> Other non-word characters in first line. + + .. A nice interface. + --> Other non-word characters in first line. + + .. + First line. + spec + --> Forbidden string not in first line. diff --git a/dox_trace/dox_trace/__init__.py b/dox_trace/dox_trace/__init__.py new file mode 100644 index 0000000..8385041 --- /dev/null +++ b/dox_trace/dox_trace/__init__.py @@ -0,0 +1,18 @@ +from .coverage import * + +coverage_start() + +import os +import sys + +# for unit testing +if os.environ.get("MANIPULATE_PYTHON_VERSION"): + sys.version_info = (3, 7) + +# for unit testing +if os.environ.get("MANIPULATE_SPHINX_VERSION"): + import sphinx + + sphinx.version_info = (6, 1, 9) + +from .main import * diff --git a/dox_trace/dox_trace/_static/dox_trace.css b/dox_trace/dox_trace/_static/dox_trace.css new file mode 100644 index 0000000..0568dda --- /dev/null +++ b/dox_trace/dox_trace/_static/dox_trace.css @@ -0,0 +1,101 @@ +/* Highlight "roles" */ + +.literal.highlight.highlight-spec { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-unit { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-interface { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-requirement { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-srs { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-mod { background: #FFFFFF; color:#222222; font-weight: bold; font-size: small; } +.literal.highlight.highlight-information { background: #FFFFFF; color:#999999; font-weight: bold; font-size: small; } + +.literal.highlight.highlight-prop { background: #FFFFFF; color:green; font-weight: bold; } + +/* Colors for labels */ + +.dox-trace-red { color:rgb(253, 13, 27); } +.dox-trace-grey { color:rgb(128, 128, 128); } + +/* Border for dox_trace objects like requirement or spec */ + +table.docutils.dox-trace-border { border: double 1px grey; position: relative } + +/* Hide specifications until shown via jquery */ + +.dox-trace-initially-hidden { + visibility: hidden; + opacity:0; +} + +.dox-trace-remove-opacity { + opacity: inherit; +} + +/* Some tables in traceability report need smaller font size */ + +.dox-trace-small-font-table { + font-size: small !important; +} + +/* Tables of invalid and rejected elements are struck through */ + +.dox-trace-strikethrough-table { + position: absolute; + opacity: 0.5; + pointer-events: none; + top: 0; + width: 100%; + height: 100%; + background-image: linear-gradient( + to bottom right, + transparent calc(50% - 1px), + grey, + transparent calc(50% + 1px)); +} + +.dox-trace-strikethrough-cell { + background-image: linear-gradient( + to top right, + transparent calc(50% - 1px), + lightgrey, + transparent calc(50% + 1px)); + pointer-events: none; +} + +.dox-trace-modal { + display: none; + position: fixed; + z-index: 1000; + padding: 50px; + left: 0; + top: 0; + width: 100%; + height: 100%; + overflow: auto; + background-color: rgb(0,0,0); + background-color: rgba(0,0,0,0.4); + +} + +.dox-trace-modal-content { + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: fit-content; + height: fit-content; +} + +/* close button */ +.dox-trace-close { + color: #aaaaaa; + float: right; + font-size: 28px; + font-weight: bold; +} + +.dox-trace-close:hover, +.dox-trace-close:focus { + color: #000; + text-decoration: none; + cursor: pointer; +} diff --git a/dox_trace/dox_trace/_static/dox_trace.js b/dox_trace/dox_trace/_static/dox_trace.js new file mode 100644 index 0000000..7a8c3fb --- /dev/null +++ b/dox_trace/dox_trace/_static/dox_trace.js @@ -0,0 +1,116 @@ +// noinspection JSUnusedGlobalSymbols + +let visibleTextFound = false +function visibleText(elem) { + $.each($(elem).contents(), function(i, itm) { + if (visibleTextFound) + return false + if (itm.nodeType === Node.TEXT_NODE) { + visibleTextFound = $.trim($(itm).text()).length > 0 + if (visibleTextFound) + return false + } + if ($(itm).is(':visible')) + visibleText(itm); + }) +} + + +function applyDoxTrace() +{ + ts = document.querySelector('meta[name="dox_trace_storage"]').content + + value = localStorage["doxTraceReadingModes_" + ts] + if (value === "none") + { + $('.dox-trace-attribute-empty').show() + $('.dox-trace-attribute-missing').show() + $('.dox-trace-attribute').show() + } + if (value === "all") + { + $('.dox-trace-attribute-empty').hide() + $('.dox-trace-attribute-missing').hide() + $('.dox-trace-attribute').hide() + } + else if (value === "empty") + { + $('.dox-trace-attribute-empty').hide() + $('.dox-trace-attribute-missing').show() + $('.dox-trace-attribute').show() + } + else if (value === "missing") + { + $('.dox-trace-attribute-empty').hide() + $('.dox-trace-attribute-missing').hide() + $('.dox-trace-attribute').show() + } + + $(".dox-trace-hide-if-empty td").each(function() + { + visibleTextFound = false + visibleText(this) + + if (visibleTextFound) + { + $(this).parent().show(); + } + else + { + $(this).parent().hide(); + } + }) +} + +function dox_trace_config_changed(radiobutton) +{ + storage = document.querySelector('meta[name="dox_trace_storage"]') + if (storage != null) + { + ts = storage.content + + localStorage["doxTraceReadingModes_" + ts] = radiobutton.value + applyDoxTrace() + } +} + +$(function() +{ + storage = document.querySelector('meta[name="dox_trace_storage"]') + if (storage != null) + { + ts = storage.content + value = localStorage["doxTraceReadingModes_" + ts] + + $("#dox_trace_config_none").prop('checked', value === "none" || value === undefined); + $("#dox_trace_config_all").prop('checked', value === "all"); + $("#dox_trace_config_empty").prop('checked', value === "empty"); + $("#dox_trace_config_missing").prop('checked', value === "missing"); + + applyDoxTrace() + + $('.dox-trace-initially-hidden').css("visibility", "visible"); + $(".dox-trace-initially-hidden").addClass('dox-trace-remove-opacity'); + + // uncomment to delete from storage for testing + // localStorage.removeItem("doxTraceReadingModes_" + ts); + } + + const modals = Array.from(document.querySelectorAll('[id^=traceabilityReportModal_]')); + modals.forEach(function(modal) { + postfix = modal.id.substring(23) + + const btn = document.getElementById("traceabilityReportButton" + postfix); + const span = document.getElementById("traceabilityReportClose" + postfix); + + btn.onclick = function() { modal.style.display = "block"; } + span.onclick = function() { modal.style.display = "none"; } + + window.addEventListener("click", function(event) { + if (event.target === modal) { modal.style.display = "none"; } + }); + }) + + +}); + diff --git a/dox_trace/dox_trace/backward_refs.py b/dox_trace/dox_trace/backward_refs.py new file mode 100644 index 0000000..70793d3 --- /dev/null +++ b/dox_trace/dox_trace/backward_refs.py @@ -0,0 +1,241 @@ +from docutils import nodes + +from .helper import cat_name2level, create_ref_node +from .directives import DoxTraceDirective + +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def calc_parents(spec_options, target_ref_id): + current = spec_options[target_ref_id] + if "parents" not in current: + parents = set() + current["parents"] = parents + for r in current["upstream_refs"]: + opt = spec_options[r] + if r not in parents and opt["role"] != "information" and not opt["strike"]: + if opt["role"] == "requirement" and opt["category"] == "input": + parents.add(r) + grandparents = calc_parents(spec_options, r) + parents.update(grandparents) + return current["parents"] + + +def calc_backward(_app, env): + std = env.domaindata["std"] + + spec_options = std["spec_options"] + for ref_id, options in spec_options.items(): + options["upstream_refs"] = set() + options["downstream_refs"] = set() + + # direct parents + for source_ref_id, source_options in spec_options.items(): + if "refs" in source_options: + source_cat_level = cat_name2level[source_options["category"]] + + for target_spec_id in source_options["refs"]: + target_ref_id = target_spec_id.lower() + if target_ref_id in spec_options: + target_options = spec_options[target_ref_id] + target_cat_level = cat_name2level[target_options["category"]] + if target_cat_level > source_cat_level: + source_options["upstream_refs"].add(target_ref_id) + target_options["downstream_refs"].add(source_ref_id) + else: + source_options["downstream_refs"].add(target_ref_id) + target_options["upstream_refs"].add(source_ref_id) + else: + source_options["downstream_refs"].add(target_spec_id) + else: + spec_options[source_ref_id]["refs"] = [] + + # all parents (without information) + for target_ref_id in spec_options: + calc_parents(spec_options, target_ref_id) + + return None + + +def upstream_missing_trace(options): + return not options["strike"] and ("tags" not in options or "tool" not in options["tags"]) + + +def upstream_missing(options): + return ( + upstream_missing_trace(options) + and options["category"] != "input" + and options["role"] != "information" + ) + + +def downstream_missing_trace(options): + return ( + not options["strike"] + and not ("tags" in options and "covered" in options["tags"]) + and not (options["category"] == "module" and options["role"] == "interface") + ) + + +def downstream_missing(options): + return downstream_missing_trace(options) and not options["role"] in ["unit", "information"] + + +def inject_backward_references(app, doctree, fromdocname): + std = app.env.domaindata["std"] + allow_undefined_refs = app.env.config.dox_trace_allow_undefined_refs + spec_options = std["spec_options"] + for node in doctree.traverse(nodes.comment): + if "backward_ref_id" in node.attributes and "backward_attr" in node.attributes: + target_ref_id = node.attributes["backward_ref_id"] + target_attribute = node.attributes["backward_attr"] + + if target_attribute == "upstream": + rs = [] + options = spec_options[target_ref_id] + attr_formatted = node.attributes["backward_attr_formatted"] + inline = nodes.inline() + inline.set_class("dox-trace-grey") + for source_ref_id in sorted(spec_options[target_ref_id]["upstream_refs"]): + ref_node = create_ref_node(app, source_ref_id, fromdocname) + if len(rs) == 0: + rs.append(nodes.raw("", attr_formatted, format="html")) + else: + rs.append(nodes.Text(", ")) + rs.append(ref_node) + if len(rs) == 0: + if upstream_missing(options): + inline.set_class("dox-trace-attribute-missing") + html = f"{attr_formatted}[missing]
" + else: + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-
" + rs.append(nodes.raw("", html, format="html")) + else: + rs.append(nodes.raw("", "
", format="html")) + for n in rs: + inline.append(n) + node.replace_self(inline) + elif target_attribute == "downstream": + rs = [] + options = spec_options[target_ref_id] + attr_formatted = node.attributes["backward_attr_formatted"] + inline = nodes.inline() + inline.set_class("dox-trace-grey") + for source_ref_id in sorted(spec_options[target_ref_id]["downstream_refs"]): + if source_ref_id in spec_options: + ref_node = create_ref_node(app, source_ref_id, fromdocname) + else: + # source_ref_id is spec_id in this case (not lower-cased) + if allow_undefined_refs: + html = DoxTraceDirective.red + source_ref_id + DoxTraceDirective.colEnd + ref_node = nodes.raw("", html, format="html") + else: + spec_node = std["spec_node"][target_ref_id] + target_spec_id = std["spec_id"][target_ref_id] + logger.error( + f"{spec_node.source}.rst:{spec_node.line}: {target_spec_id} refers to non-existing {source_ref_id}" + ) + continue + if len(rs) == 0: + rs.append(nodes.raw("", attr_formatted, format="html")) + else: + rs.append(nodes.Text(", ")) + rs.append(ref_node) + if len(rs) == 0: + if downstream_missing(options): + inline.set_class("dox-trace-attribute-missing") + html = f"{attr_formatted}[missing]
" + else: + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-
" + rs.append(nodes.raw("", html, format="html")) + else: + rs.append(nodes.raw("", "
", format="html")) + for n in rs: + inline.append(n) + node.replace_self(inline) + elif target_attribute in [ + "parent_asil", + "parent_security", + "parent_cal", + "parent_tags", + ]: + inline = nodes.inline() + inline.set_class("dox-trace-grey") + node.replace_self(inline) + attr_formatted = node.attributes["backward_attr_formatted"] + if ( + "upstream_refs" not in spec_options[target_ref_id] + or len(spec_options[target_ref_id]["upstream_refs"]) == 0 + ): + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-" + inline.append(nodes.raw("", html, format="html")) + else: + opt = target_attribute[7:] + elems = set() + for p in sorted(spec_options[target_ref_id]["upstream_refs"]): + obw = spec_options[p] + if obw["role"] != "information" and not obw["strike"] and opt in obw: + attr = spec_options[p][opt] + if isinstance(attr, list): + elems.update(attr) + else: + elems.add(attr) + if len(elems) == 0: + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-" + inline.append(nodes.raw("", html, format="html")) + else: + inline.append( + nodes.raw("", attr_formatted + ", ".join(sorted(elems)), format="html") + ) + + else: # target_attribute in ["parent_feature", "parent_change_request"] + inline = nodes.inline() + inline.set_class("dox-trace-grey") + node.replace_self(inline) + attr_formatted = node.attributes["backward_attr_formatted"] + if ( + "parents" not in spec_options[target_ref_id] + or len(spec_options[target_ref_id]["parents"]) == 0 + ): + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-
" + inline.append(nodes.raw("", html, format="html")) + else: + opt = target_attribute[7:] + elems = set() + raw_nodes = [] + + for p in sorted(spec_options[target_ref_id]["parents"]): + v = spec_options[p][opt] + if v in elems or v == "": + continue + elems.add(v) + if len(raw_nodes) > 0: + raw_nodes.append(nodes.Text(", ")) + val = v.strip() + parent_node_key = opt + "_nodes" + if parent_node_key in spec_options[p]: + for n in spec_options[p][parent_node_key]: + raw_nodes.append(n.deepcopy()) + else: + # ensured in directives.py: + # len(val) > 12 and val.startswith(":raw-html:") + # otherwise this would be an alternative: + # raw_nodes.append(nodes.Text(val.replace("\n", " "))) + raw_nodes.append(nodes.raw("", val[11:-1], format="html")) + + if len(elems) == 0: + inline.set_class("dox-trace-attribute-empty") + html = f"{attr_formatted}-
" + inline.append(nodes.raw("", html, format="html")) + else: + inline.append(nodes.raw("", attr_formatted, format="html")) + for n in raw_nodes: + inline.append(n) + inline.append(nodes.raw("", "
", format="html")) diff --git a/dox_trace/dox_trace/checks.py b/dox_trace/dox_trace/checks.py new file mode 100644 index 0000000..87d3499 --- /dev/null +++ b/dox_trace/dox_trace/checks.py @@ -0,0 +1,78 @@ +import re + +from sphinx.util import logging +from docutils import nodes + +logger = logging.getLogger(__name__) + + +def check_invalid_refs(app): + std = app.env.domaindata["std"] + spec_options = app.env.domaindata["std"]["spec_options"] + for ref_id, options in spec_options.items(): + for target_spec_id in spec_options[ref_id]["refs"]: + target_spec_id_lower = target_spec_id.lower() + if target_spec_id_lower not in spec_options and target_spec_id_lower in std["labels"]: + logger.warning( + f"Found invalid reference from {std['spec_id'][ref_id]} to {target_spec_id}" + ) + + +def check_cyclic_recursive(app, spec_options, ref_id, cyclic_stack, already_checked): + if ref_id in cyclic_stack: + current_stack = [app.env.domaindata["std"]["spec_id"][c] for c in cyclic_stack + [ref_id]] + ref_stack = " -> ".join(current_stack) + logger.error(f"Found cyclic reference: {ref_stack}") + else: + cyclic_stack.append(ref_id) + ref_opt = spec_options[ref_id] + for target_spec_id in ref_opt["downstream_refs"]: + target_ref_id = target_spec_id.lower() + if ( + target_ref_id not in already_checked + and target_ref_id in spec_options + and ref_opt["category"] == spec_options[target_ref_id]["category"] + ): + check_cyclic_recursive( + app, spec_options, target_ref_id, cyclic_stack, already_checked + ) + cyclic_stack.pop() + already_checked.add(ref_id) + + +def check_cyclic(app): + spec_options = app.env.domaindata["std"]["spec_options"] + cyclic_stack = [] + already_checked = set() + for ref_id, options in spec_options.items(): + if ref_id not in already_checked: + check_cyclic_recursive(app, spec_options, ref_id, cyclic_stack, already_checked) + + +def check_case(app): + std = app.env.domaindata["std"] + spec_options = std["spec_options"] + for ref_id, options in spec_options.items(): + for target_spec_id in spec_options[ref_id]["refs"]: + target_spec_id_real = std["spec_id"][target_spec_id.lower()] + if target_spec_id != target_spec_id_real: + logger.error( + f"Incorrect case in refs of {std['spec_id'][ref_id]}: {target_spec_id} instead of {target_spec_id_real}" + ) + + +def check_unintended_comments(_app, doctree): + for node in doctree.traverse(nodes.comment): + if len(node.rawsource) > 0: + first_line = node.rawsource.partition("\n")[0] + for name in ["spec", "mod", "interface", "unit", "srs"]: + if re.match(rf"^\W*{name}\W*$", first_line) is not None: + logger.error( + f'{node.source}:{node.line}: first line of comment looks like a typo: "{first_line}"' + ) + + +def check_consistency(app, _env): + check_invalid_refs(app) + check_cyclic(app) + check_case(app) diff --git a/dox_trace/dox_trace/config.py b/dox_trace/dox_trace/config.py new file mode 100644 index 0000000..38994f6 --- /dev/null +++ b/dox_trace/dox_trace/config.py @@ -0,0 +1,171 @@ +import re +from pathlib import Path +from docutils import nodes +from sphinx.util.docutils import SphinxDirective +from docutils.statemachine import ViewList +from sphinx.util.nodes import nested_parse_with_titles +from sphinx.util import logging + +from .directives import ( + UnitDirective, + SpecDirective, + InterfaceDirective, + RequirementDirective, + InformationDirective, + ModDirective, + SrsDirective, + DoxTraceDirective, +) + +logger = logging.getLogger(__name__) + + +def config_inited(app, config): + static = Path.joinpath(Path(__file__).parent, "_static").as_posix() + config.html_static_path.append(static) + config.templates_path.append(static) + + app.add_css_file("dox_trace.css") + config.html_js_files.append("dox_trace.js") + + project = config.project if "project" in config and config.project else "Default" + project_clean = re.sub(r"\W+", "", project) + + config.rst_prolog += f""" +.. meta:: + :dox_trace_storage: {project_clean} +""" + + directive_map = { + "unit": UnitDirective, + "spec": SpecDirective, + "interface": InterfaceDirective, + "requirement": RequirementDirective, + "information": InformationDirective, + "mod": ModDirective, + "srs": SrsDirective, + } + + type_map = { + # pylint: disable=unnecessary-lambda + "text": lambda value: DoxTraceDirective.free_text(value), + "enum": lambda value: DoxTraceDirective.multi_enum(value), + "refs": lambda value: DoxTraceDirective.multi_enum(value), + # pylint: enable=unnecessary-lambda + } + + # fmt: off + for name, attr in config.dox_trace_custom_attributes.items(): + # STEP 1: check input + + # name + + if not isinstance(name, str): + logger.error("Names of custom attributes in config file must be strings") + if name in list(DoxTraceDirective.attribute_functions.keys()) + ["text"]: + logger.error(f"Custom attribute {name} in config file already exists") + if not isinstance(attr, dict): + logger.error(f"Custom attribute {name} in config file has wrong type") + + # type + + if "type" not in attr or not isinstance(attr["type"], str): + logger.error(f"Custom attribute {name} in config file must have a valid type") + if attr["type"] not in ["text", "enum", "refs"]: + logger.error(f"Custom attribute {name} in config file has invalid type {attr['type']}") + + # directive + + if "directives" not in attr or not isinstance(attr["directives"], list) or len(attr["directives"]) == 0: + logger.error(f"Custom attribute {name} in config file must be assigned to a list of at least one directive") + for d in attr["directives"]: + if d not in ["mod", "spec", "unit", "interface", "requirement", "information", "srs"]: + logger.error(f"Custom attribute {name} in config file is assigned to invalid directive {d}") + + # category + + if "requirement" in attr["directives"] or "information" in attr["directives"]: + if "categories" not in attr or not isinstance(attr["categories"], list) or len(attr["categories"]) == 0: + logger.error(f"Custom attribute {name} in config file must be assigned to a list of at least one category") + for c in attr["categories"]: + if c not in ["input", "software", "system"]: + logger.error(f"Custom attribute {name} in config file is assigned to invalid category {c}") + else: + attr["categories"] = None + + # default + + if "default" in attr: + if attr["type"] != "text": + if not isinstance(attr["default"], list): + logger.error(f"Custom attribute {name} in config file must have type list for default") + else: + attr["default"] = list(dict.fromkeys(attr["default"])) # make unique + elif not isinstance(attr["default"], str): + logger.error(f"Custom attribute {name} in config file must have type string for default") + if attr["default"] in ["", []]: + attr["default"] = None + else: + attr["default"] = None + + # export + + if "export" not in attr: + attr["export"] = "no" + else: + if not isinstance(attr["export"], str): + logger.error(f"Custom attribute {name} in config file has invalid type for export") + if attr["export"] not in ["yes", "no"]: + logger.error(f"Custom attribute {name} in config file has invalid value {attr['export']} for export") + + # STEP 2: add common_attribute data to directives + + if attr["export"] == "yes": + DoxTraceDirective.attribute_mappings["valid_in_dim"].append(name) + DoxTraceDirective.custom_attributes[name] = { + "type": attr["type"], + "default": attr["default"], + "categories": attr["categories"], + } + + for d in attr["directives"]: + directive_map[d].option_spec[name] = type_map[attr["type"]] + # fmt: on + + +class DoxTraceConfigDirective(SphinxDirective): + def run(self): + config = """.. raw:: html + +

Type, ID and content are always shown. Visibility of the other attributes:

+ +

+ + Show all
+ + + Hide empty
+ + + Hide empty and "[missing]"
+ + + Hide all +

+ """ + + filename = self.get_source_info()[0] + line_number = self.get_source_info()[1] + + rst = ViewList() + for line in config.split("\n"): + rst.append(line, filename) + + node = nodes.section() + node.document = self.state.document + nested_parse_with_titles(self.state, rst, node) + + for generated_node in node.traverse(): + generated_node.line = line_number + + return node.children diff --git a/dox_trace/dox_trace/coverage.py b/dox_trace/dox_trace/coverage.py new file mode 100644 index 0000000..10585d4 --- /dev/null +++ b/dox_trace/dox_trace/coverage.py @@ -0,0 +1,22 @@ +import os + +enable_coverage = os.environ.get("SPHINX_COVERAGE") + +if enable_coverage: + import coverage + + dox_trace_root = os.path.dirname(__file__) + source = [dox_trace_root] + omit = [os.path.join(dox_trace_root, "__init__.py"), __file__] + cov = coverage.Coverage(branch=True, source=source, omit=omit) + + +def coverage_start(): + if enable_coverage: + cov.start() + + +def coverage_end(): + if enable_coverage: + cov.stop() + cov.save() diff --git a/dox_trace/dox_trace/dim_write.py b/dox_trace/dox_trace/dim_write.py new file mode 100644 index 0000000..8e5a7af --- /dev/null +++ b/dox_trace/dox_trace/dim_write.py @@ -0,0 +1,75 @@ +import os.path +import re +import glob +import yaml + +from .directives import DoxTraceDirective + + +def calc_folder(app, prefix): + return os.path.join(app.config.dox_trace_dim_root, prefix).replace(os.sep, "/") + + +def calc_filename(app, prefix, docname): + return os.path.join(calc_folder(app, prefix), docname + ".dim") + + +def dim_write(app): + std = app.env.domaindata["std"] + + removed_folders = [] + for docname in std["local"]: + ref_ids = app.env.domaindata["std"]["local_ordered"][docname] + + contents = {} # category to content + modules = {} # category to module name + for ref_id in ref_ids: + spec_id = std["spec_id"][ref_id] + options = std["spec_options"][ref_id] + + if "ignore_in_export" in options: + continue + + role = options["role"] + if role not in ["unit", "interface", "spec", "mod", "srs"]: + continue + + # ensured that there is always a match in the beginning of run() in directives.py + m = re.match(r"^(([^_]+)_[^_]+)", spec_id) + module_name = m.group(1) + category = m.group(2).lower() + if category not in contents: + modules[category] = module_name + contents[category] = {} + contents[category][spec_id] = options + cmap = contents[category][spec_id] + + for key in list(cmap.keys()): + if key not in DoxTraceDirective.attribute_mappings["valid_in_dim"]: + del cmap[key] + + if role in ["interface", "unit"]: + cmap["tags"].append(role) + + for attr, value in cmap.items(): + if isinstance(value, list): + cmap[attr] = ", ".join(value) + + for category, module_name in modules.items(): + # delete old dim files + if category not in removed_folders: + removed_folders.append(category) + folder = calc_folder(app, category) + files = glob.glob(folder + "/**/*.dim", recursive=True) + for file in files: + os.remove(file) + + dim_filename = calc_filename(app, category, docname) + os.makedirs(os.path.dirname(dim_filename), exist_ok=True) + with open(dim_filename, "w") as yaml_file: + yaml_file.write("module: %s\n\n" % module_name) + for k, v in contents[category].items(): + entry = {k: v} + yaml_content = yaml.dump(entry) + yaml_file.write("\n") + yaml_file.write(yaml_content) diff --git a/dox_trace/dox_trace/directives.py b/dox_trace/dox_trace/directives.py new file mode 100644 index 0000000..704cc02 --- /dev/null +++ b/dox_trace/dox_trace/directives.py @@ -0,0 +1,820 @@ +import re +import os.path +from pathlib import Path +from typing import Dict, List, Any + +from docutils.parsers.rst import directives +from docutils import nodes +from sphinx import addnodes +from sphinx.util.docutils import SphinxDirective + +from sphinx.util import logging + +from .helper import DimViewList +from .roles import spec_role + +logger = logging.getLogger(__name__) + + +class DoxTraceDirective(SphinxDirective): + strike: bool + isInputReq: bool + isSRS: bool + iface_back_comp: bool + options: Dict[str, Any] + content: List[str] + + required_arguments = 1 # ID + has_content = True # text + final_argument_whitespace = True + + red = '' + grey = '' + colEnd = "" + + custom_attributes = {} + + @staticmethod + def strip(value): + if value is None: + return "" + value = value.strip() + if len(value) > 1: + if (value[0] == '"' and value[-1] == '"') or (value[0] == "'" and value[-1] == "'"): + value = value[1:-1] + return value.strip() + return value + + @staticmethod + def multi_enum(value): + value = DoxTraceDirective.strip(value) + if value is None or value.strip() in ['""', "''", ""]: + return [] + stripped_list = [] + for s in value.split(","): + s = DoxTraceDirective.strip(s) + if s != "" and s not in stripped_list: + stripped_list.append(s) + if len(stripped_list) == 0: + return [] + return stripped_list + + @staticmethod + def free_text(value): + value = DoxTraceDirective.strip(value) + if value is None or value.strip() in ['""', "''", ""]: + return "" + return value + + # fmt: off + attribute_functions = { + # pylint: disable=unnecessary-lambda + "status": lambda value: DoxTraceDirective.free_text(value), + "review_status": lambda value: DoxTraceDirective.free_text(value), + "feature": lambda value: DoxTraceDirective.free_text(value), + "change_request": lambda value: DoxTraceDirective.free_text(value), + "asil": lambda value: DoxTraceDirective.free_text(value), + "security": lambda value: DoxTraceDirective.free_text(value), + "cal": lambda value: DoxTraceDirective.free_text(value), + "reuse": lambda value: DoxTraceDirective.free_text(value), + "usage": lambda value: DoxTraceDirective.free_text(value), + "tags": lambda value: DoxTraceDirective.multi_enum(value), + + "developer": lambda value: DoxTraceDirective.free_text(value), + "tester": lambda value: DoxTraceDirective.free_text(value), + "test_setups": lambda value: DoxTraceDirective.multi_enum(value), + "verification_methods": lambda value: DoxTraceDirective.multi_enum(value), + + "verification_criteria": lambda value: DoxTraceDirective.free_text(value), + "comment": lambda value: DoxTraceDirective.free_text(value), + "miscellaneous": lambda value: DoxTraceDirective.free_text(value), + + "sources": lambda value: DoxTraceDirective.multi_enum(value), + "refs": lambda value: DoxTraceDirective.multi_enum(value), + "location": lambda value: DoxTraceDirective.free_text(value), + + "category": lambda value: DoxTraceDirective.free_text(value), + # pylint: enable=unnecessary-lambda + } + attribute_mappings = { + # pylint: disable=line-too-long + "mod": ["status", "review_status", "asil", "security", "cal", "developer", "reuse", "usage", "location"], + "spec": ["status", "review_status", "asil", "security", "cal", "tags", "developer", "tester", "test_setups", "verification_methods", "verification_criteria", "sources", "refs" ], + "unit": ["status", "review_status", "asil", "security", "cal", "tags", "developer", "tester", "test_setups", "verification_methods", "verification_criteria", "sources", "refs" ], + "interface": ["status", "review_status", "asil", "security", "cal", "tags", "developer", "tester", "test_setups", "verification_methods", "verification_criteria", "sources", "refs" ], + "srs": ["status", "review_status", "asil", "security", "cal", "tags", "developer", "tester", "test_setups", "verification_methods", "verification_criteria", "sources", "refs", ], + "requirement": ["status", "review_status", "asil", "security", "cal", "tags", "developer", "tester", "test_setups", "verification_methods", "verification_criteria", "comment", "miscellaneous", "feature", "change_request", "sources", "refs", "category" ], + "information": ["status", "review_status", "asil", "security", "cal", "tags", "comment", "miscellaneous", "refs", "category" ], + "valid_in_dim": ["status", "review_status", "asil", "tags", "developer", "tester", "verification_criteria", "comment", "miscellaneous", "feature", "change_request", "sources", "refs", "text" ], + # pylint: enable=line-too-long + } + # fmt: on + + @staticmethod + def create_option_spec(role): + option_spec_name = {"ignore_in_export": directives.flag} + for attr in DoxTraceDirective.attribute_mappings[role]: + option_spec_name[attr] = DoxTraceDirective.attribute_functions[attr] + return option_spec_name + + def attr_name(self, name, value, first=False): + separator = "" if first else " | " + + if value == "-": + prefix = '' + postfix = "" + elif value == "[missing]": + prefix = '' + postfix = "" + else: + prefix = "" + postfix = "" + + return f"{prefix}{separator}{name}: {value}{postfix}" + + def calc_status_attr(self): + if "status" in self.options: + status = self.options["status"] + else: + status = "draft" + self.options["status"] = status + if status == "invalid": + self.strike = True + + if "review_status" in self.options: + review_status = self.options["review_status"] + else: + if self.isInputReq: + review_status = "not_reviewed" + else: + review_status = "accepted" + self.options["review_status"] = review_status + + if review_status in ["rejected", "not_relevant"]: + self.strike = True + + attr = ["Status: ", status] + + if self.isInputReq or review_status != "accepted": + attr.append(f" | Review Status: {review_status}") + + return "".join(attr) + + def calc_test_dev_attr(self, spec_id): + attr = [] + + if self.role not in ["information"]: + ref_id = spec_id.lower() + + developer = self.options["developer"] if "developer" in self.options else None + if developer: + developer = developer.replace("\n", " ") + else: + self.options["developer"] = "" + if self.strike: + developer = "-" + else: + developer = "[missing]" + attr.append(self.attr_name("Developer", developer, True)) + + self.options["developer_split"] = [ + d.strip() for d in self.options["developer"].split(",") + ] + + if self.env.config.dox_trace_test_setups_backward: + if "verification_methods" in self.options and "test_setups" not in self.options: + self.options["test_setups"] = self.options["verification_methods"] + ts_attr_name = "test_setups" + ts_display_name = "Test Setups" + else: + if "test_setups" in self.options and "verification_methods" not in self.options: + self.options["verification_methods"] = self.options["test_setups"] + ts_attr_name = "verification_methods" + ts_display_name = "Verification Methods" + + if (self.role != "mod") and not self.iface_back_comp: + tester = self.options["tester"] if "tester" in self.options else None + if tester: + tester = tester.replace("\n", " ") + else: + self.options["tester"] = "" + if self.strike or ( + ts_attr_name in self.options + and len(self.options[ts_attr_name]) == 1 + and self.options[ts_attr_name][0] == "none" + ): + tester = "-" + else: + tester = "[missing]" + attr.append(self.attr_name("Tester", tester)) + + ts = None + + if ts_attr_name in self.options: + ts = self.options[ts_attr_name] + if not ts: + if self.role in ["unit", "spec", "interface", "srs"]: + if ref_id.startswith("smd_"): + ts = ["off_target"] + else: # must be swa_ or srs_ + ts = ["on_target"] + self.options[ts_attr_name] = ts + else: + self.options[ts_attr_name] = "none" + if ts: + test_setups = ", ".join(ts) + else: + test_setups = "-" + attr.append(self.attr_name(ts_display_name, test_setups)) + + if ( + developer not in ["-", "[missing]"] + or tester not in ["-", "[missing]"] + or test_setups != "-" + ): + attr.append("
") + elif developer == "[missing]" or tester == "[missing]": + attr.append('
') + else: + attr.append('
') + else: + self.options["tester"] = "" + self.options[ts_attr_name] = ["none"] + + return "".join(attr) + + def get_property(self, module_name, attribute_name): + p = self.env.config.properties + if module_name in p and attribute_name in p[module_name]: + return p[module_name][attribute_name] + return None + + def calc_asil_sec_review_attr(self): + attr = ["Asil: "] + + if "asil" in self.options: + asil = self.options["asil"] + else: + asil = "not_set" + self.options["asil"] = asil + attr.append(asil) + + if self.env.config.dox_trace_security_backward: + if "security" in self.options: + sec = self.options["security"] + else: + if "cal" in self.options: + if self.options["cal"] == "QM": + sec = "no" + elif self.options["cal"] in ["CAL_1", "CAL_2", "CAL_3", "CAL_4"]: + sec = "yes" + else: + sec = "not_set" + else: + sec = "not_set" + self.options["security"] = sec + attr.append(f" | Security: {sec}") + else: + if "cal" in self.options: + cal = self.options["cal"] + else: + if "security" in self.options: + if self.options["security"] == "yes": + cal = "CAL_4" + elif self.options["security"] == "no": + cal = "QM" + else: + cal = "not_set" + else: + cal = "not_set" + self.options["cal"] = cal + attr.append(f" | Cal: {cal}") + + if self.role == "mod": + if "reuse" in self.options and self.options["reuse"] != "": + attr.append(" | Reuse: " + self.options["reuse"]) + else: + attr.append( + ' | Reuse: -' + ) + + if "usage" in self.options and self.options["usage"] != "": + attr.append(" | Usage: " + self.options["usage"]) + else: + attr.append( + ' | Usage: -' + ) + + return "".join(attr) + + def calc_sources(self, document, line_number): + sources = self.options["sources"] + + if self.role in ["unit", "spec", "interface", "srs"]: # check for existence + rst_file = document.settings.env.docname + split = ("/" + rst_file).replace("\\", "/").split("/doc/") + dir_source = os.path.dirname(document.get("source")) + for s in sources: + file = None + if len(split) > 1: # source referenced from regular module + path2mod = "../" * (split[-1].count("/") + 1) + file = os.path.join(dir_source, path2mod + s) + if not file or not os.path.isfile(file): # fallback for non-standard modules + file = os.path.join(dir_source, s) + if not os.path.isfile(file): + logger.error( + f'{document.settings.env.docname}.rst:{line_number}: file "{s}" not found' + ) + + file_res = Path(file).resolve() + srcdir_res = Path(self.env.app.srcdir).resolve() + rel_to_base = str(file_res.relative_to(srcdir_res)).replace("\\", "/") + if "sources_base" not in self.options: + self.options["sources_base"] = {rel_to_base} + else: + self.options["sources_base"].add(rel_to_base) + else: # role == "requirement", checked in Dim + self.options["sources_base"] = sources + + return ", ".join(sources) + + def run(self): + std = self.env.domaindata["std"] + spec_id = self.arguments[0] + ref_id = spec_id.lower() + document = self.state.document + docname = document.settings.env.docname + line_number = self.get_source_info()[1] + self.iface_back_comp = ref_id.startswith("smd_") and self.role == "interface" + + raw_nodes = [] + self.strike = False + + if "\n" in spec_id: + spec_id_nl = spec_id.replace("\n", "\\n") + logger.error(f"{docname}.rst:{line_number}: id {spec_id_nl} must not contain newlines") + + if hasattr(self.env.config, "properties"): + parts = spec_id.split("_") + module_name = "_".join(parts[0:2]) if len(parts) > 2 else None + for attr in list(self.option_spec.keys()) + ["content"]: + if attr == "content" and len(self.content) > 0: + continue + if attr not in self.options: + val = self.get_property(spec_id, attr) # e.g. SWA_MyModule_Abc + if val is None and module_name is not None: + val = self.get_property(module_name, attr) # e.g. SWA_MyModule + if val is None: + val = self.get_property(parts[0], attr) # e.g. SWA + if val is None: + val = self.get_property("_default_", attr) + if val: + if attr == "content": + self.content = val.split("\n") + else: + if isinstance(val, str) and attr in self.attribute_functions: + val = self.attribute_functions[attr](val) + self.options[attr] = val + + if self.role in ["requirement", "information"]: + if "category" in self.options and self.options["category"] in ["software", "system"]: + category = self.options["category"] + else: + category = "input" + + # Use the top level heading as module name, because elements from Dim, especially + # customer requirements, do not follow a naming convention, which makes it impossible + # to derive a module name. + titles = document.traverse(nodes.title) + if len(titles) > 0: + self.options["module_name"] = titles[0].astext() + else: + self.options["module_name"] = "Unknown" + else: + if self.env.config.dox_trace_allow_deprecated: + prefix = { + "srs": "SRS", + "spec": "SMD|SWA", + "unit": "SMD|SWA", + "mod": "SMD|SWA", + "interface": "SMD|SWA", + } + else: + prefix = { + "srs": "SRS", + "spec": "SMD|SWA", + "unit": "SMD", + "mod": "SWA", + "interface": "SWA", + } + + if self.env.config.dox_trace_tolerant_naming_convention and self.role != "srs": + postfix = "_[^_]" + postfix_readable = "_" + else: + postfix = "_[^_]+_[^_]+$" + postfix_readable = "__" + + if not re.match(rf"^({prefix[self.role]}){postfix}", spec_id): + logger.error( + f"{docname}.rst:{line_number}: id {spec_id} does not follow the form {prefix[self.role]}{postfix_readable}" + ) + + if spec_id.startswith("SRS_"): + category = "software" + elif spec_id.startswith("SWA_"): + category = "architecture" + else: # SMD_ + category = "module" + + self.options["category"] = category + + self.isInputReq = self.role == "requirement" and self.options["category"] == "input" + self.isSRS = self.role == "srs" or ( + self.role == "requirement" and self.options["category"] == "software" + ) + + self.options = { + k: v for k, v in self.options.items() if v is not None or k == "ignore_in_export" + } + + status_attr = self.calc_status_attr() + test_dev_attr = self.calc_test_dev_attr(spec_id) + # calcAsilSecReviewAttr must be called after calcTestDevAttr + asil_sec_review_attr = self.calc_asil_sec_review_attr() + + self.options["strike"] = self.strike + + html = [] + if self.strike: + html.append('
\n') + opa = "; opacity: 0.5" + else: + opa = "" + html.append( + f'\n' + ' \n' + " \n" + ' \n" + ' \n' + f' \n \n") + + additional_attributes = [] + if not ((self.role == "information" and category != "input") or (self.role == "mod")): + additional_attributes.append({"name": "verification_criteria", "mode": "vc"}) + if self.options["category"] == "input": + additional_attributes.append({"name": "comment", "mode": "comment"}) + additional_attributes.append({"name": "feature", "mode": "feature"}) + additional_attributes.append({"name": "change_request", "mode": "cr"}) + additional_attributes.append({"name": "miscellaneous", "mode": "misc"}) + else: + additional_attributes.append({"name": "derived", "mode": "feature"}) + additional_attributes.append({"name": "derived", "mode": "change_request"}) + + for name, ca in DoxTraceDirective.custom_attributes.items(): + if name in self.option_spec: + if self.role in ["requirement", "information"]: + if self.options["category"] not in ca["categories"]: + continue + if name not in self.options and ca["default"]: + self.options[name] = ca["default"] + additional_attributes.append({"name": name, "mode": ca["type"]}) + + if len(additional_attributes) > 0: + html.append( + ' \n \n') + + if self.iface_back_comp: + self.options.pop("verification_criteria", None) + elif ( + "verification_criteria" in self.options + and self.options["verification_criteria"] != "" + ): + self.options["verification_criteria"] = "See Sphinx documentation." + + html.append(' \n \n

\n' + " " + ) + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + + spec_nodes, ign = spec_role(f"{self.role}_generated", "", spec_id, line_number, self.state) + raw_nodes.extend(spec_nodes) + + html = [ + f'   {status_attr}\n' + "

\n' + f" {asil_sec_review_attr}" + ] + + if category != "input": + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + + attr_formatted = " | " + "Upstream Asil: " + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = "parent_asil" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + + cal_str = "Security" if self.env.config.dox_trace_security_backward else "Cal" + attr_formatted = " | " + f"Upstream {cal_str}: " + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = f"parent_{cal_str.lower()}" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + + html = ["
\n"] + else: + html.append("
\n") + + if test_dev_attr != "": + html.append(f" {test_dev_attr}\n") + + if "tags" not in self.options: + self.options["tags"] = [] + tags = self.options["tags"] + if self.role != "mod": + value = ", ".join(tags) if len(tags) > 0 else "-" + html.append(f' {self.attr_name("Tags", value, True)}') + + if category != "input": + if len(tags) == 0: + html.append(' | ') + bar = "" + else: + bar = " | " + attr_formatted = bar + "Upstream Tags: " + + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = "parent_tags" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + html = ["\n"] + else: + html.append("\n") + + # the content + html.append('

\n') + if len(self.content) == 0: + html.append(" [missing]\n") + self.options["text"] = "" + else: + if ( + self.role in ["requirement", "information"] + and len(self.content) == 1 + and len(self.content[0]) > 12 + and self.content[0].startswith(":raw-html:") + ): + html.append(f" {self.content[0][11:-1]}") + else: + html.append(" ") + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + html = [] + text_nodes = DimViewList.string_to_nodes(self.content, self.content_offset, self) + raw_nodes.extend(text_nodes) + self.options["text"] = "See Sphinx documentation." + html.append("

\n' + ) + + for attr in additional_attributes: + name = attr["name"] + mode = attr["mode"] + if name in self.option_spec and not self.iface_back_comp: + pretty_name = name.replace("_", " ").title() + if ( + name in self.options + and self.options[name] + and self.options[name] == ":raw-html:``" + ): + self.options[name] = "" + + if name in self.options and self.options[name]: + val = self.options[name] + html.append(f" {pretty_name}: ") + if mode == "enum": + html.append(", ".join(val)) + html.append("
\n") + elif mode == "refs": + for r in val: + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + explicit = bool(re.match(r"^(SMD|SWA)_[^_\n<> ]+_([^\n<> ]+)", r)) + ref_node = addnodes.pending_xref( + "", + refdomain="std", + refexplicit=explicit, + reftarget=r.lower(), + reftype="ref", + refwarn=True, + ) + ref_node += nodes.Text(r) + inline_node = nodes.inline() + inline_node += ref_node + raw_nodes.append(inline_node) + html = [", "] + html = ["
\n"] + else: # text + if ( + self.role in ["requirement", "information"] + and len(val) > 11 + and val.startswith(":raw-html:`") + and val.endswith("`") + ): + html.append(val[11:-1]) + html.append("
\n") + else: + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + # in options of directives no empty lines are allowed, therefore + # preserve line breaks expect if line ends with backlash + val = re.sub(r"( )*\\( )*(\n|$)", " ", val, re.M).strip() + self.options[name] = val + val = val.replace("\n", "\n\n").split("\n") + + if len(val) > 1: + # Sphinx does not render paragraphs like bullet points correctly + # here if not prepended by whitespaces + val = [" " + v for v in val] + html = [] + else: + html = ["
\n"] + text_nodes = DimViewList.string_to_nodes( + val, self.content_offset, self + ) + # The ViewList from docutils always generates a paragraph wrapper + # node, here text_nodes[0]. This will be replaced by an inline node + # to avoid newlines in the HTML output. + additional_attributes_node = nodes.inline() + additional_attributes_node += text_nodes[0].children + raw_nodes.append(additional_attributes_node) + self.options[name + "_nodes"] = text_nodes[0].children + elif name == "verification_criteria": + if self.isSRS and "tool" not in tags and not self.strike: + html.append( + ' Verification Criteria: [missing]
\n' + ) + else: + html.append( + ' Verification Criteria: -
\n' + ) + self.options[name] = "" + else: + html.append( + f' {pretty_name}: -
\n' + ) + self.options[name] = "" + elif name == "derived": + name = mode + pretty_name = name.replace("_", " ").title() + attr_formatted = f"Derived {pretty_name}: " + html.append(" ") + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = f"parent_{name}" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + html = ["\n"] + + html.append('

\n') + html.append(" ") + attr_formatted = "Upstream References: " + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = "upstream" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + html = ["\n"] + if self.role != "mod": + html.append(" ") + attr_formatted = "Downstream References: " + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + n = nodes.comment() + n.attributes["backward_ref_id"] = ref_id + n.attributes["backward_attr"] = "downstream" + n.attributes["backward_attr_formatted"] = attr_formatted + inline_node = nodes.inline() + inline_node += n + raw_nodes.append(inline_node) + html = [] + if "sources" in self.option_spec: + if self.role == "unit" or self.iface_back_comp or "sources" in self.options: + html = ["\n"] + if "sources" not in self.options: + if self.strike or "covered" in tags: + html.append( + ' Sources: -\n' + ) + else: + html.append( + ' Sources: [missing]\n' + ) + self.options["sources"] = [] + else: + sources = self.calc_sources(document, line_number) + html.append(f" Sources: {sources}\n") + else: + self.options["sources"] = [] + + else: # a mod specification + if "location" in self.options: + html.append(" Location: ") + file = os.path.join( + self.env.app.srcdir, self.options["location"], "doc/index" + ).replace("\\", "/") + file_with_ending = file + ".rst" + if not os.path.isfile(file_with_ending): + if self.strike: + html.append(self.options["location"]) + else: + html.append(self.red + self.options["location"] + self.colEnd) + else: + rst_file = os.path.join(self.env.app.srcdir, docname).replace("\\", "/") + rst_dir = os.path.dirname(rst_file) + doc_link = os.path.relpath(file, rst_dir).replace("\\", "/") + + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + ref_node = addnodes.pending_xref( + "", + refdomain="std", + refexplicit=True, + reftarget=doc_link, + reftype="doc", + refwarn=True, + ) + ref_node += nodes.Text(self.options["location"]) + inline_node = nodes.inline() + inline_node += ref_node + raw_nodes.append(inline_node) + html = [] + self.options["tags"] = ["covered"] + html.append("\n") + else: + if self.strike: + html.append( + ' Location: -\n' + ) + else: + html.append( + ' Location: [missing]\n' + ) + + html.append("

\n") + if self.strike: + html.append( + '
\n
\n' + ) + + raw_nodes.append(nodes.raw("", "".join(html), format="html")) + + std["spec_options"][ref_id] = self.options + std["spec_options"][ref_id]["role"] = self.role + + return raw_nodes + + +class UnitDirective(DoxTraceDirective): + role = "unit" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class SpecDirective(DoxTraceDirective): + role = "spec" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class InterfaceDirective(DoxTraceDirective): + role = "interface" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class RequirementDirective(DoxTraceDirective): + role = "requirement" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class InformationDirective(DoxTraceDirective): + role = "information" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class ModDirective(DoxTraceDirective): + role = "mod" + option_spec = DoxTraceDirective.create_option_spec(role) + + +class SrsDirective(DoxTraceDirective): + role = "srs" + option_spec = DoxTraceDirective.create_option_spec(role) diff --git a/dox_trace/dox_trace/enclosed.py b/dox_trace/dox_trace/enclosed.py new file mode 100644 index 0000000..a4a56a2 --- /dev/null +++ b/dox_trace/dox_trace/enclosed.py @@ -0,0 +1,43 @@ +""" +Copies files from source folder to output folder preserving the path. +Example: + +.. enclosed:: + + demo.pdf + images/test.png +""" + +from pathlib import Path +import shutil +from sphinx.util.docutils import SphinxDirective + +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +class EnclosedDirective(SphinxDirective): + has_content = True + + def run(self): + for num, filename in enumerate(self.content, start=0): + rst_folder = Path(self.content.info(num)[0]).parent + sub_folder = rst_folder.relative_to(self.env.app.srcdir) + + source = rst_folder.joinpath(filename) + target = Path(self.env.app.builder.outdir).joinpath(sub_folder, filename) + + if not source.is_file(): + logger.warning( + '%s:%d: file "%s" does not exist' + % ( + self.content.info(num)[0], + self.content.info(num)[1] + 1, + filename, + ) + ) + else: + target.parent.mkdir(parents=True, exist_ok=True) + shutil.copyfile(source, target) + return [] diff --git a/dox_trace/dox_trace/env.py b/dox_trace/dox_trace/env.py new file mode 100644 index 0000000..bce4dab --- /dev/null +++ b/dox_trace/dox_trace/env.py @@ -0,0 +1,110 @@ +import re +import copy + +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def prepare_env(app, _env, _docnames): + std = app.env.domaindata["std"] + + # docname => ref_ids + if "local" not in std: + std["local"] = {} + if "local_ordered" not in std: + std["local_ordered"] = {} + + # ref_id => node + if "spec_node" not in std: + std["spec_node"] = {} + + # ref_id => spec_id + if "spec_id" not in std: + std["spec_id"] = {} + + # ref_id => spec_id + if "spec_options" not in std: + std["spec_options"] = {} + + std["last_dox_trace_version"] = app.extensions["dox_trace"].version + + +def add_node_to_env(document, spec_id, node): + ref_id = spec_id.lower() + env = document.settings.env + std = env.domaindata["std"] + + if ref_id in std["spec_id"]: + logger.error(f"specification {spec_id} found twice") + + docname = env.docname + if docname not in env.domaindata["std"]["local"]: + std["local"][docname] = {ref_id} + std["local_ordered"][docname] = [ref_id] + else: + std["local"][docname].add(ref_id) + std["local_ordered"][docname].append(ref_id) + + text = spec_id + m = re.match(r"^(SMD|SWA)_[^_\n<> ]+_([^\n<> ]+)", spec_id) + if m: + text = m.group(2).strip() + + std["anonlabels"][ref_id] = env.docname, ref_id + std["labels"][ref_id] = env.docname, ref_id, text + std["spec_node"][ref_id] = node + std["spec_id"][ref_id] = spec_id + + +def purge_doc_from_env(_app, env, docname): + std = env.domaindata["std"] + doc_attr = ["spec_options", "anonlabels", "labels", "spec_node", "spec_id"] + if docname in env.domaindata["std"]["local"]: + for ref_id in std["local"][docname]: + for attr in doc_attr: + assert attr in std + std[attr].pop(ref_id, None) + std["local"].pop(docname, None) + std["local_ordered"].pop(docname, None) + + +def merge_env_parallel_build(_app, env, _docnames, other): + std = env.domaindata["std"] + std_other = other.domaindata["std"] + + doc_attr = [ + "local", + "local_ordered", + "spec_node", + "spec_id", + "spec_options", + "anonlabels", + "labels", + ] + for attr in doc_attr: + std[attr].update(std_other[attr]) + + +# for unit testing only +def merge_env_parallel_build_non_posix(app, _doctree, _docname): + other = copy.deepcopy(app.env) + std = app.env.domaindata["std"] + doc_attr = [ + "local", + "local_ordered", + "spec_node", + "spec_id", + "spec_options", + "anonlabels", + "labels", + ] + for attr in doc_attr: + std[attr].clear() + merge_env_parallel_build(app, app.env, None, other) + + ext = app.extensions["dox_trace"] + read_allowed = getattr(ext, "parallel_read_safe", None) + write_allowed = getattr(ext, "parallel_write_safe", None) + tester_dummy = "Parallel = " + str(read_allowed and write_allowed) + std["spec_options"]["swa_spec_main"]["tester"] = tester_dummy diff --git a/dox_trace/dox_trace/helper.py b/dox_trace/dox_trace/helper.py new file mode 100644 index 0000000..d857dec --- /dev/null +++ b/dox_trace/dox_trace/helper.py @@ -0,0 +1,91 @@ +from docutils import nodes +from docutils.statemachine import ViewList +from sphinx.util.nodes import nested_parse_with_titles + +cat_name2level = {"module": 1, "architecture": 2, "software": 3, "system": 4, "input": 5} + + +def create_ref_node(app, ref_id, fromdocname): + std = app.env.domaindata["std"] + spec_id = std["spec_id"][ref_id] + docname, r = std["anonlabels"][ref_id] + refuri = app.builder.get_relative_uri(fromdocname, docname) + "#" + r + return nodes.reference( + spec_id, + spec_id, + internal=True, + refdocname=docname, + refuri=refuri, + refid=r, + ) + + +class DimViewList(ViewList): + def __init__(self, filename): + self.filename = filename + super().__init__() + + def puts(self, string): + self.append(string, self.filename) + + @staticmethod + def string_to_nodes(string, offset, directive): + filename = directive.get_source_info()[0] + line_number = directive.get_source_info()[1] + + rst = DimViewList(filename) + for s in string: + rst.puts(s) + + node = nodes.section() + node.document = directive.state.document + nested_parse_with_titles(directive.state, rst, node, offset) + + titles = [] + for generated_node in node.traverse(): + if isinstance(generated_node, nodes.title): + titles.append(generated_node) + generated_node.line = line_number + + # within a spec-box, there is sometimes no newline rendered by RTD before a heading + previous_parent = None + for t in titles: + p = t.parent + assert p is not None # in most cases p is a section node + pp = p.parent + assert pp is not None # in most cases pp is a section node + + # in the following case, Sphinx renders a newline already + if (pp.parent is not None or previous_parent is None) and pp.parent != previous_parent: + previous_parent = pp.parent + continue + previous_parent = pp.parent + + # if spec is starting with a heading, no newline is needed + idx = pp.index(p) + if idx == 0: + continue + # also no newline is needed if the heading has an anchor, e.g. .. _xyz: + if isinstance(pp.children[idx - 1], nodes.target): + continue + # or previous element is a block + if isinstance(pp.children[idx - 1], nodes.literal_block): + continue + # or previous element ended with a block + pp_grandchildren = pp.children[idx - 1].children + if len(pp_grandchildren) > 0 and isinstance(pp_grandchildren[-1], nodes.literal_block): + continue + + # the newline is enforced by an invisible space instead of
, because in some + # situations the
would be packed into a container/span/paragraph, which makes the + # vertical gap before the heading larger than intended + newline = nodes.raw("", " ", format="html") + + if len(pp_grandchildren) > 0 and isinstance(pp_grandchildren[-1], nodes.target): + # if previous section ended with an anchor, place the newline here + pp_grandchildren.insert(len(pp_grandchildren) - 1, newline) + else: + # otherwise in front of the heading + pp.children.insert(idx, newline) + + return node.children diff --git a/dox_trace/dox_trace/main.py b/dox_trace/dox_trace/main.py new file mode 100644 index 0000000..a0ca5a5 --- /dev/null +++ b/dox_trace/dox_trace/main.py @@ -0,0 +1,194 @@ +import sys +import yaml +import os + +from .dim_write import dim_write +from .backward_refs import calc_backward, inject_backward_references +from .env import ( + prepare_env, + purge_doc_from_env, + merge_env_parallel_build, + merge_env_parallel_build_non_posix, +) +from .report import DoxTraceTraceabilityDirective, inject_report +from .undefined_refs import ( + UndefinedRefsDirective, + calc_unresolved_references, + inject_undefined_references, +) +from .checks import check_unintended_comments, check_consistency +from .properties import prop_role, PropDirective +from .enclosed import EnclosedDirective +from .config import config_inited, DoxTraceConfigDirective +from .coverage import coverage_end +from .roles import spec_role +from .directives import ( + ModDirective, + UnitDirective, + SpecDirective, + InterfaceDirective, + SrsDirective, + RequirementDirective, + InformationDirective, + DoxTraceDirective, +) +from sphinx import version_info as sphinx_version +from sphinx.util import logging +from .yaml import SafeLoaderWithoutBoolean +from .version import __version__ + +if sys.version_info < (3, 8): + try: + raise RuntimeError("The dox_trace extension requires Python 3.8+") + finally: + coverage_end() + +if sphinx_version < (6, 2, 0): + try: + raise RuntimeError("The dox_trace extension requires Sphinx 6.2+") + finally: + coverage_end() + +logger = logging.getLogger(__name__) + + +# needed to collect coverage correctly in unit test +def config_inited_wrapper(app, config): + exception_raised = False + try: + if config.dox_trace_properties_file: + if not os.path.isfile(config.dox_trace_properties_file): + raise ValueError("%s does not exist" % config.dox_trace_properties_file) + with open(config.dox_trace_properties_file, "r") as stream: + config["properties"] = yaml.load(stream, SafeLoaderWithoutBoolean) + + DoxTraceDirective.attribute_mappings["valid_in_dim"].append( + "security" if config.dox_trace_security_backward else "cal" + ) + DoxTraceDirective.attribute_mappings["valid_in_dim"].append( + "test_setups" if config.dox_trace_test_setups_backward else "verification_methods" + ) + + return config_inited(app, config) + except Exception as e: + exception_raised = True + raise e + finally: + if exception_raised: + coverage_end() + + +def build_finished(app, exception): + try: + if exception: + raise exception + + if app.config.dox_trace_dim_root: + logger.info("writing Dim files... ", nonl=True) + dim_write(app) + logger.info("done") + + except Exception as e: + # use this to debug bugs in this extension + # import traceback + # traceback.print_exc() + raise e + finally: + coverage_end() + + +def version_changed(app, env, _added, _changed, _removed): + std = env.domaindata["std"] + version = app.extensions["dox_trace"].version + if "last_dox_trace_version" not in std or std["last_dox_trace_version"] != version: + return app.env.found_docs + return [] + + +def setup(app): + ########################### + # EXTENSION CONFIGURATION # + ########################### + + app.add_config_value("dox_trace_dim_root", None, "html", [str]) + app.add_config_value("dox_trace_tolerant_naming_convention", False, "html", [bool]) + app.add_config_value("dox_trace_allow_deprecated", False, "html", [bool]) + app.add_config_value("dox_trace_allow_undefined_refs", False, "html", [bool]) + app.add_config_value("dox_trace_security_backward", {}, "html", [bool]) + app.add_config_value("dox_trace_test_setups_backward", {}, "html", [bool]) + app.add_config_value("dox_trace_custom_attributes", {}, "html", [dict]) + app.add_config_value("dox_trace_properties_file", None, "html", [str]) + + ################ + # OFFICIAL API # + ################ + + # directives used by developers writing documentation + app.add_directive("mod", ModDirective) + app.add_directive("spec", SpecDirective) + app.add_directive("unit", UnitDirective) + app.add_directive("interface", InterfaceDirective) + app.add_directive("srs", SrsDirective) + + # directives used by Dim tool + app.add_directive("requirement", RequirementDirective) + app.add_directive("information", InformationDirective) + + # special commands for configuration / displaying information + app.add_directive("dox_trace_config", DoxTraceConfigDirective) + app.add_directive("undefined_refs", UndefinedRefsDirective) + app.add_directive("traceability_report", DoxTraceTraceabilityDirective) + + # properties + app.add_role("prop", prop_role) + app.add_directive("prop", PropDirective) + + # enclosed + app.add_directive("enclosed", EnclosedDirective) + + ############################### + # INTERNAL API, NO PUBLIC USE # + ############################### + + app.add_role("mod_generated", spec_role) + app.add_role("spec_generated", spec_role) + app.add_role("unit_generated", spec_role) + app.add_role("interface_generated", spec_role) + app.add_role("requirement_generated", spec_role) + app.add_role("information_generated", spec_role) + app.add_role("srs_generated", spec_role) + + #################### + # SPHINX CALLBACKS # + #################### + + app.connect("config-inited", config_inited_wrapper) + app.connect("env-get-outdated", version_changed) + app.connect("env-before-read-docs", prepare_env) + app.connect("env-purge-doc", purge_doc_from_env) + app.connect("env-merge-info", merge_env_parallel_build) + app.connect("doctree-read", check_unintended_comments) + app.connect("env-updated", calc_backward) + app.connect("env-updated", calc_unresolved_references) + app.connect("env-check-consistency", check_consistency) + app.connect("doctree-resolved", inject_backward_references) + app.connect("doctree-resolved", inject_undefined_references) + app.connect("doctree-resolved", inject_report) + app.connect("build-finished", build_finished) + + #################### + # FOR UNIT TESTING # + #################### + + version = __version__ + if os.environ.get("MANIPULATE_DOXTRACE_VERSION"): + version = "manipulated_version" + + if os.environ.get("MANIPULATE_DOXTRACE_PARALLEL"): + app.connect("doctree-resolved", merge_env_parallel_build_non_posix) + + return { + "version": version, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/dox_trace/dox_trace/properties.py b/dox_trace/dox_trace/properties.py new file mode 100644 index 0000000..50ee5c4 --- /dev/null +++ b/dox_trace/dox_trace/properties.py @@ -0,0 +1,75 @@ +from docutils import nodes +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective +from docutils.statemachine import ViewList +from sphinx.util.nodes import nested_parse_with_titles + +logger = logging.getLogger(__name__) + + +def prop_read(config, module, attribute): + if ( + isinstance(config.properties, dict) + and module in config.properties + and isinstance(config.properties[module], dict) + and attribute in config.properties[module] + ): + return config.properties[module][attribute] + return None + + +def prop_value(config, text, filename, line_number): + value = None + if hasattr(config, "properties"): + split = text.split(":") + if len(split) == 2: + module = split[0] + attribute = split[1] + value = prop_read(config, module, attribute) + if not value: + value = prop_read(config, "_default_", attribute) + if not value: + logger.error(f"{filename}.rst:{line_number}: property {text} not found") + else: + logger.error( + f'{filename}.rst:{line_number}: property {text} does not include exactly one ":"' + ) + else: + logger.error( + f"{filename}.rst:{line_number}: dox_trace_properties_file not specified in configuration" + ) + return value + + +def prop_role(_role, rawtext, text, lineno, inliner, _options={}, _content=[]): + env = inliner.document.settings.env + config = env.app.config + value = prop_value(config, text, env.docname, lineno) + + node = nodes.literal(rawtext, value) + node.set_class("highlight") + node.set_class("highlight-prop") + + return [node], [] + + +class PropDirective(SphinxDirective): + required_arguments = 1 + has_content = False + + def run(self): + spec_id = self.arguments[0] + filename = self.get_source_info()[0] + document = self.state.document + line_number = self.get_source_info()[1] + + value = prop_value(self.env.app.config, spec_id, document.settings.env.docname, line_number) + + rst = ViewList() + for line in value.split("\n"): + rst.append(line, filename, line_number) + + node = nodes.section() + node.document = document + nested_parse_with_titles(self.state, rst, node) + return node.children diff --git a/dox_trace/dox_trace/report.py b/dox_trace/dox_trace/report.py new file mode 100644 index 0000000..25ec849 --- /dev/null +++ b/dox_trace/dox_trace/report.py @@ -0,0 +1,174 @@ +import re + +from docutils import nodes +from docutils.parsers.rst import directives + +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective + +from .helper import DimViewList +from .report_input import calc_table_input_developer, calc_table_input_review_status +from .report_architecture import calc_table_architecture_type +from .report_module import calc_table_module_type +from .report_source import calc_source_list +from .report_generic import ( + calc_table_status, + calc_table_safety, + calc_table_stream, + calc_table_list, + calc_table_security, + calc_table_cal, +) + + +logger = logging.getLogger(__name__) + + +class DoxTraceTraceabilityDirective(SphinxDirective): + required_arguments = 1 # ID + has_content = False + option_spec = {"developer": directives.unchanged_required} + + def add_chapter(self, category, function_name, title, text=""): + if title: + title_node = DimViewList.string_to_nodes( + [title, len(title) * "-", text], self.content_offset, self + ) + else: + title_node = [nodes.inline()] + report_node = nodes.comment() + report_node.attributes["traceability_report"] = category + report_node.attributes["traceability_report_function"] = function_name + report_node.attributes["developer"] = ( + self.options["developer"] if category != "source" else None + ) + title_node[0] += report_node + return title_node + + def run(self): + category = self.arguments[0] + document = self.state.document + line_number = self.get_source_info()[1] + + if category not in ["input", "software", "architecture", "module", "source"]: + logger.error( + f"{document.settings.env.docname}.rst:{line_number}: category must be input, software, architecture, module or source" + ) + + if category != "source": + if "developer" not in self.options: + raise Exception( + f"{document.settings.env.docname}.rst:{line_number}: developer option not specified" + ) + else: + developer = self.options["developer"] + else: + developer = None + + if self.env.config.dox_trace_security_backward: + calc_table_security_cal = calc_table_security + else: + calc_table_security_cal = calc_table_cal + + # fmt: off + filter_heading = "**Filter:** |br| " + upstream_sufficiency = " |br| |br| **Upstream Sufficiency:** |br| " + downstream_sufficiency = " |br| |br| **Downstream Sufficiency:** |br| " + + srs_up = upstream_sufficiency + "Either an upstream reference exists or the element is tagged with *tool*." + swa_up = upstream_sufficiency + "Either an upstream reference exists to SRS/SWA or the element is tagged with *tool*." + smd_up = upstream_sufficiency + "Either an upstream reference exists to SWA/SMD or the element is tagged with *tool*." + + inp_down = downstream_sufficiency + "Either a downstream reference exists, the element is not *rejected* or the element is tagged with *covered*." + srs_down = downstream_sufficiency + "Either a downstream reference exists, the element is tagged with *covered* or a source is specified." + swa_down = downstream_sufficiency + "Either a downstream reference exists, the element is tagged with *covered* or a location/source is specified." + smd_down = downstream_sufficiency + "Either a downstream reference exists, the element is tagged with *covered* or a source is specified." + + node_list = [] + if category == "input": + node_list.extend(self.add_chapter(category, calc_table_input_developer, "Developer", filter_heading + "type = requirement")) + node_list.extend(self.add_chapter(category, calc_table_status, "Status", filter_heading + f"type = requirement |br| developer = {developer}")) + node_list.extend(self.add_chapter(category, calc_table_input_review_status, "Review Status", filter_heading + f"type = requirement |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_safety, "Functional Safety", filter_heading + f"type = requirement |br| developer = {developer} |br| status = valid |br| review_status = accepted")) + node_list.extend(self.add_chapter(category, calc_table_security_cal, "Cyber Security", filter_heading + f"type = requirement |br| developer = {developer} |br| status = valid |br| review_status = accepted")) + node_list.extend(self.add_chapter(category, calc_table_stream, "Downstream", filter_heading + f"type = requirement |br| developer = {developer} |br| status = valid |br| review_status = accepted" + inp_down)) + node_list.extend(self.add_chapter(category, calc_table_list, "List of Requirements", filter_heading + f"type = requirement |br| developer = {developer} |br| status = valid |br| review_status = accepted")) + elif category == "software": + node_list.extend(self.add_chapter(category, calc_table_status, "Status", filter_heading + f"type = requirement / srs |br| developer = {developer}")) + node_list.extend(self.add_chapter(category, calc_table_safety, "Functional Safety", filter_heading + f"type = requirement / srs |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_security_cal, "Cyber Security", filter_heading + f"type = requirement / srs |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_stream, "Upstream and Downstream", filter_heading + f"type = requirement / srs |br| developer = {developer} |br| status = valid" + srs_up + srs_down)) + node_list.extend(self.add_chapter(category, calc_table_list, "List of Requirements", filter_heading + f"type = requirement / srs |br| developer = {developer} |br| status = valid")) + elif category == "architecture": + node_list.extend(self.add_chapter(category, calc_table_status, "Status", filter_heading + f"type = spec / interface / mod |br| developer = {developer}")) + node_list.extend(self.add_chapter(category, calc_table_architecture_type, "Type", filter_heading + f"type = spec / interface / mod |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_safety, "Functional Safety", filter_heading + f"type = spec / interface / mod |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_security_cal, "Cyber Security", filter_heading + f"type = spec / interface / mod |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_stream, "Upstream and Downstream", filter_heading + f"type = spec / interface / mod |br| developer = {developer} |br| status = valid" + swa_up + swa_down)) + node_list.extend(self.add_chapter(category, calc_table_list, "List of Specifications", filter_heading + f"type = spec / interface / mod |br| developer = {developer} |br| status = valid")) + elif category == "module": + smd_interface = "/ interface " if self.env.config.dox_trace_allow_deprecated else "" + node_list.extend(self.add_chapter(category, calc_table_status, "Status", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer}")) + node_list.extend(self.add_chapter(category, calc_table_module_type, "Type", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_safety, "Functional Safety", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_security_cal, "Cyber Security", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer} |br| status = valid")) + node_list.extend(self.add_chapter(category, calc_table_stream, "Upstream and Downstream", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer} |br| status = valid" + smd_up + smd_down)) + node_list.extend(self.add_chapter(category, calc_table_list, "List of Specifications", filter_heading + f"type = spec {smd_interface}/ unit |br| developer = {developer} |br| status = valid")) + else: # source + node_list.extend(self.add_chapter(category, calc_source_list, None, None)) + # fmt: on + + return node_list + + +def get_modules(app, requested_category): + std = app.env.domaindata["std"] + + global dox_trace_modules + if "dox_trace_modules" not in globals(): + dox_trace_modules = {} + for ref_id, spec_id in sorted(std["spec_id"].items()): + options = std["spec_options"][ref_id] + if options["role"] in ["information"]: + continue + if "ignore_in_export" in options: + continue + + if "module_name" in std["spec_options"][ref_id]: + module_name = std["spec_options"][ref_id]["module_name"] + else: + m = re.match(r"^(([^_]+)_[^_]+)", spec_id) + module_name = m.group(1) + + category = options["category"] + if category not in dox_trace_modules: + dox_trace_modules[category] = {} + if module_name not in dox_trace_modules[category]: + dox_trace_modules[category][module_name] = [] + dox_trace_modules[category][module_name].append(ref_id) + + for category in dox_trace_modules.keys(): + mdict = dox_trace_modules[category] + dox_trace_modules[category] = {name: mdict[name] for name in sorted(mdict)} + + if requested_category in dox_trace_modules: + return dox_trace_modules[requested_category] + return None + + +def inject_report(app, doctree, fromdocname): + for node in doctree.traverse(nodes.comment): + if "traceability_report" in node.attributes: + category = node.attributes["traceability_report"] + function_name = node.attributes["traceability_report_function"] + developer = node.attributes["developer"] + + modules = get_modules(app, category) + if modules or category == "source": + table = function_name(app, category, fromdocname, modules, developer) + else: + table = None + if table: + node.replace_self(table) + else: + node.replace_self(nodes.paragraph("", "", nodes.emphasis("", "No data yet"))) diff --git a/dox_trace/dox_trace/report_architecture.py b/dox_trace/dox_trace/report_architecture.py new file mode 100644 index 0000000..2e86714 --- /dev/null +++ b/dox_trace/dox_trace/report_architecture.py @@ -0,0 +1,6 @@ +from .report_generic import calc_table_type + + +def calc_table_architecture_type(app, category, fromdocname, modules, developer): + types = ["spec", "interface", "mod"] + return calc_table_type(app, category, fromdocname, modules, developer, types) diff --git a/dox_trace/dox_trace/report_generic.py b/dox_trace/dox_trace/report_generic.py new file mode 100644 index 0000000..2701ba0 --- /dev/null +++ b/dox_trace/dox_trace/report_generic.py @@ -0,0 +1,362 @@ +import re +from .report_table import create_table, create_row_heading, create_row_values, create_row_refs +from .backward_refs import downstream_missing_trace, upstream_missing_trace +from .helper import cat_name2level + + +def create_developer_regex(developer): + return re.compile("\\A" + developer.replace(" ", "[ _]*") + "\\Z", re.IGNORECASE) + + +def init_row_values(value_names): + values = {} + for value_name in value_names: + values[value_name] = [] + return values + + +def sum_up_row_values(value_names, values_module, values_total): + for value_name in value_names: + values_total[value_name] += values_module[value_name] + + +def calc_table_status(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + table, thead, tbody = create_table(5) + value_names = ["all", "valid", "draft", "invalid"] + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + dev_split = options["developer_split"] + if not any(re.match(dev_regex, dev) for dev in dev_split): + continue + if options["status"] in value_names: + spec_id = std["spec_id"][ref_id] + values_module[options["status"]].append(spec_id) + if not all(len(value) == 0 for value in values_module.values()): + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=True, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + if len(rows) > 0: + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=True + ) + tbody += rows + return table + + return None + + +def get_dev_spec_id(std, options, dev_regex, ref_id): + dev_split = options["developer_split"] + if not any(re.match(dev_regex, dev) for dev in dev_split): + return None + if options["status"] != "valid": + return None + if options["review_status"] not in ["accepted"]: + return None + return std["spec_id"][ref_id] + + +def calc_table_type(app, category, fromdocname, modules, developer, types): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + table, thead, tbody = create_table(2 + len(types)) + value_names = ["all"] + types + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + spec_id = get_dev_spec_id(std, options, dev_regex, ref_id) + if not spec_id: + continue + values_module[options["role"]].append(spec_id) + if not all(len(value) == 0 for value in values_module.values()): + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=True, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + if len(rows) > 0: + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=True + ) + tbody += rows + return table + + return None + + +def calc_table_safety_cal(app, category, fromdocname, modules, developer, attr_name): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + data = {} + value_names = [] + + for modules_name, ref_ids in modules.items(): + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + spec_id = get_dev_spec_id(std, options, dev_regex, ref_id) + if not spec_id: + continue + + if modules_name not in data: + data[modules_name] = {} + if options[attr_name] not in data[modules_name]: + data[modules_name][options[attr_name]] = [] + if options[attr_name] not in value_names: + value_names.append(options[attr_name]) + data[modules_name][options[attr_name]].append(spec_id) + + if len(data) > 0: + if "not_set" in value_names: + value_names.remove("not_set") + value_names.sort() + value_names.append("not_set") + value_names.insert(0, "all") + + values_total = init_row_values(value_names) + rows = [] + for modules_name, values_module_short in data.items(): + values_module = init_row_values(value_names) + for value in values_module_short: + values_module[value] = values_module_short[value] + sum_up_row_values(value_names, values_module, values_total) + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=True, + ) + ) + + table, thead, tbody = create_table(1 + len(value_names)) + thead += create_row_heading(value_names) + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=True + ) + tbody += rows + return table + + return None + + +def calc_table_safety(app, category, fromdocname, modules, developer): + return calc_table_safety_cal(app, category, fromdocname, modules, developer, "asil") + + +def calc_table_cal(app, category, fromdocname, modules, developer): + return calc_table_safety_cal(app, category, fromdocname, modules, developer, "cal") + + +def calc_table_security(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + table, thead, tbody = create_table(5) + value_names = ["all", "yes", "no", "not_set"] + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + spec_id = get_dev_spec_id(std, options, dev_regex, ref_id) + if not spec_id: + continue + + if options["security"] in ["yes", "no", "not_set"]: + values_module[options["security"]].append(spec_id) + else: # pragma: no cover (robustness) + pass + if not all(len(value) == 0 for value in values_module.values()): + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=True, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + if len(rows) > 0: + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=True + ) + tbody += rows + return table + + return None + + +def calc_table_stream(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + if category == "input": + value_names = ["all", "Downstream Sufficient", "Downstream Missing"] + else: + value_names = [ + "all", + "Upstream Sufficient", + "Upstream Missing", + "Downstream Sufficient", + "Downstream Missing", + ] + + table, thead, tbody = create_table(len(value_names) + 1) + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + spec_id = get_dev_spec_id(std, options, dev_regex, ref_id) + if not spec_id: + continue + values_module["all"].append(spec_id) + + if ( + ("downstream_refs" in options and options["downstream_refs"]) + or ("location" in options and options["location"] != "") + or ("sources" in options and options["sources"] != []) + or (not downstream_missing_trace(options)) + ): + values_module["Downstream Sufficient"].append(spec_id) + else: + values_module["Downstream Missing"].append(spec_id) + + if category != "input": + sufficient = not upstream_missing_trace(options) + if not sufficient and "upstream_refs" in options and options["upstream_refs"]: + above = 2 if category == "software" else 1 + current_level = cat_name2level[category] + sufficient = any( + cat_name2level[std["spec_options"][r]["category"]] <= current_level + above + for r in options["upstream_refs"] + ) + if sufficient: + values_module["Upstream Sufficient"].append(spec_id) + else: + values_module["Upstream Missing"].append(spec_id) + + if not all(len(value) == 0 for value in values_module.values()): + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=False, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + if len(rows) > 0: + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=False + ) + tbody += rows + return table + + return None + + +def calc_table_list(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = create_developer_regex(developer) + + if category == "input": + value_names = ["ID", "Downstream"] + else: + value_names = ["ID", "Upstream", "Downstream"] + + table, thead, tbody = create_table(len(value_names) + 1, small=True) + thead += create_row_heading(value_names) + + rows = [] + for modules_name, ref_ids in modules.items(): + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + if not get_dev_spec_id(std, options, dev_regex, ref_id): + continue + + location = sources = None + downstream_refs = sorted(options["downstream_refs"]) + if "location" in options: + location = options["location"] + elif "sources" in options: + sources = sorted(options["sources"]) + if not downstream_refs and not location and not sources: + downstream_refs = "[missing]" if downstream_missing_trace(options) else "-" + + if category != "input": + upstream_refs = sorted(options["upstream_refs"]) + if len(upstream_refs) == 0: + upstream_refs = "[missing]" if upstream_missing_trace(options) else "-" + else: + upstream_refs = None + + rows.append( + create_row_refs( + app, + fromdocname, + modules_name, + ref_id, + downstream_refs, + location, + sources, + upstream_refs, + ) + ) + + if len(rows) > 0: + tbody += rows + return table + + return None diff --git a/dox_trace/dox_trace/report_input.py b/dox_trace/dox_trace/report_input.py new file mode 100644 index 0000000..e96fa10 --- /dev/null +++ b/dox_trace/dox_trace/report_input.py @@ -0,0 +1,105 @@ +import re +from .report_generic import ( + create_table, + create_row_heading, + create_row_values, + init_row_values, + sum_up_row_values, +) + + +def calc_table_input_developer(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = re.compile("\\A" + developer.replace(" ", "[ _]*") + "\\Z", re.IGNORECASE) + + table, thead, tbody = create_table(5) + value_names = ["all", developer, "other", "not set"] + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + spec_id = std["spec_id"][ref_id] + if "developer" not in options or options["developer"] in ["", "[missing]"]: + values_module["not set"].append(spec_id) + else: + dev_split = options["developer_split"] + if any(re.match(dev_regex, dev) for dev in dev_split): + values_module[developer].append(spec_id) + if len(dev_split) > 1: + # more than just one developer + values_module["other"].append(spec_id) + else: + values_module["other"].append(spec_id) + values_module["all"].append(spec_id) + + # no "continue" above, at least one value is > 0 + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=False, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + # no "continue" above, at least one row exists + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=False + ) + tbody += rows + return table + + +def calc_table_input_review_status(app, category, fromdocname, modules, developer): + std = app.env.domaindata["std"] + dev_regex = re.compile("\\A" + developer.replace(" ", "[ _]*") + "\\Z", re.IGNORECASE) + + table, thead, tbody = create_table(7) + value_names = ["all", "accepted", "unclear", "rejected", "not_relevant", "not_reviewed"] + thead += create_row_heading(value_names) + + values_total = init_row_values(value_names) + rows = [] + for modules_name, ref_ids in modules.items(): + values_module = init_row_values(value_names) + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + if options["status"] != "valid": + continue + dev_split = options["developer_split"] + if not any(re.match(dev_regex, dev) for dev in dev_split): + continue + if options["review_status"] in value_names: + spec_id = std["spec_id"][ref_id] + values_module[options["review_status"]].append(spec_id) + + if not all(len(value) == 0 for value in values_module.values()): + rows.append( + create_row_values( + app, + fromdocname, + category, + value_names, + modules_name, + values_module.values(), + calc_sum=True, + ) + ) + sum_up_row_values(value_names, values_module, values_total) + + if len(rows) > 0: + tbody += create_row_values( + app, fromdocname, category, value_names, "TOTAL", values_total.values(), calc_sum=True + ) + tbody += rows + return table + + return None diff --git a/dox_trace/dox_trace/report_module.py b/dox_trace/dox_trace/report_module.py new file mode 100644 index 0000000..46caa51 --- /dev/null +++ b/dox_trace/dox_trace/report_module.py @@ -0,0 +1,9 @@ +from .report_generic import calc_table_type + + +def calc_table_module_type(app, category, fromdocname, modules, developer): + if app.env.config.dox_trace_allow_deprecated: + types = ["spec", "interface", "unit"] + else: + types = ["spec", "unit"] + return calc_table_type(app, category, fromdocname, modules, developer, types) diff --git a/dox_trace/dox_trace/report_source.py b/dox_trace/dox_trace/report_source.py new file mode 100644 index 0000000..93397e6 --- /dev/null +++ b/dox_trace/dox_trace/report_source.py @@ -0,0 +1,48 @@ +from .helper import create_ref_node + +from docutils import nodes +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def calc_source_backward(std): + sources = {} + for docname, ref_ids in std["local_ordered"].items(): + for ref_id in ref_ids: + options = std["spec_options"][ref_id] + if "sources_base" in options: + for f in options["sources_base"]: + if f not in sources: + sources[f] = [] + sources[f].append(ref_id) + return sources + + +def calc_source_list(app, _category, fromdocname, _modules, _developer): + std = app.env.domaindata["std"] + sources = calc_source_backward(std) + + if len(sources) == 0: + return None + + node_list = nodes.bullet_list() + for source in sorted(sources.keys()): + ref_ids = sources[source] + ref_ids.sort() + rs = [] + for ref_id in ref_ids: + ref_node = create_ref_node(app, ref_id, fromdocname) + if len(rs) > 0: + rs.append(nodes.Text(", ")) + rs.append(ref_node) + node_para_source = nodes.paragraph("", "", nodes.literal("", source)) + node_para_refs = nodes.paragraph() + node_para_refs += rs + + node_item = nodes.list_item() + node_list.append(node_item) + node_item.append(node_para_source) + node_item.append(node_para_refs) + + return node_list diff --git a/dox_trace/dox_trace/report_table.py b/dox_trace/dox_trace/report_table.py new file mode 100644 index 0000000..c76f1c4 --- /dev/null +++ b/dox_trace/dox_trace/report_table.py @@ -0,0 +1,174 @@ +from docutils import nodes +import itertools +import os +import re + +dox_trace_row_counter = 0 + + +def create_table(num_rows, small=False): + table = nodes.table() + if small: + table["classes"] += ["dox-trace-small-font-table"] + tg = nodes.tgroup(cols=num_rows) + for _ in range(num_rows): + tg += nodes.colspec() + table += tg + thead = nodes.thead() + tg += thead + tbody = nodes.tbody() + tg += tbody + return table, thead, tbody + + +def word_break(word): + if len(word) <= 30: + return word + word = word.replace("_", "_").replace("/", "/") + str_split = word.split("") + if any(len(s) > 30 for s in str_split): + long_str = [] + for s in str_split: + if len(s) > 30: + long_str.append(re.sub(r"(.)([A-Z])", r"\1\2", s)) + else: + long_str.append(s) + return "".join(long_str) + return word + + +def create_row_values(app, fromdocname, category, headings, module_name, values, calc_sum): + std = app.env.domaindata["std"] + if module_name == "TOTAL": + for v in values: + v.sort() + global dox_trace_row_counter + dox_trace_row_counter += 1 + row_id = str(dox_trace_row_counter) + row = nodes.row() + + mod_node = nodes.raw("", word_break(module_name), format="html") + row += nodes.entry("", mod_node) + for i, (h, v) in enumerate(zip(headings, values)): + if calc_sum and i == 0: + v = sorted(list(itertools.chain.from_iterable(values))) + if len(v) > 0: + html = [] + postfix = category + "_" + row_id + "_" + h + "_" + module_name + html.append(f'{len(v)}\n') + html.append(f'
\n') + html.append(f'
\n') + html.append( + f'×\n' + ) + refs = [] + for spec_id in v: + ref_id = spec_id.lower() + if ref_id in std["anonlabels"]: + source_docname, r = std["anonlabels"][ref_id] + refuri = app.builder.get_relative_uri(fromdocname, source_docname) + "#" + r + refs.append(f'{spec_id}') + else: # pragma: no cover (robustness) + pass + joined_refs = "
\n".join(refs) + html.append(f"

\n{joined_refs}

\n") + html.append(f"
\n") + row += nodes.entry("", nodes.raw("", "".join(html), format="html")) + else: + row += nodes.entry("", nodes.raw("", "0", format="html")) + return row + + +def create_row_heading(entries): + row = nodes.row() + cell = nodes.entry() + cell.set_class("dox-trace-strikethrough-cell") + row += cell + for e in entries: + row += nodes.entry("", nodes.paragraph(text=e)) + return row + + +def create_ref_node(app, fromdocname, ref_id): + std = app.env.domaindata["std"] + + inline = nodes.inline() + if ref_id in std["spec_id"] and ref_id in std["anonlabels"]: + source_docname, r = std["anonlabels"][ref_id] + refuri = app.builder.get_relative_uri(fromdocname, source_docname) + "#" + r + ref_node = nodes.reference( + "", + "", + internal=True, + refdocname=source_docname, + refuri=refuri, + refid=r, + ) + spec_id = std["spec_id"][ref_id] + spec_node = nodes.raw("", word_break(spec_id), format="html") + ref_node += spec_node + inline += ref_node + else: + spec_node = nodes.raw("", word_break(ref_id), format="html") + inline.set_class("dox-trace-red") + inline += spec_node + return inline + + +def create_location_node(app, fromdocname, location): + inline = nodes.inline() + file = os.path.join(location, "doc/index").replace("\\", "/") + loc_node = nodes.raw("", word_break(location), format="html") + if os.path.isfile(os.path.join(app.srcdir, file + ".rst")): + refuri = app.builder.get_relative_uri(fromdocname, file) + ref_node = nodes.reference( + "", + "", + internal=True, + refdocname=file, + refuri=refuri, + refid=None, + ) + ref_node += loc_node + inline += ref_node + else: + inline.set_class("dox-trace-red") + inline += loc_node + return inline + + +def create_refs_entry(app, fromdocname, refs, location=None, sources=None): + entry = nodes.entry("") + if refs: + for idx, ref_id in enumerate(refs): + ref_node = create_ref_node(app, fromdocname, ref_id) + if idx > 0: + entry += nodes.raw("", ",
", format="html") + entry += ref_node + if location: + entry += create_location_node(app, fromdocname, location) + if sources: + if refs and len(refs) > 0: + entry += nodes.raw("", ",
", format="html") + sources_with_word_break = [word_break(s) for s in sources] + entry += nodes.raw("", ",
".join(sources_with_word_break), format="html") + return entry + + +def create_row_refs(app, fromdocname, module_name, ref_id, downstream, location, sources, upstream): + row = nodes.row() + row += nodes.entry("", nodes.raw("", word_break(module_name), format="html")) + row += nodes.entry("", create_ref_node(app, fromdocname, ref_id)) + + if not upstream is None: + if isinstance(upstream, str): + row += nodes.entry("", nodes.raw("", word_break(upstream), format="html")) + else: + row += create_refs_entry(app, fromdocname, upstream) + + if isinstance(downstream, str) and not location and not sources: + row += nodes.entry("", nodes.raw("", word_break(downstream), format="html")) + else: + row += create_refs_entry(app, fromdocname, downstream, location, sources) + + return row diff --git a/dox_trace/dox_trace/roles.py b/dox_trace/dox_trace/roles.py new file mode 100644 index 0000000..40e272d --- /dev/null +++ b/dox_trace/dox_trace/roles.py @@ -0,0 +1,25 @@ +from docutils import nodes + +from .env import add_node_to_env + + +def spec_role(role, rawtext, text, lineno, inliner, _options={}, _content=[]): + env = inliner.document.settings.env + + spec_id = text + ref_id = spec_id.lower() + role = role.replace("_generated", "") + + node = nodes.literal(rawtext, "[" + role + "] ") + node.set_class("highlight") + node.set_class("highlight-%s" % role) + node.line = lineno + + self_ref = nodes.reference(spec_id, spec_id, refdocname=env.docname, refid=ref_id) + node.append(self_ref) + + target_node = nodes.target("", "", ids=[ref_id]) + + add_node_to_env(inliner.document, spec_id, node) + + return [target_node, node], [] diff --git a/dox_trace/dox_trace/undefined_refs.py b/dox_trace/dox_trace/undefined_refs.py new file mode 100644 index 0000000..418b476 --- /dev/null +++ b/dox_trace/dox_trace/undefined_refs.py @@ -0,0 +1,65 @@ +from sphinx.util import logging +from docutils import nodes +from sphinx.util.docutils import SphinxDirective +from .helper import create_ref_node + +logger = logging.getLogger(__name__) + + +def calc_unresolved_references(_app, env): + std = env.domaindata["std"] + spec_options = std["spec_options"] + + undefined_map = std["undefined_map"] = {} + + for ref_id, options in spec_options.items(): + resolved_refs = [] + for target_spec_id in spec_options[ref_id]["refs"]: + target_spec_id_lower = target_spec_id.lower() + if ( + target_spec_id_lower not in spec_options + and target_spec_id_lower not in std["labels"] + ): + if ref_id not in undefined_map: + undefined_map[ref_id] = [] + undefined_map[ref_id].append(target_spec_id) + else: + # this adds invalid refs again which are reported in check_invalid_refs + resolved_refs.append(target_spec_id) + if len(resolved_refs) == 0: + spec_options[ref_id]["refs"] = [] + else: + spec_options[ref_id]["refs"] = resolved_refs + + +def inject_undefined_references(app, doctree, fromdocname): + std = app.env.domaindata["std"] + undefined_map = std["undefined_map"] + + for node in doctree.traverse(nodes.comment): + if "undefined_refs" in node.attributes and node.attributes["undefined_refs"]: + if len(undefined_map) == 0: + node.replace_self(nodes.emphasis("", "No undefined references found.")) + continue + + node_list = nodes.bullet_list() + refs_ids = undefined_map.keys() + for ref_id in sorted(refs_ids): + ref_node = create_ref_node(app, ref_id, fromdocname) + + node_para = nodes.paragraph("", "") + node_para.append(ref_node) + node_para.append(nodes.Text(": " + ", ".join(undefined_map[ref_id]))) + + node_item = nodes.list_item() + node_list.append(node_item) + node_item.append(node_para) + + node.replace_self(node_list) + + +class UndefinedRefsDirective(SphinxDirective): + def run(self): + n = nodes.comment() + n.attributes["undefined_refs"] = True + return [n] diff --git a/dox_trace/dox_trace/version.py b/dox_trace/dox_trace/version.py new file mode 100644 index 0000000..528787c --- /dev/null +++ b/dox_trace/dox_trace/version.py @@ -0,0 +1 @@ +__version__ = "3.0.0" diff --git a/dox_trace/dox_trace/yaml.py b/dox_trace/dox_trace/yaml.py new file mode 100644 index 0000000..a06f70f --- /dev/null +++ b/dox_trace/dox_trace/yaml.py @@ -0,0 +1,26 @@ +# prevents "no", "yes" etc. to be interpreted as bool + +from yaml.constructor import SafeConstructor +from yaml.reader import * +from yaml.scanner import * +from yaml.parser import * +from yaml.composer import * +from yaml.resolver import * + + +class SafeCstrWithoutBoolean(SafeConstructor): + def add_bool(self, node): + return self.construct_scalar(node) + + +SafeCstrWithoutBoolean.add_constructor("tag:yaml.org,2002:bool", SafeCstrWithoutBoolean.add_bool) + + +class SafeLoaderWithoutBoolean(Reader, Scanner, Parser, Composer, SafeCstrWithoutBoolean, Resolver): + def __init__(self, stream): + Reader.__init__(self, stream) + Scanner.__init__(self) + Parser.__init__(self) + Composer.__init__(self) + SafeCstrWithoutBoolean.__init__(self) + Resolver.__init__(self) diff --git a/dox_trace/pyproject.toml b/dox_trace/pyproject.toml new file mode 100644 index 0000000..3ff8a5c --- /dev/null +++ b/dox_trace/pyproject.toml @@ -0,0 +1,29 @@ +[build-system] +requires = ["setuptools >= 70.0.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "dox_trace" +dynamic = ["version"] +authors = [ + { name="Accenture" }, +] +description = "Adds specification directives to achieve traceability in Sphinx documentations." +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", +] +license = {text = "Apache-2.0"} + +[project.urls] +Homepage = "https://github.com/esrlabs/dox" +Issues = "https://github.com/esrlabs/dox/issues" + +[tool.setuptools] +license-files = ["LICENSE"] +dynamic.version = {attr = "dox_trace.version.__version__"} +package-data."*" = ['_static/*', "LICENSE"] +packages.find.exclude = ["spec", "spec.*"] diff --git a/dox_trace/req/config.dim b/dox_trace/req/config.dim new file mode 100644 index 0000000..803ccc4 --- /dev/null +++ b/dox_trace/req/config.dim @@ -0,0 +1,7 @@ +Config: + - files: dox_trace.dim + originator: Accenture + disable_naming_convention_check: yes + category: software + +Properties: properties.yaml diff --git a/dox_trace/req/dox_trace.dim b/dox_trace/req/dox_trace.dim new file mode 100644 index 0000000..1649aef --- /dev/null +++ b/dox_trace/req/dox_trace.dim @@ -0,0 +1,1498 @@ +document: dox_trace + +DoxTrace_Build_Heading: h1 Execution + +DoxTrace_Build_Single: + text: dox_trace shall support single-threaded builds. + tags: tool, covered, tested + status: valid + sources: dox_trace/main.py + +DoxTrace_Build_Multi: + text: dox_trace shall support multi-threaded builds. + tags: tool, covered, tested + status: valid + sources: dox_trace/main.py + +DoxTrace_Syntax_Heading: h1 Syntax + +DoxTrace_Syntax_Directives: h2 Directives + +DoxTrace_Syntax_Types: + text: | + dox_trace shall provide the following directives: + - spec + - unit + - interface + - requirement + - information + - mod + Note: they are called generically "specifications" in this document regardless of the type. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/main.py + +DoxTrace_Syntax_Structure: + text: | + dox_trace shall use the following syntax for the directives: + .. :: + :: + :: + + + The ID is mandatory, the attributes are optional. Also the content can be omitted. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/main.py + +DoxTrace_Syntax_General: h2 General Handling + +DoxTrace_Syntax_Anchor: + text: The specifications shall be referencable by their ID like any other regular anchor. + tags: tool, covered, tested + status: valid + sources: dox_trace/roles.py + +DoxTrace_Syntax_Stripped: + text: All values shall be stripped (removing leading and trailing whitespaces). + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Empty: + text: Attributes with empty values, "" or '' shall be treated as empty strings. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Check: + type: information + text: dox_trace does not check the general syntax of RST files. If e.g. a directive does not match + Sphinx syntax, Sphinx aborts the build and returns with an exit code != 0. dox_trace does + not check if the values are correct, e.g. if an invalid tag is used. This is done by the Dim + tool after an export. + status: valid + +DoxTrace_Syntax_Multi: + text: | + The attributes "tags", "verification_methods", "sources", and "refs" shall be treated as comma separated lists. + When loading the values the following is done to harmonize further processing of the data like displaying in HTML: + - split by "," + - strip + - remove duplicated values + - remove empty values, "" and '' + - join again with ", " as separator. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_FreeText: + text: All other attributes and the content shall be treated as free text supporting any Sphinx + syntax like images, tables, etc. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/helper.py + +DoxTrace_Syntax_Attributes: h2 Attributes + +DoxTrace_Syntax_Newlines: + text: Text attributes shall preserve newlines except a line ends with a backslash. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Status: + text: | + The attribute "status" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + - mod + The default value shall be "draft". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_ReviewStatus: + text: | + The attribute "review_status" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + - mod + The default value shall be "not_reviewed" for input requirements, otherwise "accepted". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Asil: + text: | + The attribute "asil" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + - mod + The default value shall be "not_set". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Cal: + text: | + The attribute "cal" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + - mod + The default value shall be "not_set". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Security: + text: | + The attribute "security" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + - mod + The default value shall be "not_set". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_SecurityToCal: + text: | + If + - the config parameter "dox_trace_security_backward" is not set to "True" AND + - "cal" is not set AND + - "security" is set", + the attribute "cal" shall be derived from "security" with the following mapping: + - "yes" -> "CAL_4" + - "no" -> "QM" + - "not_set" -> "not_set" + Otherwise it shall be ignored. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_CalToSecurity: + text: | + If + - the config parameter "dox_trace_security_backward" is set to "True" AND + - "cal" is set AND + - "security" is not set", + the attribute "security" shall be derived from "cal" with the following mapping: + - "CAL_1" -> "yes" + - "CAL_2" -> "yes" + - "CAL_3" -> "yes" + - "CAL_4" -> "yes" + - "QM" -> "no" + - "not_set" -> "not_set" + Otherwise it shall be ignored. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Reuse: + text: | + The attribute "reuse" shall be available for: + - mod + The default value shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Usage: + text: | + The attribute "usage" shall be available for: + - mod + The default value shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Developer: + text: | + The attribute "developer" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - mod + The default value shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Tester: + text: | + The attribute "tester" shall be available for: + - srs + - spec + - unit + - interface + - requirement + Ignore: + - For interface with ID starting with "SMD_" this attribute shall be ignored. + Default: + - The default value shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_TestSetups: + text: | + The attribute "test_setups" shall be available for: + - srs + - spec + - unit + - interface + - requirement + Ignore: + - For interface with ID starting with "SMD_" this attribute shall be ignored. + Default: + - For srs, spec and unit the default value shall be "off_target" if the ID starts with "SMD_", otherwise "on_target". + - Otherwise "none". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_VerificationMethods: + text: | + The attribute "verification_methods" shall be available for: + - srs + - spec + - unit + - interface + - requirement + Ignore: + - For interface with ID starting with "SMD_" this attribute shall be ignored. + Default: + - For srs, spec and unit the default value shall be "off_target" if the ID starts with "SMD_", otherwise "on_target". + - Otherwise "none". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_TestSetupsToVerificationMethods: + text: | + If + - the config parameter "dox_trace_test_setups_backward" is not set to "True" AND + - "verification_methods" is not set AND + - "test_setups" is set", + the attribute "verification_methods" shall be set to the value from "test_setups". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_VerificationMethodsToTestSetups: + text: | + If + - the config parameter "dox_trace_test_setups_backward" is set to "True" AND + - "test_setups" is not set AND + - "verification_methods" is set", + the attribute "test_setups" shall be set to the value from "verification_methods". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Tags: + text: | + The attribute "tags" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + The default shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_VerificationCriteria: + text: | + The attribute "verification_criteria" shall be available for: + - srs + - spec + - unit + - interface + - requirement + For interface with ID starting with "SMD_" this attribute shall be ignored. + Default shall be empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Comment: + text: | + The attribute "comment" shall be available for: + - requirement + - information + Default shall be empty. + It shall be ignored if category is not "input". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Miscellaneous: + text: | + The attribute "miscellaneous" shall be available for: + - requirement + - information + Default shall be empty. + It shall be ignored if category is not "input". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Feature: + text: | + The attribute "feature" shall be available for: + - requirement + Default shall be empty. + It shall be ignored if category is not "input". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_ChangeRequest: + text: | + The attribute "change_request" shall be available for: + - requirement + Default shall be empty. + It shall be ignored if category is not "input". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Sources: + text: | + The attribute "sources" shall be available for: + - srs + - spec + - unit + - interface + - requirement + The default shall be empty. + It shall be used to reference source code files. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Refs: + text: | + The attribute "refs" shall be available for: + - srs + - spec + - unit + - interface + - requirement + - information + The default shall be empty. + It shall be used to reference other specifications. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Syntax_Location: + text: | + The attribute "location" shall be available for: + - mod + The default shall be empty. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_Category: + text: | + The attribute "category" shall be available for: + - requirement + - information + The default shall be "input". + Note: this attribute is used by the Dim tool, it's not intended to be used manually. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Syntax_IgnoreInExport: + text: | + The attribute "ignore_in_export" shall be available for all types. + It shall have no value. It's either set or not set. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Checks_Heading: h1 Checks + +DoxTrace_Checks_Cyclic: + text: | + dox_trace shall check for cyclic references of specifications. + If a cyclic reference is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/checks.py + +DoxTrace_Checks_InvalidRefs: + text: | + dox_trace shall check for references in "refs" attributes which do not point to another specification but to other anchors. + If such reference is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/checks.py + +DoxTrace_Checks_Case: + text: | + Sphinx is internally converting anchors and references to lower case, which means references with incorrect case are also working. + To avoid confusion and problems in further processing of the specifications, Sphinx shall check for references in "refs" attributes which have incorrect case. + If such reference is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/checks.py + +DoxTrace_Checks_Sources: + text: | + dox_trace shall check for source files specified in "sources" attributes in "srs", "spec", "unit" and "interface" which do not exist. + If such a source file is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + dox_trace shall not check "sources" in "requirements", because this is already done in Dim and the source files might not be exported by Dim. + dox_trace shall accept paths relative to the following two locations: + - the folder which contains the RST-file OR + - the parent folder of the closest "doc"-folder: /doc/**/. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Checks_Comments: + text: | + The syntactical difference between a directive and a comment is very small in Sphinx. + To avoid unintended comments when writing specifications, Sphinx shall check if the first line of a comment contains only "srs", "spec", "mod", "interface" or "unit" beside other non-word characters. + If such comment is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/checks.py + +DoxTrace_Checks_Unique: + text: | + dox_trace shall check if an ID is used twice. + If such an ID is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/env.py + +DoxTrace_Checks_Newline: + text: | + dox_trace shall check if an ID contains a newline. + If such an ID is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Checks_Naming: + text: | + dox_trace shall check if an IDs does not follow the naming scheme __. + - must not be empty and not contain additional underscores + - depends on the type: + - srs: SRS + - mod, interface: SWA + - spec: SWA or SMD + - unit: SMD + If such an ID is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Checks_NamingDeprecated: + text: | + dox_trace shall provide a Sphinx configuration variable "dox_trace_allow_deprecated". + If set to True, dox_trace shall use a less strict naming scheme for mod, spec, unit and interface: + - _ + - must not be empty and not start with an underscore + - the can be SWA or SMD + If a violation is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Checks_SphinxVersion: + text: | + dox_trace shall check if Sphinx 6.2+ is used. This is needed due to an important bugfix for nested parsing. + If an older Sphinx version is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/main.py + +DoxTrace_Checks_PythonVersion: + text: | + dox_trace shall check if Python 3.8+ is used, which is needed by Sphinx 6.2. + If an older Python version is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/main.py + +DoxTrace_HTML_Heading: h1 HTML + +DoxTrace_HTML_General: h2 General + +DoxTrace_HTML_Incremental: + text: dox_trace shall support the HTML-transformer of Sphinx including incremental builds. Only + the mandatory pages shall be rebuilt (e.g. when adding a new specification). + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/roles.py + +DoxTrace_HTML_Version: + text: If the version of this extension has changed compared to the previous build, all files shall + be rebuilt to avoid inconsistent data. + tags: tool, covered, tested + status: valid + sources: dox_trace/main.py + +DoxTrace_HTML_Table: + text: Every specification shall be rendered as table with a black border containing all attributes + which belong to this specification. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/_static/dox_trace.css + +DoxTrace_HTML_Background: + text: The table background shall be light-grey except for the actual content of the specification + which shall be white. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Attributes: + text: | + Regular attribute names shall be black bold. + Regular attribute values shall be black normal. + Upstream and derived attribute names shall be grey bold. + Upstream and derived attribute values shall be grey normal. + Note: The content of some attributes can overwrite this behaviour, see DoxTrace_Syntax_FreeText. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Strike: + text: | + The complete specification shall be greyed out and struck through if: + - "status" is "invalid" OR + - "review_status" is "rejected" or "not_relevant" + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/_static/dox_trace.css + +DoxTrace_HTML_Content: + text: If the content is empty, it shall be displayed as "[missing]". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_RegularAttributes: h2 Regular Attributes + +DoxTrace_HTML_TypeID: + text: | + The specification type and ID shall be rendered in the following form: "[] ", e.g. "[unit] SMD_MyModule_Abc" + - The complete string shall have a white background. + - The types "requirement", "spec", "unit" and "interface" shall be rendered in black bold font. + - The type "information" shall be rendered in light-grey bold font. + - The ID shall be rendered as link to itself (so the anchor can be simply copied from the address bar of the browser). + tags: tool, covered, tested + status: valid + sources: > + dox_trace/roles.py, + dox_trace/_static/dox_trace.css + +DoxTrace_HTML_ReviewStatus: + text: | + The "review_status" attribute shall only be shown if: + - it is not "accepted" OR + - the specification is an input requirement. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Reuse: + text: The "reuse" attribute shall be displayed as "-" if it is empty. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Usage: + text: The "usage" attribute shall be displayed as "-" if it is empty. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Developer: + text: | + If the "developer" attribute is empty it shall be displayed as: + - "[missing]" if the specification is not struck through + - "-" otherwise + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Tester: + text: | + If the "tester" attribute is empty it shall be displayed as: + - "[missing]" + - if the specification is not struck through AND + - "verification_methods" is not "none" + - "-" otherwise + "tester" shall not be displayed for interfaces with ID starting with "SMD_". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_TestSetups: + text: | + If the config parameter "dox_trace_test_setups_backward" is not set to "True", the "test_setups" attribute shall not be displayed. + If the "test_setups" attribute is empty it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_VerificationMethods: + text: | + If the config parameter "dox_trace_test_setups_backward" is set to "True", the "verification_methods" attribute shall not be displayed. + If the "verification_methods" attribute is empty it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Cal: + text: If the config parameter "dox_trace_security_backward" is set to "True", the "cal" attribute + shall not be displayed. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Security: + text: If the config parameter "dox_trace_security_backward" is not set to "True", the "security" + attribute shall not be displayed. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Tags: + text: If the "tags" attribute is empty, it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_VerificationCriteria: + text: | + If the "verification_criteria" attribute is empty, it shall be displayed as: + - "[missing]" for software requirements without "tool" in "tags" which are not struck through + - "-" otherwise + "verification_criteria" shall not be displayed for interfaces with ID starting with "SMD_". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Comment: + text: If the "comment" attribute is empty, it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Miscellaneous: + text: If the "miscellaneous" attribute is empty, it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Feature: + text: If the "feature" attribute is empty, it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_ChangeRequest: + text: If the "change_request" attribute is empty, it shall be displayed as "-". + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Sources: + text: | + The attribute "sources" shall only be shown for: + - "unit" + - "interface" if the ID starts with SMD_ + - value is not empty. + If the value is empty (for "unit" and SMD "interfaces"), it shall be displayed as: + - "[missing]" if "covered" is not in "tags" and the specification is not struck through + - "-" otherwise + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_Location: + text: | + If the attribute "location" is empty, it shall be displayed as: + - "[missing]" if the specification is not struck through + - "-" otherwise + If the attribute "location" is not empty, it shall be displayed as + - link to the corresponding module if location + "doc/index.rst" exists + - as is if the specification is struck through + - as is in red otherwise + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_CalculatedAttributes: h2 Additional Calculated Attributes + +DoxTrace_HTML_UpstreamRefs: + text: | + dox_trace shall derive from "refs" attribute backward references. + dox_trace shall, based on these (backward) references, compile a list of upstream and downstream references per specification. + Upstream references are (backward) references to a higher category and backward references to the same category. + Downstream references are (backward) references to a lower category and explicit references to the same category. + Categories are top-down: input, system, software, architecture and module. + dox_trace shall show the upstream references in an "Upstream Reference" field as comma separated, clickable links to the referenced specifications. + If no upstream references are available, the field shall shall be displayed as: + - "[missing]" if + a) "tool" is not in "tags" AND + b) the specification is not struck through AND + c) the type is not "information" AND + d) the category is not "input" + - "-" otherwise + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_DownstreamRefs: + text: | + dox_trace shall show the downstream references in an "Downstream Reference" field as comma separated, clickable links to the referenced specifications. + If no downstream references are available, the field shall shall be displayed as: + - "[missing]" if + a) "covered" is not in "tags" AND + b) the specification is not struck through AND + c) the type is not "information" or "unit" AND + d) the specification is not of type "interface" in category "module" + - "-" otherwise + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_HTML_RefsRed: + text: | + dox_trace shall provide a Sphinx configuration variable "dox_trace_allow_undefined_refs". + If explicitly set to True, dox_trace shall suppress warnings about undefined references in the "refs" attribute. + Instead, these IDs shall be displayed in red in "Downstream References". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/unresolved_refs.py + +DoxTrace_HTML_RefsExport: + text: dox_trace shall not export unresolved references. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/unresolved_refs.py + +DoxTrace_HTML_UpstreamAsil: + text: | + An "Upstream Asil" attribute shall be displayed if the category is not "input". + It shall be a comma separated list of all "asil" attributes from direct upstream references, but not from indirect upstream references. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_UpstreamCal: + text: | + An "Upstream Cal" attribute shall be displayed if the category is not "input". + It shall be a comma separated list of all "cal" attributes from direct upstream references, but not from indirect upstream references. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_UpstreamSecurity: + text: | + If + - the config parameter "dox_trace_security_backward" is set to "True" AND + - the category is not "input" + an "Upstream Security" attribute shall be displayed instead of "Upstream Cal". + It shall be a comma separated list of all "security" attributes from direct upstream references, but not from indirect upstream references. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_UpstreamTags: + text: | + An "Upstream Tags" attribute shall be displayed if neither the category is "input" nor the type is "mod". + It shall be a comma separated list of all tags from direct upstream references, but not from indirect upstream references. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_DerivedFeature: + text: | + A "Derived Feature" attribute shall be displayed except for category "input" and types "information" and "mod". + It shall be a comma separated list of all "feature" attributes from direct and indirect upstream references which are input requirements. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_DerivedChangeRequest: + text: | + A "Derived Change Request" attribute shall be displayed except for category "input" and types "information" and "mod". + It shall be a comma separated list of all "change request" attributes from direct and indirect upstream references which are input requirements. + Upstream references to "information" and struck through specifications shall be ignored. + The values shall be unique. + If the list is empty, "-" shall be displayed. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/backward_refs.py + +DoxTrace_HTML_Configuration: h2 Configuration + +DoxTrace_HTML_ConfigDirective: + text: dox_trace shall provide the argument-less directive ".. dox_trace_config::". This directive + shall generate a configuration table to change the HTML output on-the-fly using jQuery + described below. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/_static/dox_trace.js + +DoxTrace_HTML_ConfigStorage: + text: The configuration shall be stored permanently in local storage of the browser based on the + Sphinx project name. + tags: tool, covered, tested + status: valid + sources: dox_trace/_static/dox_trace.js + +DoxTrace_HTML_ConfigReadingMode: + text: | + The configuration directive shall provide a setting to hide/show attributes: + - Show all + - Hide empty + - Hide empty and "[missing]" + - Hide all + Type, ID and the content shall always be shown. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/config.py, + dox_trace/_static/dox_trace.js + +DoxTrace_HTML_EnclosedFiles: h2 Enclosed Files + +DoxTrace_HTML_EnclosedDirective: + text: dox_trace shall provide a directive "enclosed" which copies all listed files to the build + folder. + tags: tool, covered, tested + status: valid + sources: dox_trace/enclosed.py + +DoxTrace_HTML_TraceabilityReport: h2 Traceability Report + +DoxTrace_HTML_TraceabilityReportInput: + text: dox_trace shall provide a Sphinx directive to create a traceability report for input + requirements. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_table.py, + report_input.py + +DoxTrace_HTML_TraceabilityReportSoftware: + text: dox_trace shall provide a Sphinx directive to create a traceability report for software + requirements. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_table.py + +DoxTrace_HTML_TraceabilityReportArchitecture: + text: dox_trace shall provide a Sphinx directive to create a traceability report for software + architecture. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_table.py + +DoxTrace_HTML_TraceabilityReportModule: + text: dox_trace shall provide a Sphinx directive to create a traceability report for software + module design. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_table.py + +DoxTrace_HTML_TraceabilityReportSource: + text: dox_trace shall provide a Sphinx directive to create a traceability report for source files. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_table.py, + report_source.py + +DoxTrace_HTML_TraceabilityReportUnknownCategory: + text: If the traceability report is specified for an unknown category, dox_trace shall abort the + build and print an appropriate error message. + tags: tool, covered, tested + status: valid + sources: dox_trace/report.py + +DoxTrace_HTML_TraceabilityReportUnknownModule: + text: For the traceability report, the module names need to be determined. If that is not + possible, the module name "Unknown" shall be used as fallback. + tags: tool, covered, tested + status: valid + sources: dox_trace/report.py + +DoxTrace_HTML_TraceabilityReportIgnore: + text: dox_trace shall ignore specifications with attribute "ignore_in_export" for the traceability + report. + tags: tool, covered, tested + status: valid + sources: dox_trace/report.py + +DoxTrace_HTML_TraceabilityDeveloper: + text: The directive for the traceability report shall provide an option to specify the developer + to select the relevant entries. This option shall be mandatory for all reports except for + source files. dox_trace shall be tolerant applying this option regarding whitespaces and + capitalization. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/report.py, + report_generic.py, + report_input.py, + report_architecture.py, + report_module.py + +DoxTrace_HTML_UndefinedRefsList: h2 List of Undefined References + +DoxTrace_HTML_UndefinedRefsListDirective: + text: dox_trace shall provide the argument-less directive ".. undefined_refs::". This directive + shall generate a list of all specifications, which have undefined references. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/checks.py, + dox_trace/undefined_refs.py + refs: DoxTrace_HTML_RefsRed + +DoxTrace_Export_Heading: h1 Export + +DoxTrace_Export_Config: + text: | + dox_trace shall provide a Sphinx configuration variable "dox_trace_dim_root". + If set, dox_trace shall export all "srs", "spec", "unit" "interface" and "mod" elements to this folder in Dim format. + If not set, no export shall be made. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Filenames: + text: | + The filenames shall be "//.dim": + - is defined by the configuration variable + - shall either be "srs", "swa" or "smd", depending on the ID to be exported + - is given by Sphinx, e.g. if the specifications are in /a/b/c.rst, will be "a/b/c" + Note, that is defined by the user when calling the Sphinx executable. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Delete: + text: | + Before doing the export, dox_trace shall delete all files in the "dox_trace_dim_root" folder from a potential previous export, which means: + - "/srs/**/*.dim", + - "/swa/**/*.dim" and + - "/smd/**/*.dim". + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_ModuleName: + text: | + The "module" attribute of the Dim file shall taken from the first specification of the particular RST-files with the following regex: "^[^_]+_[^_]+". + This means the module name of "SWA_MyFeature_Abc" is "SWA_MyFeature". + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_IDs: + text: The IDs of the Dim requirements shall be the same as the dox_trace specification IDs. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Attributes: + text: The attributes for the Dim requirements shall be exported 1:1 from the dox_trace + specifications with the exceptions stated below. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_Category: + text: | + "category" attributes shall never be exported. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Cal: + text: If the config parameter "dox_trace_security_backward" is set to "True", the "cal" attribute + shall not be exported. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_Security: + text: If the config parameter "dox_trace_security_backward" is not set to "True", the "security" + attribute shall not be exported. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_VerificationCriteria: + text: | + If type is "interface" and the ID starts with "SMD_", "verification_criteria" shall not be exported. + If "verification_criteria" is set, it shall be replaced by "See Sphinx documentation." for the export. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_Reuse: + text: | + "reuse" attributes shall never be exported. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Usage: + text: | + "usage" attributes shall never be exported. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Export_Location: + text: | + "location" attributes shall never be exported. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_Export_Content: + text: | + The specification content has no explicit attribute name in dox_trace. For the export the name "text" shall be used. + The value shall always be replaced by "See Sphinx documentation." for the export if the content is not empty. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_Tester: + text: | + "tester" shall be set to "" for the export if: + - type is "mod" + - type is "interface" and the ID starts with "SMD_" + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_TestSetups: + text: | + If the config parameter "dox_trace_test_setups_backward" is not set to "True", the "test_setups" attribute shall not be exported. + "test_setups" shall be set to "none" for the export if: + - type is "mod" + - type is "interface" and the ID starts with "SMD_" tags: tool, covered, tested + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_VerificationMethods: + text: | + If the config parameter "dox_trace_test_setups_backward" is set to "True", the "verification_methods" attribute shall not be exported. + "verification_methods" shall be set to "none" for the export if: + - type is "mod" + - type is "interface" and the ID starts with "SMD_" + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/dim_write.py + +DoxTrace_Export_Unit: + text: The "tags" attribute shall be extended with "unit" for "unit" specifications for the export. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Interface: + text: The "tags" attribute shall be extended with "interface" for "interface" specifications for + the export. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Export_Mod: + text: The "tags" attribute shall be extended with "covered" for "mod" specifications for the + export if the attribute "location" points to a valid module. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + refs: DoxTrace_HTML_Location + +DoxTrace_Export_IgnoreInExport: + text: If "ignore_in_export" is set, the particular specification shall not be exported. + tags: tool, covered, tested + status: valid + sources: dox_trace/dim_write.py + +DoxTrace_Custom_Heading: h1 Custom Attributes + +DoxTrace_CustomGeneral_Heading: h2 Configuration + +DoxTrace_CustomGeneral_Config: + text: | + dox_trace shall provide a Sphinx configuration variable "dox_trace_custom_attributes", which shall be a hash with: + + - key: "name" of the attribute + - value: parameter hash for the attribute (details see following requirements) + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomName_Heading: h2 Name + +DoxTrace_CustomName_Available: + text: dox_trace shall make the attributes available for specifications using the configured names. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomName_Conflict: + text: | + dox_trace shall check if the specified attribute names already exist. + If a name conflict is detected, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomDirectives_Heading: h2 Directives + +DoxTrace_CustomDirectives_Syntax: + text: A custom attribute shall have a mandatory "directives" parameter with a non-empty list of + all specification types for which the attribute shall be available. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + refs: DoxTrace_Syntax_Types + +DoxTrace_CustomDirectives_Check: + text: If that "directives" parameter is not provided, the build shall be aborted with exit code != + 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomCategories_Heading: h2 Categories + +DoxTrace_CustomCategories_Syntax: + text: If the "directives" parameter includes "requirement" or "information, the custom attribute + shall also have a "categories" parameter with a non-empty list of all category types for + which the attribute shall be available. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomCategories_Value: + text: | + The allowed values for "categories" shall be "system", "software" and "input". + If another value is used, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: dox_trace/directives.py + +DoxTrace_CustomType_Heading: h2 Type + +DoxTrace_CustomTypes_Syntax: + text: A custom attribute shall have a mandatory "type" parameter with the allowed + values "text", "enum" and "refs". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomTypes_Text: + text: | + If the "type" parameter is set to "text", dox_trace shall handle this parameter as RST syntax and format the output accordingly. + Empty "text" attributes shall be rendered as "-". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomTypes_Enum: + text: | + If the "type" parameter is set to "enum", dox_trace shall handle this parameter as a comma separated string list and format the output accordingly. + Empty "enum" attributes shall be rendered as "-". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomTypes_Refs: + text: | + If the "type" parameter is set to "refs", dox_trace shall handle this parameter as a comma separated list of Sphinx references and format the output accordingly. + Empty "refs" attributes shall be rendered as "-". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomDefault_Heading: h2 Default + +DoxTrace_CustomDefault_Syntax: + text: | + A custom attribute shall have an optional "default" parameter. + If the custom attribute is not set in a specification, this default value shall be taken. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomDefault_Type: + text: | + The type of the "default" parameter shall be: + + - string for attribute type "text" + - list for attribute types "enum" and "refs" + + If another type is used, the build shall be aborted with exit code != 0 and an error message be printed to the console. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomDefault_Default: + text: | + If "default" is not set, the value of this parameter shall be treated as: + + - empty string for attribute type "text" + - empty list for attribute types "enum" and "refs" + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_CustomExport_Heading: h2 Export + +DoxTrace_CustomExport_Syntax: + text: | + A custom attribute shall have an optional "export" parameter with the allowed values "yes" and "no". + If not set, the value of this parameter shall be treated as "no". + + Attributes shall be exported to Dim if the "export" parameter is set to "yes". + tags: tool, covered, tested + status: valid + sources: > + dox_trace/config.py, + dox_trace/directives.py + +DoxTrace_Properties_Heading: h1 Properties + +dox_trace_properties_file: + text: | + dox_trace shall provide a Sphinx configuration variable "dox_trace_properties_file". + This file shall be a YAML file consisting of a hash with an ID as key and another hash as value. + The inner hashes shall be the attribute key/value pairs for specifications. + + Example: + + SMD_myQmModule: { asil: QM, cal: QM } + SWA_mySafeFeature: { asil: ASIL_B, cal: CAL_2 } + _default_: { asil: ASIL_D, cal: CAL_2 } + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/yaml.py + +DoxTrace_Properties_Use: + text: | + If an attribute or the content is not explicitly specified in an RST file, dox_trace shall try to find a matching property before falling back to the default value. + + The IDs shall be matched in the following order: + + - prio 1: property ID = specification ID, e.g. SWA_Feature_XY + - prio 2: property ID = specification ID until one character before the second "_", e.g. SWA_Feature + - prio 3: property ID = specification ID until one character before the first "_", e.g. SWA + - prio 4: property ID = "_default_" + + If an ID including the attribute name is found, the value shall be used for the corresponding specification. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/properties.py + +DoxTrace_Properties_Custom: + text: Properties shall also apply to custom attributes. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/directives.py, + dox_trace/properties.py + +DoxTrace_Properties_Standalone: + text: | + The properties shall also be usable as roles and directives independent from specifications: + + - role: :prop:`:` + - directive: .. prop:: : + + The fallback "_default_" shall be applied here the same way as for specifications. + tags: tool, covered, tested + status: valid + sources: > + dox_trace/yaml.py, + dox_trace/properties.py diff --git a/dox_trace/req/properties.yaml b/dox_trace/req/properties.yaml new file mode 100644 index 0000000..beb3822 --- /dev/null +++ b/dox_trace/req/properties.yaml @@ -0,0 +1,5 @@ +dox_trace: + asil: QM + cal: QM + developer: Accenture + tester: Accenture diff --git a/dox_trace/spec/asil_spec.rb b/dox_trace/spec/asil_spec.rb new file mode 100644 index 0000000..a1f14a4 --- /dev/null +++ b/dox_trace/spec/asil_spec.rb @@ -0,0 +1,64 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute asil" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("asil") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Asil'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("asil", "index.html") + + expect(data.value("InputInformation_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("InputRequirement_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SRS_Information_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SRS_Requirement_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SRS_Srs_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SWA_Spec_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SMD_Unit_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SWA_Interface_AsilB", "asil")).to eq 'ASIL_B' + expect(data.value("SWA_Mod_AsilB", "asil")).to eq 'ASIL_B' + + expect(data.value("InputInformation_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("InputRequirement_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SRS_Information_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SRS_Requirement_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SRS_Srs_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SWA_Spec_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SMD_Unit_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SWA_Interface_AsilDefault", "asil")).to eq 'not_set' + expect(data.value("SWA_Mod_AsilDefault", "asil")).to eq 'not_set' + + expect(data.value("SWA_Spec_ReviewStatusRejected", "asil")).to eq 'not_set' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Asil', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/asil/export_root/srs/index.dim"] + + expect(srs["SRS_Srs_AsilB"]["asil"]).to eq 'ASIL_B' + expect(srs["SRS_Srs_AsilDefault"]["asil"]).to eq 'not_set' + + swa = @test.dim_original_data["spec/test_input/asil/export_root/swa/index.dim"] + + expect(swa["SWA_Spec_AsilB"]["asil"]).to eq 'ASIL_B' + expect(swa["SWA_Interface_AsilB"]["asil"]).to eq 'ASIL_B' + expect(swa["SWA_Mod_AsilB"]["asil"]).to eq 'ASIL_B' + + expect(swa["SWA_Spec_AsilDefault"]["asil"]).to eq 'not_set' + expect(swa["SWA_Interface_AsilDefault"]["asil"]).to eq 'not_set' + expect(swa["SWA_Mod_AsilDefault"]["asil"]).to eq 'not_set' + + expect(swa["SWA_Spec_ReviewStatusRejected"]["asil"]).to eq 'not_set' + + smd = @test.dim_original_data["spec/test_input/asil/export_root/smd/index.dim"] + + expect(smd["SMD_Unit_AsilDefault"]["asil"]).to eq 'not_set' + expect(smd["SMD_Unit_AsilB"]["asil"]).to eq 'ASIL_B' + end + end + + end +end diff --git a/dox_trace/spec/cal_spec.rb b/dox_trace/spec/cal_spec.rb new file mode 100644 index 0000000..9c1bf30 --- /dev/null +++ b/dox_trace/spec/cal_spec.rb @@ -0,0 +1,78 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute cal" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("cal") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Cal'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("cal", "index.html") + + expect(data.value("InputInformation_Cal3", "cal")).to eq 'CAL_3' + expect(data.value("InputRequirement_Cal4", "cal")).to eq 'CAL_4' + expect(data.value("SRS_Information_Cal1", "cal")).to eq 'CAL_1' + expect(data.value("SRS_Requirement_Cal2", "cal")).to eq 'CAL_2' + expect(data.value("SRS_Srs_CalQm", "cal")).to eq 'QM' + expect(data.value("SWA_Spec_CalQm", "cal")).to eq 'QM' + expect(data.value("SMD_Unit_Cal1", "cal")).to eq 'CAL_1' + expect(data.value("SWA_Interface_CalQm", "cal")).to eq 'QM' + expect(data.value("SWA_Mod_CalNotSet", "cal")).to eq 'not_set' + + expect(data.value("InputInformation_CalDefault", "cal")).to eq 'not_set' + expect(data.value("InputRequirement_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SRS_Information_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SRS_Requirement_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SRS_Srs_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SWA_Spec_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SMD_Unit_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SWA_Interface_CalDefault", "cal")).to eq 'not_set' + expect(data.value("SWA_Mod_CalDefault", "cal")).to eq 'not_set' + + expect(data.value("SWA_Spec_ReviewStatusRejected", "cal")).to eq 'not_set' + end + + it 'shall derive the value from security if cal is not defined', doc_refs: ['DoxTrace_Syntax_SecurityToCal', 'DoxTrace_HTML_Security'] do + data = HtmlData.new("cal", "index.html") + + expect(data.value("SWA_Spec_CalYes", "cal")).to eq 'CAL_4' + expect(data.value("SWA_Spec_CalNo", "cal")).to eq 'QM' + expect(data.value("SWA_Spec_CalNotSet", "cal")).to eq 'not_set' + expect(data.value("SWA_Spec_CalYes1", "cal")).to eq 'CAL_1' + + expect(data.exist?("SWA_Spec_CalYes1", "security")).to be false + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Cal', 'DoxTrace_Export_Attributes', 'DoxTrace_Export_Security'] do + srs = @test.dim_original_data["spec/test_input/cal/export_root/srs/index.dim"] + expect(srs["SRS_Srs_CalQm"]["cal"]).to eq 'QM' + expect(srs["SRS_Srs_CalDefault"]["cal"]).to eq 'not_set' + + swa = @test.dim_original_data["spec/test_input/cal/export_root/swa/index.dim"] + expect(swa["SWA_Spec_CalQm"]["cal"]).to eq 'QM' + expect(swa["SWA_Interface_CalQm"]["cal"]).to eq 'QM' + expect(swa["SWA_Mod_CalNotSet"]["cal"]).to eq 'not_set' + expect(swa["SWA_Spec_CalDefault"]["cal"]).to eq 'not_set' + expect(swa["SWA_Interface_CalDefault"]["cal"]).to eq 'not_set' + expect(swa["SWA_Mod_CalDefault"]["cal"]).to eq 'not_set' + expect(swa["SWA_Spec_ReviewStatusRejected"]["cal"]).to eq 'not_set' + + expect(swa["SWA_Spec_CalYes"]["cal"]).to eq 'CAL_4' + expect(swa["SWA_Spec_CalNo"]["cal"]).to eq 'QM' + expect(swa["SWA_Spec_CalNotSet"]["cal"]).to eq 'not_set' + expect(swa["SWA_Spec_CalYes1"]["cal"]).to eq 'CAL_1' + + # security is not exported + expect(swa["SWA_Spec_CalYes1"]).not_to include "security" + + smd = @test.dim_original_data["spec/test_input/cal/export_root/smd/index.dim"] + expect(smd["SMD_Unit_Cal1"]["cal"]).to eq 'CAL_1' + expect(smd["SMD_Unit_CalDefault"]["cal"]).to eq 'not_set' + end + end + + end +end diff --git a/dox_trace/spec/category_spec.rb b/dox_trace/spec/category_spec.rb new file mode 100644 index 0000000..ec06a20 --- /dev/null +++ b/dox_trace/spec/category_spec.rb @@ -0,0 +1,98 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute category" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("category") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("category", "index.html") + + # comment is only visible for input requirements, not for software requirements + + expect(data.exist?("SRS_Information_CategorySet", "comment")).to be false + expect(data.exist?("SRS_Requirement_CategorySet", "comment")).to be false + expect(data.exist?("InputInformation_CategorySet", "comment")).to be true + expect(data.exist?("InputRequirement_CategorySet", "comment")).to be true + + expect(data.exist?("DefaultInformation_CategoryDefault", "comment")).to be true + expect(data.exist?("DefaultRequirement_CategoryDefault", "comment")).to be true + end + + it 'shall not be exported', doc_refs: ['DoxTrace_Export_Category'] do + dim = File.read("#{$test_input_dir}/category/export_root/swa/index.dim") + expect(dim).not_to match(/category/) + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("category_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "category"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("category_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "category"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("category_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "category"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("category_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "category"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("category_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Category'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "category"' + end + end + + end +end diff --git a/dox_trace/spec/change_request_spec.rb b/dox_trace/spec/change_request_spec.rb new file mode 100644 index 0000000..2761c57 --- /dev/null +++ b/dox_trace/spec/change_request_spec.rb @@ -0,0 +1,102 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute change_request" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("change_request") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_ChangeRequest', 'DoxTrace_HTML_ChangeRequest'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("change_request", "index.html") + + expect(data.exist?("SRS_Requirement_ChangeRequestSet", "change_request")).to be false + expect(data.value("InputRequirement_ChangeRequestSet", "change_request")).to eq 'Dd' + + expect(data.exist?("SRS_Requirement_ChangeRequestDefault", "change_request")).to be false + expect(data.value("InputRequirement_ChangeRequestDefault", "change_request")).to eq '-' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("change_request_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("change_request_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("change_request_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("change_request_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("change_request_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("change_request_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_ChangeRequest'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "change_request"' + end + end + + end +end diff --git a/dox_trace/spec/checks_spec.rb b/dox_trace/spec/checks_spec.rb new file mode 100644 index 0000000..a274247 --- /dev/null +++ b/dox_trace/spec/checks_spec.rb @@ -0,0 +1,355 @@ +require_relative 'framework/helper' + +module Sphinx + describe "dox_trace shall" do + context 'check for self-references' do + before(:all) do + @test = Test.new("check_cyclic_direct") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Cyclic'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Found cyclic reference: SRS_Requirement_Direct -> SRS_Requirement_Direct' + end + end + + context 'check for cyclic references through several specifications' do + before(:all) do + @test = Test.new("check_cyclic_indirect") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Cyclic'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Found cyclic reference: SRS_Requirement_Indirect1 -> SRS_Requirement_Indirect2 -> SRS_Requirement_Indirect4 -> SRS_Requirement_Indirect1' + end + end + + context 'check for cyclic references not through several levels' do + before(:all) do + @test = Test.new("check_cyclic_indirect_levels") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Cyclic'] do + expect(@test.exit_code).to be == 0 + expect(@test.test_stderr).not_to include 'Found cyclic reference' + end + end + + context 'check for invalid references' do + before(:all) do + @test = Test.new("check_invalid_ref") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_InvalidRefs'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Found invalid reference from SRS_Requirement_InvalidRef to invalid_target' + end + end + + context 'check for references with wrong case' do + before(:all) do + @test = Test.new("check_invalid_case") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Case'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Incorrect case in refs of SRS_Requirement_InvalidCase: SRS_Requirement_target instead of SRS_Requirement_Target' + end + end + + context 'check for sources in spec which do not exist' do + before(:all) do + @test = Test.new("check_invalid_sources_spec") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: file "does/not/exist.cpp" not found' + end + end + + context 'check for sources in unit which do not exist' do + before(:all) do + @test = Test.new("check_invalid_sources_unit") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: file "does/not/exist.cpp" not found' + end + end + + context 'check for sources in interface which do not exist' do + before(:all) do + @test = Test.new("check_invalid_sources_interface") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: file "does/not/exist.cpp" not found' + end + end + + context 'check for sources in srs which do not exist' do + before(:all) do + @test = Test.new("check_invalid_sources_srs") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: file "does/not/exist.cpp" not found' + end + end + + context 'not check for invalid sources in requirement' do + before(:all) do + @test = Test.new("check_invalid_sources_requirement") + @test.run + end + it 'and not abort the build in these cases', doc_refs: ['DoxTrace_Checks_Sources'] do + expect(@test.exit_code).to be == 0 + end + end + + context 'check for invalid comment "spec:"' do + before(:all) do + @test = Test.new("check_invalid_comment_spec") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'first line of comment looks like a typo: "spec:"' + end + end + + context 'check for invalid comment ":unit:"' do + before(:all) do + @test = Test.new("check_invalid_comment_unit") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include ' first line of comment looks like a typo: ":unit:"' + end + end + + context 'check for invalid comment "interface"' do + before(:all) do + @test = Test.new("check_invalid_comment_interface") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'first line of comment looks like a typo: "interface"' + end + end + + context 'check for invalid comment ":mod"' do + before(:all) do + @test = Test.new("check_invalid_comment_mod") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'first line of comment looks like a typo: ":mod"' + end + end + + context 'check for invalid comment "srs.."' do + before(:all) do + @test = Test.new("check_invalid_comment_srs") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'first line of comment looks like a typo: "srs.."' + end + end + + context 'ignore valid comments' do + before(:all) do + @test = Test.new("check_invalid_comment_ignored") + @test.run + end + it 'and not abort the build in these cases', doc_refs: ['DoxTrace_Checks_Comments'] do + expect(@test.exit_code).to be == 0 + end + end + + context 'check if an ID is used twice' do + before(:all) do + @test = Test.new("check_unique_id") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Unique'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'specification SRS_Requirement_NotUnique found twice' + end + end + + context 'check if an ID contains a newline' do + before(:all) do + @test = Test.new("check_newline_id") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Newline'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SRS_Requirement_Direct\nContinue must not contain newlines' + end + end + + context 'check if an ID has two underscores after the prefix instead of one' do + before(:all) do + @test = Test.new("check_naming_double_underscore") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SWA__ does not follow the form SMD|SWA__' + end + end + + context 'check if an ID has incorrect case' do + before(:all) do + @test = Test.new("check_naming_lower_case") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id swa_x_y does not follow the form SMD|SWA__' + end + end + + context 'check if an ID does not have a character after the first underscore' do + before(:all) do + @test = Test.new("check_naming_too_short") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SMD_ModuleName_ does not follow the form SMD__' + end + end + + context 'check if a deprecated ID does not have a character after the first underscore' do + before(:all) do + @test = Test.new("check_naming_too_short_deprecated") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_NamingDeprecated'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SMD_ does not follow the form SMD|SWA__' + end + end + + context 'check if spec ID does not contain three underscores' do + before(:all) do + @test = Test.new("check_naming_three_underscores") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SWA_X_Y_Z does not follow the form SMD|SWA__' + end + end + + context 'check if an interface ID does not start with wrong prefix' do + before(:all) do + @test = Test.new("check_naming_wrong_prefix_interface") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SMD_X_Y does not follow the form SWA__' + end + end + + context 'check if a mod ID does not start with wrong prefix' do + before(:all) do + @test = Test.new("check_naming_wrong_prefix_mod") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SMD_X_Y does not follow the form SWA__' + end + end + + context 'check if an srs ID does not start with wrong prefix' do + before(:all) do + @test = Test.new("check_naming_wrong_prefix_srs") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SWA_X_Y does not follow the form SRS__' + end + end + + context 'check if a unit ID does not start with wrong prefix' do + before(:all) do + @test = Test.new("check_naming_wrong_prefix_unit") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SWA_X_Y does not follow the form SMD__' + end + end + + context 'check if a deprecated ID does not start with wrong prefix' do + before(:all) do + @test = Test.new("check_naming_wrong_prefix_tolerant") + @test.run + end + it 'and abort the build with appropriate error message if detected', doc_refs: ['DoxTrace_Checks_NamingDeprecated'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: id SRS_X does not follow the form SMD_' + end + end + + context 'accept valid IDs' do + before(:all) do + @test = Test.new("check_naming_valid") + @test.run + end + it 'and not abort the build in these cases', doc_refs: ['DoxTrace_Checks_Naming'] do + expect(@test.exit_code).to be == 0 + end + end + + context 'accept valid deprecated IDs' do + before(:all) do + @test = Test.new("check_naming_valid_tolerant") + @test.run + end + it 'and not abort the build in these cases', doc_refs: ['DoxTrace_Checks_NamingDeprecated'] do + expect(@test.exit_code).to be == 0 + end + end + + context 'check if Python 3.8 or later is used' do + before(:all) do + # every test setup can be used which has to error + @test = Test.new("check_outdated_python", "MANIPULATE_PYTHON_VERSION=1") + @test.run + end + it 'and abort the build with appropriate error message if Python version is too old', doc_refs: ['DoxTrace_Checks_PythonVersion'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'The dox_trace extension requires Python 3.8+' + end + end + + context 'check if Sphinx 6.2 or later is used' do + before(:all) do + # every test setup can be used which has to error + @test = Test.new("check_outdated_sphinx", "MANIPULATE_SPHINX_VERSION=1") + @test.run + end + it 'and abort the build with appropriate error message if Sphinx version is too old', doc_refs: ['DoxTrace_Checks_SphinxVersion'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'The dox_trace extension requires Sphinx 6.2+' + end + end + end +end diff --git a/dox_trace/spec/comment_spec.rb b/dox_trace/spec/comment_spec.rb new file mode 100644 index 0000000..db87c4c --- /dev/null +++ b/dox_trace/spec/comment_spec.rb @@ -0,0 +1,93 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute comment" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("comment") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Comment', 'DoxTrace_HTML_Comment'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("comment", "index.html") + + expect(data.exist?("SRS_Information_CommentSet", "comment")).to be false + expect(data.exist?("SRS_Requirement_CommentSet", "comment")).to be false + expect(data.value("InputInformation_CommentSet", "comment")).to eq 'Cc' + expect(data.value("InputRequirement_CommentSet", "comment")).to eq 'Dd' + + expect(data.exist?("SRS_Information_CommentDefault", "comment")).to be false + expect(data.exist?("SRS_Requirement_CommentDefault", "comment")).to be false + expect(data.value("InputInformation_CommentDefault", "comment")).to eq '-' + expect(data.value("InputRequirement_CommentDefault", "comment")).to eq '-' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("comment_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Comment'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "comment"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("comment_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Comment'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "comment"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("comment_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Comment'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "comment"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("comment_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Comment'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "comment"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("comment_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Comment'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "comment"' + end + end + + end +end diff --git a/dox_trace/spec/config_spec.rb b/dox_trace/spec/config_spec.rb new file mode 100644 index 0000000..edc8eaf --- /dev/null +++ b/dox_trace/spec/config_spec.rb @@ -0,0 +1,170 @@ + require_relative 'framework/helper' + +module Sphinx + describe "The directive" do + context 'dox_trace_config' do + before(:all) do + @test = Test.new("config") + @test.run + end + + attributes = ["Status", "Review Status", + "Asil", "Security", "Developer", "Tester", "Test Setups", "Tags", + "Reuse", "Usage", + "Verification Criteria", + "Comment", + "Feature", + "Change Request", + "Miscellaneous", + "Upstream Asil", "Upstream Security", "Upstream Tags", "Derived Feature", "Derived Change Request", + "Location", "Sources", "Upstream References", "Downstream References"] + + + it 'shall be used to hide/show complete attribute rows', doc_refs: [ 'DoxTrace_HTML_ConfigReadingMode'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("config", "index.html") + + html = data.html + html.gsub!(/

\s*\[missing\]\s*<\/p><\/td><\/tr>/m, "") # content + html.gsub!(//, "") # hidden rows + html.gsub!(/|

|<\/p>)/m, "") # attributes from first row + + # attributes hidden + attributes.each do |attribute| + if html.include?("#{attribute}:") + puts "FOUND: #{attribute}" + end + expect(html).not_to include("#{attribute}:") + end + end + + # this is a test if jQuery and localStorage are used in general, it will + # not replace a manual test and review in real browsers + it 'shall expand to a configuration table using jQuery and the local storage of the browser', + doc_refs: ['DoxTrace_HTML_ConfigDirective', 'DoxTrace_HTML_ConfigStorage'] do + + data = HtmlData.new("config", "index.html") + js = File.read("#{$test_input_dir}/config/build/html/_static/dox_trace.js") + expect(data.html).to match(/_static\/dox_trace.css/) + + # id used in jQuery + ["dox_trace_config_none", "dox_trace_config_empty", "dox_trace_config_missing", "dox_trace_config_all"].each do |id| + expect(data.html).to match(/id="#{id}"/) + expect(js).to match(/##{id}/) + end + + # local storage based on project name + expect(js).to match(/name="dox_trace_storage"/) + expect(data.html).to match(//) + end + + it 'shall be used to hide/show empty/missing attributes', doc_refs: [ 'DoxTrace_HTML_ConfigReadingMode'] do + data_index = HtmlData.new("config", "index.html") + data_filled = HtmlData.new("config", "filled.html") + data_special = HtmlData.new("config", "special.html") + + expected = { + "Input_ConfigPreview_Requirement" => {:empty => ["verification_methods", "tags", "verification_criteria", "comment", "miscellaneous", "feature", "change_request", "upstream_references", "custom"], + :missing => ["developer", "tester", "downstream_references"]}, + "Input_ConfigPreview_Information" => {:empty => ["tags", "comment", "miscellaneous", "downstream_references", "upstream_references", "custom"], + :missing => []}, + "SRS_ConfigPreview_Requirement" => {:empty => ["verification_methods", "tags", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "custom"], + :missing => ["developer", "tester", "verification_criteria", "downstream_references", "upstream_references"]}, + "SRS_ConfigPreview_Information" => {:empty => ["tags", "upstream_asil", "upstream_security", "upstream_tags", "downstream_references", "upstream_references", "custom"], + :missing => []}, + "SRS_ConfigPreview_Srs" => {:empty => ["tags", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "custom"], + :missing => ["verification_criteria", "downstream_references", "upstream_references", "developer", "tester"]}, + "SWA_ConfigPreview_Spec" => {:empty => ["tags", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "verification_criteria", "custom"], + :missing => ["downstream_references", "upstream_references", "developer", "tester"]}, + "SWA_ConfigPreview_Mod" => {:empty => ["reuse", "usage", "upstream_asil", "upstream_security", "custom"], + :missing => ["developer", "location", "upstream_references", "developer"]}, + "SWA_ConfigPreview_Interface" => {:empty => ["tags", "verification_criteria", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "custom"], + :missing => ["downstream_references", "upstream_references", "developer", "tester"]}, + "SMD_ConfigPreview_Unit" => {:empty => ["tags", "verification_criteria", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "downstream_references", "custom"], + :missing => ["sources", "upstream_references", "developer", "tester"]}, + "Input_ConfigPreview_RequirementFilled" => {:empty => [],:missing => []}, + "Input_ConfigPreview_InformationFilled" => {:empty => [],:missing => []}, + "SRS_ConfigPreview_RequirementFilled" => {:empty => [],:missing => []}, + "SRS_ConfigPreview_InformationFilled" => {:empty => [],:missing => []}, + "SRS_ConfigPreview_SrsFilled" => {:empty => [],:missing => []}, + "SWA_ConfigPreview_SpecFilled" => {:empty => [],:missing => []}, + "SWA_ConfigPreview_ModFilled" => {:empty => [],:missing => []}, + "SWA_ConfigPreview_InterfaceFilled" => {:empty => [],:missing => []}, + "SMD_ConfigPreview_UnitFilled" => {:empty => ["downstream_references"],:missing => []}, + + "SRS_ConfigPreview_RequirementStruck" => {:empty => ["verification_methods", "tags", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "custom", + "developer", "tester", "verification_criteria", "downstream_references", "upstream_references"], + :missing => []}, + "SWA_ConfigPreview_SpecStruck" => {:empty => ["tags", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "verification_criteria", "custom", + "downstream_references", "upstream_references", "developer", "tester"], + :missing => []}, + "SWA_ConfigPreview_ModStruck" => {:empty => ["reuse", "usage", "upstream_asil", "upstream_security", "custom", + "developer", "location", "upstream_references"], + :missing => []}, + "SMD_ConfigPreview_UnitStruck" => {:empty => ["tags", "verification_criteria", "derived_feature", "derived_change_request", "upstream_asil", "upstream_security", "upstream_tags", "downstream_references", "custom", + "sources", "upstream_references", "developer", "tester"], + :missing => []}, + } + + expected.each do |id, map| + (attributes + ["Custom"]).each do |attribute| + attribute = attribute.downcase.gsub(" ", "_") + [data_index, data_filled, data_special].each do |data_file| + if data_file.exist?(id, attribute) + expect(data_file.missing_class?(id, attribute)).to be map[:missing].include?(attribute) + expect(data_file.empty_class?(id, attribute)).to be map[:empty].include?(attribute) + end + end + end + end + end + + it 'shall also hide the vertical bar between "Tags" and "Upstream Tags" if at least one of them is hidden', + doc_refs: [ 'DoxTrace_HTML_ConfigReadingMode'] do + + data = HtmlData.new("config", "special.html") + + expected = { + "SWA_ConfigPreview_SpecParentTagsParent" => true, + "SWA_ConfigPreview_SpecParentTagsNone" => true, + "SWA_ConfigPreview_SpecParentTagsBoth" => false, + "SWA_ConfigPreview_SpecParentTagsOnlyParent" => true, + "SWA_ConfigPreview_SpecParentTagsOnlyChild" => true + } + + expected.each do |id, empty| + str = empty ? " dox-trace-attribute-empty" : "" + bar_empty = /\A[^<]*<\/*span> \|/ + table = data.getTableInternal(id, "tags") + expect(table.match?(bar_empty)).to be true + end + end + + it 'shall hide a row if all attributes in this row are hidden', doc_refs: [ 'DoxTrace_HTML_ConfigReadingMode'] do + data = HtmlData.new("config", "special.html") + + # two rows can disappear completely if empty/missing values are hidden + expect(data.getTableInternal("SWA_ConfigPreview_SpecParentTagsHideIfEmpty", "status").scan(/hide-if-empty/).length).to be 2 + end + + it 'shall not add an unnecessary line break if "Developer", "Tester" and "Verification Methods" are hidden', + doc_refs: [ 'DoxTrace_HTML_ConfigReadingMode'] do + + data = HtmlData.new("config", "special.html") + + expected = { + "Input_ConfigPreview_RequirementDevTestAlways" => /\A-<\/span>
/, + "Input_ConfigPreview_RequirementDevTestMissing" => /\A-<\/span>
<\/span>/, + "Input_ConfigPreview_RequirementDevTestEmpty" => /\A-<\/span>
<\/span>/ + } + + expected.each do |id, regex| + table = data.getTableInternal(id, "verification_methods") + expect(table.match?(regex)).to be true + end + end + + end + end +end diff --git a/dox_trace/spec/content_spec.rb b/dox_trace/spec/content_spec.rb new file mode 100644 index 0000000..29faf02 --- /dev/null +++ b/dox_trace/spec/content_spec.rb @@ -0,0 +1,41 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The content" do + context 'of specifications' do + before(:all) do + @test = Test.new("content") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_HTML_Content'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("content", "index.html") + + expect(data.value("SRS_Requirement_Missing", "content")).to eq '[missing]' + expect(data.value("SRS_Information_Missing", "content")).to eq '[missing]' + expect(data.value("InputRequirement_Missing", "content")).to eq '[missing]' + expect(data.value("InputInformation_Missing", "content")).to eq '[missing]' + expect(data.value("SRS_Srs_Missing", "content")).to eq '[missing]' + expect(data.value("SWA_Spec_Missing", "content")).to eq '[missing]' + expect(data.value("SMD_Unit_Missing", "content")).to eq '[missing]' + expect(data.value("SWA_Interface_Missing", "content")).to eq '[missing]' + expect(data.value("SWA_Mod_Missing", "content")).to eq '[missing]' + + expect(data.value("SWA_Spec_Struck", "content")).to eq '[missing]' + + expect(data.value("SWA_Spec_Content1", "content")).to eq '

Some text.

' + expect(data.value("SWA_Spec_Content2", "content")).to match /counter.*End of example/m + expect(data.value("SRS_Requirement_Content3", "content")).to match /This is bold<\/b>\./ + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Export_Content'] do + data = @test.dim_original_data["spec/test_input/content/export_root/swa/index.dim"] + + expect(data["SWA_Spec_Missing"]["text"]).to eq '' + expect(data["SWA_Spec_Content1"]["text"]).to eq 'See Sphinx documentation.' + expect(data["SWA_Spec_Content2"]["text"]).to eq 'See Sphinx documentation.' + end + end + end +end diff --git a/dox_trace/spec/custom_categories_spec.rb b/dox_trace/spec/custom_categories_spec.rb new file mode 100644 index 0000000..00ce4fb --- /dev/null +++ b/dox_trace/spec/custom_categories_spec.rb @@ -0,0 +1,85 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute categories" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_categories") + @test.run + end + + it 'shall filter the attribute for the directives correctly without any error', doc_refs: ['DoxTrace_CustomCategories_Syntax', 'DoxTrace_CustomCategories_Value'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("custom_categories", "index.html") + + expect(data.value("Custom_ReqInput", "custom1")).to eq "1" + expect(data.exist?("Custom_ReqSystem", "custom1")).to be false + expect(data.value("SRS_Custom_ReqSoftware", "custom1")).to eq "1" + expect(data.exist?("Custom_InfoInput", "custom1")).to be false + expect(data.exist?("Custom_InfoSystem", "custom1")).to be false + expect(data.exist?("SRS_Custom_InfoSoftware", "custom1")).to be false + expect(data.exist?("SMD_Custom_Unit", "custom1")).to be false + + expect(data.exist?("Custom_ReqInput", "custom2")).to be false + expect(data.exist?("Custom_ReqSystem", "custom2")).to be false + expect(data.value("SRS_Custom_ReqSoftware", "custom2")).to eq "2" + expect(data.exist?("Custom_InfoInput", "custom2")).to be false + expect(data.exist?("Custom_InfoSystem", "custom2")).to be false + expect(data.value("SRS_Custom_InfoSoftware", "custom2")).to eq "2" + expect(data.exist?("SMD_Custom_Unit", "custom2")).to be false + + expect(data.exist?("SRS_Custom_ReqSoftware", "custom3")).to be false + expect(data.value("SMD_Custom_Unit", "custom3")).to eq "3" + + expect(data.value("Custom_ReqInput", "custom4")).to eq "4" + expect(data.value("Custom_ReqSystem", "custom4")).to eq "4" + expect(data.value("SRS_Custom_ReqSoftware", "custom4")).to eq "4" + end + end + + context 'config missing in a requirement/information directive' do + before(:all) do + @test = Test.new("custom_categories_invalid_missing") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomCategories_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one category' + end + end + + context 'config with wrong type' do + before(:all) do + @test = Test.new("custom_categories_invalid_type") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomCategories_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one category' + end + end + + context 'config with empty list' do + before(:all) do + @test = Test.new("custom_categories_invalid_empty") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomCategories_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one category' + end + end + + context 'config with invalid value' do + before(:all) do + @test = Test.new("custom_categories_invalid_value") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomCategories_Value'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file is assigned to invalid category hardware' + end + end + + end +end diff --git a/dox_trace/spec/custom_default_spec.rb b/dox_trace/spec/custom_default_spec.rb new file mode 100644 index 0000000..26dd818 --- /dev/null +++ b/dox_trace/spec/custom_default_spec.rb @@ -0,0 +1,70 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute default" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_default") + @test.run + end + + it 'shall set the default value for attributes correctly without any error', doc_refs: ['DoxTrace_CustomDefault_Syntax', 'DoxTrace_CustomDefault_Default'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("custom_default", "index.html") + + expect(data.value("SWA_Custom_Set", "custom1")).to eq "1" + expect(data.value("SWA_Custom_Set", "custom2")).to eq "2" + expect(data.value("SWA_Custom_Set", "custom3")).to eq "3" + expect(data.value("SWA_Custom_Set", "custom4")).to eq "4" + expect(data.value("SWA_Custom_Set", "custom5")).to eq "5" + expect(data.value("SWA_Custom_Set", "custom6")).to eq "6" + expect(data.value("SWA_Custom_Set", "custom7")).to eq "#swa_custom_r2" + expect(data.value("SWA_Custom_Set", "custom8")).to eq "#swa_custom_r2" + expect(data.value("SWA_Custom_Set", "custom9")).to eq "#swa_custom_r2" + + expect(data.value("SWA_Custom_NotSet", "custom1")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom2")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom3")).to eq "d3" + expect(data.value("SWA_Custom_NotSet", "custom4")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom5")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom6")).to eq "d6, d7" + expect(data.value("SWA_Custom_NotSet", "custom7")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom8")).to eq "-" + expect(data.value("SWA_Custom_NotSet", "custom9")).to eq "#smd_custom_r1" + + expect(data.value("SWA_Custom_Empty", "custom1")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom2")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom3")).to eq "d3" + expect(data.value("SWA_Custom_Empty", "custom4")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom5")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom6")).to eq "d6, d7" + expect(data.value("SWA_Custom_Empty", "custom7")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom8")).to eq "-" + expect(data.value("SWA_Custom_Empty", "custom9")).to eq "#smd_custom_r1" + end + end + + context 'config with wrong type for text attributes' do + before(:all) do + @test = Test.new("custom_default_invalid_text") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDefault_Type'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must have type string for default' + end + end + + context 'config with wrong type for non-text attributes' do + before(:all) do + @test = Test.new("custom_default_invalid_nontext") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDefault_Type'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must have type list for default' + end + end + + end +end diff --git a/dox_trace/spec/custom_directives_spec.rb b/dox_trace/spec/custom_directives_spec.rb new file mode 100644 index 0000000..67bb2ed --- /dev/null +++ b/dox_trace/spec/custom_directives_spec.rb @@ -0,0 +1,98 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute directives" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_directives") + @test.run + end + + it 'shall assign the attribute to a list of directives', doc_refs: ['DoxTrace_CustomDirectives_Syntax'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("custom_directives", "index.html") + + expect(data.value("SMD_Custom_R1", "custom1")).to eq "1" + expect(data.value("SWA_Custom_R2", "custom2")).to eq "2" + expect(data.value("SWA_Custom_R3", "custom3")).to eq "3" + expect(data.value("SWA_Custom_R4", "custom4")).to eq "4" + expect(data.value("SRS_Custom_R5", "custom5")).to eq "5" + expect(data.value("SRS_Custom_R6", "custom6")).to eq "6" + expect(data.value("SRS_Custom_R7", "custom9")).to eq "9" + + expect(data.value("SMD_Custom_R1", "custom7")).to eq "7" + expect(data.value("SWA_Custom_R2", "custom7")).to eq "7" + expect(data.value("SWA_Custom_R3", "custom7")).to eq "7" + expect(data.value("SWA_Custom_R4", "custom7")).to eq "7" + expect(data.value("SRS_Custom_R5", "custom7")).to eq "7" + expect(data.value("SRS_Custom_R6", "custom7")).to eq "7" + expect(data.value("SRS_Custom_R7", "custom7")).to eq "7" + + expect(data.value("SMD_Custom_R1", "custom8")).to eq "8" + expect(data.value("SWA_Custom_R2", "custom8")).to eq "8" + expect(data.exist?("SWA_Custom_R3", "custom8")).to be false + expect(data.exist?("SWA_Custom_R4", "custom8")).to be false + expect(data.exist?("SRS_Custom_R5", "custom8")).to be false + expect(data.exist?("SRS_Custom_R6", "custom8")).to be false + expect(data.exist?("SRS_Custom_R7", "custom8")).to be false + end + end + + context 'config with empty list' do + before(:all) do + @test = Test.new("custom_directives_invalid_empty") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDirectives_Check'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one directive' + end + end + + context 'config missing' do + before(:all) do + @test = Test.new("custom_directives_invalid_missing") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDirectives_Check'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one directive' + end + end + + context 'used for non-specified directives' do + before(:all) do + @test = Test.new("custom_directives_invalid_spec") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDirectives_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "custom"' + end + end + + context 'config wrong type' do + before(:all) do + @test = Test.new("custom_directives_invalid_type") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDirectives_Check'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must be assigned to a list of at least one directive' + end + end + + context 'config with invalid value' do + before(:all) do + @test = Test.new("custom_directives_invalid_value") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomDirectives_Check'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file is assigned to invalid directive file' + end + end + + end +end diff --git a/dox_trace/spec/custom_export_spec.rb b/dox_trace/spec/custom_export_spec.rb new file mode 100644 index 0000000..f36698b --- /dev/null +++ b/dox_trace/spec/custom_export_spec.rb @@ -0,0 +1,56 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute export" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_export") + @test.run + end + + it 'shall export the attribute if set to yes', doc_refs: ['DoxTrace_CustomExport_Syntax'] do + expect(@test.exit_code).to be == 0 + content = File.read("spec/test_input/custom_export/export_root/swa/index.dim") + + # workaround with regex until Dim officially supports custom attributes + + expect(content).to match /SWA_Custom_R2:.*custom_complex_text: '\*\*bold\*\*\s*\n.*- first\s*\n\s*- second'.*custom_enum: '*a, b, c.*custom_refs: '*SMD_Custom_R0,\s*SWA_Custom_R2,\s*SMD_Custom_R1/m + expect(content).to match /SWA_Custom_R3:.*custom_refs: custom_attr/m + end + + it 'shall not export the attribute if set to no', doc_refs: ['DoxTrace_CustomExport_Syntax'] do + expect(@test.exit_code).to be == 0 + content = File.read("spec/test_input/custom_export/export_root/smd/index.dim") + + # workaround with regex until Dim officially supports custom attributes + + expect(content).to match /SMD_Custom_R1:.*custom1/m # custom1 export set to yes + expect(content).not_to match /SMD_Custom_R1:.*custom2/m # custom2 export set to no + expect(content).not_to match /SMD_Custom_R1:.*custom3/m # custom3 export set to no + end + end + + context 'config wrong type' do + before(:all) do + @test = Test.new("custom_export_invalid_type") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomExport_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file has invalid type for export' + end + end + + context 'config with invalid value' do + before(:all) do + @test = Test.new("custom_export_invalid_value") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomExport_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file has invalid value nope for export' + end + end + + end +end diff --git a/dox_trace/spec/custom_name_spec.rb b/dox_trace/spec/custom_name_spec.rb new file mode 100644 index 0000000..b242db5 --- /dev/null +++ b/dox_trace/spec/custom_name_spec.rb @@ -0,0 +1,64 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute name" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_name") + @test.run + end + + it 'shall be available in RST files for directives', doc_refs: ['DoxTrace_CustomName_Available'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("custom_name", "index.html") + + expect(data.value("SWA_Custom_Set", "custom")).to eq "123" + end + end + + context 'config with conflicting name' do + before(:all) do + @test = Test.new("custom_name_invalid_exists") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomName_Conflict'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute review_status in config file already exists' + end + end + + context 'config with reserved name text' do + before(:all) do + @test = Test.new("custom_name_invalid_text") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomName_Conflict'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute text in config file already exists' + end + end + + context 'config with invalid type' do + before(:all) do + @test = Test.new("custom_name_invalid_type") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomGeneral_Config'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Names of custom attributes in config file must be strings' + end + end + + context 'config invalid dictionary' do + before(:all) do + @test = Test.new("custom_name_invalid_value") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomGeneral_Config'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file has wrong type' + end + end + + end +end diff --git a/dox_trace/spec/custom_type_spec.rb b/dox_trace/spec/custom_type_spec.rb new file mode 100644 index 0000000..3fe8f3c --- /dev/null +++ b/dox_trace/spec/custom_type_spec.rb @@ -0,0 +1,67 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The custom attribute type" do + context 'with valid configuration' do + before(:all) do + @test = Test.new("custom_type") + @test.run + end + + it 'shall be available in RST files for directives', doc_refs: ['DoxTrace_CustomTypes_Syntax', 'DoxTrace_CustomTypes_Text', 'DoxTrace_CustomTypes_Enum', 'DoxTrace_CustomTypes_Refs'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("custom_type", "index.html") + + # empty text, enum, refs rendered as "-" + expect(data.value("SMD_Custom_R1", "custom_complex_text")).to eq "-" + expect(data.value("SMD_Custom_R1", "custom2")).to eq "-" + expect(data.value("SMD_Custom_R1", "custom3")).to eq "-" + + expect(data.value("SWA_Custom_S1", "custom_complex_text")).to eq "1" + expect(data.value("SWA_Custom_S1", "custom2")).to eq "2" + expect(data.value("SWA_Custom_S1", "custom3")).to eq "#smd_custom_r1" + + expect(data.value("SWA_Custom_S2", "custom_complex_text")).to match /

bold<\/strong><\/p>.*

  • bullet1<\/p><\/li>.*not_bold/m + expect(data.value("SWA_Custom_S2", "custom2")).to eq "2, 3" + expect(data.value("SWA_Custom_S2", "custom3")).to eq "#smd_custom_r1, #swa_custom_r2, #custom-attr" + + expect(data.value("SWA_Custom_S3", "custom3", true)).to eq "SMD_Custom_R1" + expect(data.value("SWA_Custom_S4", "custom3", true)).to eq "Custom Attributes" + end + end + + context 'config with missing value' do + before(:all) do + @test = Test.new("custom_type_invalid_missing") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomTypes_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must have a valid type' + end + end + + context 'config with invalid type' do + before(:all) do + @test = Test.new("custom_type_invalid_type") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomTypes_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file must have a valid type' + end + end + + context 'config with invalid value' do + before(:all) do + @test = Test.new("custom_type_invalid_value") + @test.run + end + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_CustomTypes_Syntax'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'Custom attribute custom in config file has invalid type nope' + end + end + + end +end diff --git a/dox_trace/spec/derived_change_request_spec.rb b/dox_trace/spec/derived_change_request_spec.rb new file mode 100644 index 0000000..208943b --- /dev/null +++ b/dox_trace/spec/derived_change_request_spec.rb @@ -0,0 +1,32 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Derived Change Request" do + context 'for specifications' do + before(:all) do + @test = Test.new("derived_change_request") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_DerivedChangeRequest'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("derived_change_request", "index.html") + + expect(data.value("SRS_Requirement_Shown", "derived_change_request")).to eq "-" + expect(data.value("SWA_Spec_Shown", "derived_change_request")).to eq "-" + expect(data.value("SMD_Unit_Shown", "derived_change_request")).to eq "-" + expect(data.value("SWA_Interface_Shown", "derived_change_request")).to eq "-" + expect(data.value("SRS_Srs_Shown", "derived_change_request")).to eq "-" + expect(data.exist?("InputRequirement_NotShown", "derived_change_request")).to be false + expect(data.exist?("InputInformation_NotShown", "derived_change_request")).to be false + expect(data.exist?("SRS_Information_NotShown", "derived_change_request")).to be false + expect(data.exist?("SWA_Mod_NotShown", "derived_change_request")).to be false + + expect(data.value("SRS_Requirement_child", "derived_change_request")).to eq ["H", "J", "I", "K", "L"].sort.join(", ") + expect(data.value("SWA_Spec_ignoreBackRefs", "derived_change_request")).to eq "-" + expect(data.value("SWA_Spec_unique", "derived_change_request")).to eq ["A", "B"].sort.join(", ") + expect(data.value("SWA_Spec_multi", "derived_change_request")).to eq "X
    Y, X" + end + end + end +end diff --git a/dox_trace/spec/derived_feature_spec.rb b/dox_trace/spec/derived_feature_spec.rb new file mode 100644 index 0000000..8faeaab --- /dev/null +++ b/dox_trace/spec/derived_feature_spec.rb @@ -0,0 +1,32 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Derived Feature" do + context 'for specifications' do + before(:all) do + @test = Test.new("derived_feature") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_DerivedFeature'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("derived_feature", "index.html") + + expect(data.value("SRS_Requirement_Shown", "derived_feature")).to eq "-" + expect(data.value("SWA_Spec_Shown", "derived_feature")).to eq "-" + expect(data.value("SMD_Unit_Shown", "derived_feature")).to eq "-" + expect(data.value("SWA_Interface_Shown", "derived_feature")).to eq "-" + expect(data.value("SRS_Srs_Shown", "derived_feature")).to eq "-" + expect(data.exist?("InputRequirement_NotShown", "derived_feature")).to be false + expect(data.exist?("InputInformation_NotShown", "derived_feature")).to be false + expect(data.exist?("SRS_Information_NotShown", "derived_feature")).to be false + expect(data.exist?("SWA_Mod_NotShown", "derived_feature")).to be false + + expect(data.value("SRS_Requirement_child", "derived_feature")).to eq ["H", "J", "I", "K", "L"].sort.join(", ") + expect(data.value("SWA_Spec_ignoreBackRefs", "derived_feature")).to eq "-" + expect(data.value("SWA_Spec_unique", "derived_feature")).to eq ["A", "B"].sort.join(", ") + expect(data.value("SWA_Spec_multi", "derived_feature")).to eq "X
    Y, X" + end + end + end +end diff --git a/dox_trace/spec/developer_spec.rb b/dox_trace/spec/developer_spec.rb new file mode 100644 index 0000000..b8119e4 --- /dev/null +++ b/dox_trace/spec/developer_spec.rb @@ -0,0 +1,73 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute developer" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("developer") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Developer', 'DoxTrace_HTML_Developer'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("developer", "index.html") + + expect(data.value("SRS_Requirement_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("InputRequirement_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("SRS_Srs_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("SWA_Spec_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("SMD_Unit_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("SWA_Interface_DeveloperXY", "developer")).to eq 'XY' + expect(data.value("SWA_Mod_DeveloperXY", "developer")).to eq 'XY' + + expect(data.value("SRS_Requirement_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("InputRequirement_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("SRS_Srs_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("SWA_Spec_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("SMD_Unit_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("SWA_Interface_DeveloperDefault", "developer")).to eq '[missing]' + expect(data.value("SWA_Mod_DeveloperDefault", "developer")).to eq '[missing]' + + expect(data.value("SRS_Srs_DeveloperDefaultStruck", "developer")).to eq '-' + expect(data.value("SRS_Requirement_DeveloperDefaultStruck", "developer")).to eq '-' + expect(data.value("InputRequirement_DeveloperDefaultStruck", "developer")).to eq '-' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Developer', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/developer/export_root/srs/index.dim"] + + expect(srs["SRS_Srs_DeveloperXY"]["developer"]).to eq 'XY' + expect(srs["SRS_Srs_DeveloperDefault"]["developer"]).to eq '' + expect(srs["SRS_Srs_DeveloperDefaultStruck"]["developer"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/developer/export_root/swa/index.dim"] + + expect(swa["SWA_Spec_DeveloperXY"]["developer"]).to eq 'XY' + expect(swa["SWA_Interface_DeveloperXY"]["developer"]).to eq 'XY' + expect(swa["SWA_Mod_DeveloperXY"]["developer"]).to eq 'XY' + + expect(swa["SWA_Spec_DeveloperDefault"]["developer"]).to eq '' + expect(swa["SWA_Interface_DeveloperDefault"]["developer"]).to eq '' + expect(swa["SWA_Mod_DeveloperDefault"]["developer"]).to eq '' + + smd = @test.dim_original_data["spec/test_input/developer/export_root/smd/index.dim"] + + expect(smd["SMD_Unit_DeveloperXY"]["developer"]).to eq 'XY' + expect(smd["SMD_Unit_DeveloperDefault"]["developer"]).to eq '' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("developer_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Developer'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "developer"' + end + end + end +end diff --git a/dox_trace/spec/directives_spec.rb b/dox_trace/spec/directives_spec.rb new file mode 100644 index 0000000..7257072 --- /dev/null +++ b/dox_trace/spec/directives_spec.rb @@ -0,0 +1,61 @@ +require_relative 'framework/helper' + +module Sphinx + describe "dox_trace" do + + context 'shall provide' do + before(:all) do + @test = Test.new("directives_valid") + @test.run + end + it 'the directives requirement, information, srs, spec, unit and interface', doc_refs: ['DoxTrace_Syntax_Types'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("directives_valid", "index.html") + + expect(data.exist?("SRS_Requirement_Type", "status")).to be true + expect(data.exist?("SRS_Information_Type", "status")).to be true + expect(data.exist?("SRS_Srs_Type", "status")).to be true + expect(data.exist?("SWA_Spec_Type", "status")).to be true + expect(data.exist?("SMD_Unit_Type", "status")).to be true + expect(data.exist?("SMD_Unit_Type", "status")).to be true + expect(data.exist?("SWA_Mod_Type", "status")).to be true + end + + it 'optional attributes and content for the directives', doc_refs: ['DoxTrace_Syntax_Structure'] do + data = HtmlData.new("directives_valid", "index.html") + + expect(data.value("SWA_Spec_Type", "status")).to eq "draft" + expect(data.value("SWA_Spec_Attribute", "status")).to eq "valid" + end + + it 'a mandatory ID argument for the directives', doc_refs: ['DoxTrace_Syntax_Structure'] do + data = HtmlData.new("directives_valid", "index.html") + + expect(data.value("SWA_Spec_Type", "content")).to eq "[missing]" + expect(data.value("SWA_Spec_Content", "content")).to include "Some content." + end + end + + context 'shall abort the build with an appropriate error message' do + before(:all) do + @test = Test.new("directives_no_id") + @test.run + end + it 'if the ID argument for a directive is missing', doc_refs: ['DoxTrace_Syntax_Structure'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include '1 argument(s) required, 0 supplied.' + end + end + + context 'shall abort the build with appropriate error message' do + before(:all) do + @test = Test.new("directives_no_empty_line") + @test.run + end + it 'if an empty line is missing before the content', doc_refs: ['DoxTrace_Syntax_Structure'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'invalid option block' + end + end + end +end diff --git a/dox_trace/spec/downstream_references_spec.rb b/dox_trace/spec/downstream_references_spec.rb new file mode 100644 index 0000000..bebda51 --- /dev/null +++ b/dox_trace/spec/downstream_references_spec.rb @@ -0,0 +1,66 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Downstream References" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("refs") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Refs', 'DoxTrace_HTML_DownstreamRefs'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("refs", "index.html") + + expect(data.value("SRS_Requirement_RefsSet", "Downstream References")).to eq '#smd_unit_refsset, #srs_requirement_refsdefault' + expect(data.value("SRS_Information_RefsSet", "Downstream References")).to eq '#srs_information_refsdefault' + expect(data.value("InputRequirement_RefsSet", "Downstream References")).to eq '#inputrequirement_refsdefault' + expect(data.value("InputInformation_RefsSet", "Downstream References")).to eq '#inputinformation_refsdefault' + expect(data.value("SRS_Srs_RefsSet", "Downstream References")).to eq '#smd_unit_refsset, #srs_srs_refsdefault' + expect(data.value("SWA_Spec_RefsSet", "Downstream References")).to eq '#swa_spec_refsdefault' + expect(data.value("SMD_Unit_RefsSet", "Downstream References")).to eq '#smd_unit_refsdefault' + expect(data.value("SWA_Interface_RefsSet", "Downstream References")).to eq '#smd_unit_refsset, #swa_interface_refsdefault' + expect(data.value("SMD_Interface_RefsSet", "Downstream References")).to eq '#smd_unit_refsset' + + expect(data.value("SRS_Requirement_RefsDefault", "Downstream References")).to eq '[missing]' + expect(data.value("SRS_Information_RefsDefault", "Downstream References")).to eq '-' + expect(data.value("InputRequirement_RefsDefault", "Downstream References")).to eq '[missing]' + expect(data.value("InputInformation_RefsDefault", "Downstream References")).to eq '-' + expect(data.value("SRS_Srs_RefsDefault", "Downstream References")).to eq '[missing]' + expect(data.value("SWA_Spec_RefsDefault", "Downstream References")).to eq '[missing]' + expect(data.value("SMD_Unit_RefsDefault", "Downstream References")).to eq '-' + expect(data.value("SWA_Interface_RefsDefault", "Downstream References")).to eq '[missing]' + expect(data.value("SMD_Interface_RefsDefault", "Downstream References")).to eq '-' + + expect(data.value("SWA_Spec_TagsCovered", "Downstream References")).to eq '-' + expect(data.value("SWA_Spec_StatusInvalid", "Downstream References")).to eq '-' + + expect(data.value("SWA_Spec_RoundTrip", "Downstream References")).to eq '#smd_spec_roundtrip' + expect(data.value("SMD_Spec_RoundTrip", "Downstream References")).to eq '[missing]' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Refs', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/refs/export_root/srs/index.dim"] + expect(srs["SRS_Srs_RefsSet"]["refs"]).to eq 'SRS_Srs_RefsDefault, SMD_Unit_RefsSet' + expect(srs["SRS_Srs_RefsDefault"]["refs"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/refs/export_root/swa/index.dim"] + expect(swa["SWA_Spec_RefsSet"]["refs"]).to eq 'SWA_Spec_RefsDefault' + expect(swa["SWA_Interface_RefsSet"]["refs"]).to eq 'SWA_Interface_RefsDefault, SMD_Unit_RefsSet' + expect(swa["SWA_Spec_RefsDefault"]["refs"]).to eq '' + expect(swa["SWA_Interface_RefsDefault"]["refs"]).to eq '' + expect(swa["SWA_Spec_TagsCovered"]["refs"]).to eq '' + expect(swa["SWA_Spec_StatusInvalid"]["refs"]).to eq '' + expect(swa["SWA_Spec_RoundTrip"]["refs"]).to eq 'SMD_Spec_RoundTrip' + + smd = @test.dim_original_data["spec/test_input/refs/export_root/smd/index.dim"] + expect(smd["SMD_Unit_RefsSet"]["refs"]).to eq 'SMD_Unit_RefsDefault' + expect(smd["SMD_Interface_RefsSet"]["refs"]).to eq 'SMD_Unit_RefsSet' + expect(smd["SMD_Unit_RefsDefault"]["refs"]).to eq '' + expect(smd["SMD_Interface_RefsDefault"]["refs"]).to eq '' + expect(smd["SMD_Spec_RoundTrip"]["refs"]).to eq 'SWA_Spec_RoundTrip' + end + end + + end +end diff --git a/dox_trace/spec/enclosed_spec.rb b/dox_trace/spec/enclosed_spec.rb new file mode 100644 index 0000000..355270d --- /dev/null +++ b/dox_trace/spec/enclosed_spec.rb @@ -0,0 +1,35 @@ + require_relative 'framework/helper' + +module Sphinx + describe "The directive enclosed" do + + context 'shall copy files to build folder' do + before(:all) do + @test = Test.new("enclosed") + @test.run + end + + it 'listed in the content of the directive', doc_refs: [ 'DoxTrace_HTML_EnclosedDirective'] do + expect(@test.exit_code).to be == 0 + + expect(File.exist?("spec/test_input/enclosed/build/html/a.txt")).to be true + expect(File.exist?("spec/test_input/enclosed/build/html/b/b.txt")).to be true + expect(File.exist?("spec/test_input/enclosed/build/html/c.txt")).to be true + end + end + + context 'shall warn if a file listed in the content of the directive' do + before(:all) do + @test = Test.new("enclosed_invalid") + @test.run + end + + it 'does not exist', doc_refs: [ 'DoxTrace_HTML_EnclosedDirective'] do + expect(@test.exit_code).to be > 0 + + expect(@test.test_stderr).to include 'index.rst:8: file "d.txt" does not exist' + end + end + + end +end diff --git a/dox_trace/spec/export_spec.rb b/dox_trace/spec/export_spec.rb new file mode 100644 index 0000000..a00c4d1 --- /dev/null +++ b/dox_trace/spec/export_spec.rb @@ -0,0 +1,155 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The export to Dim format" do + context 'with a valid dox_trace_dim_root configuration' do + before do + FileUtils.mkdir_p("spec/test_input/export/export_root/srs") + FileUtils.mkdir_p("spec/test_input/export/export_root/swa") + FileUtils.mkdir_p("spec/test_input/export/export_root/smd/dummy") + FileUtils.touch("spec/test_input/export/export_root/srs/dummy.dim") + FileUtils.touch("spec/test_input/export/export_root/swa/dummy.dim") + FileUtils.touch("spec/test_input/export/export_root/smd/dummy/dummy.dim") + @test = Test.new("export") + @test.run + end + + it 'shall contain srs, spec, unit, interface, mod with their IDs', doc_refs: ['DoxTrace_Export_Config', 'DoxTrace_Export_IDs'] do + expect(@test.exit_code).to be == 0 + srs = @test.dim_original_data["spec/test_input/export/export_root/srs/index.dim"] + expect(srs.include?"SRS_Srs_Type").to be true + expect(srs.include?"SRS_Requirement_Type").to be false + expect(srs.include?"SRS_Information_Type").to be false + expect(srs.include?"InputRequirement_Type").to be false + expect(srs.include?"InputInformation_Type").to be false + expect(srs.include?"SWA_Spec_Type").to be false + expect(srs.include?"SWA_Interface_Type").to be false + expect(srs.include?"SWA_Mod_Type").to be false + expect(srs.include?"SMD_Unit_Type").to be false + + swa = @test.dim_original_data["spec/test_input/export/export_root/swa/index.dim"] + expect(swa.include?"SRS_Srs_Type").to be false + expect(swa.include?"SRS_Requirement_Type").to be false + expect(swa.include?"SRS_Information_Type").to be false + expect(swa.include?"InputRequirement_Type").to be false + expect(swa.include?"InputInformation_Type").to be false + expect(swa.include?"SWA_Spec_Type").to be true + expect(swa.include?"SWA_Interface_Type").to be true + expect(swa.include?"SWA_Mod_Type").to be true + expect(swa.include?"SMD_Unit_Type").to be false + + smd = @test.dim_original_data["spec/test_input/export/export_root/smd/index.dim"] + expect(smd.include?"SRS_Srs_Type").to be false + expect(smd.include?"SRS_Requirement_Type").to be false + expect(smd.include?"SRS_Information_Type").to be false + expect(smd.include?"InputRequirement_Type").to be false + expect(smd.include?"InputInformation_Type").to be false + expect(smd.include?"SMD_Unit_Type").to be true + expect(smd.include?"SWA_Spec_Type").to be false + expect(smd.include?"SWA_Interface_Type").to be false + expect(smd.include?"SWA_Mod_Type").to be false + end + + it 'shall create the same folder and filename structure as the according RST files', + doc_refs: ['DoxTrace_Export_Filenames'] do + data = @test.dim_original_data + + expect(data.include?"spec/test_input/export/export_root/srs/index.dim").to be true + expect(data.include?"spec/test_input/export/export_root/srs/subfolder/b.dim").to be false + expect(data.include?"spec/test_input/export/export_root/srs/subfolder/a.dim").to be false + expect(data.include?"spec/test_input/export/export_root/srs/subfolder/b/c.dim").to be false + expect(data.include?"spec/test_input/export/export_root/srs/subfolder/b/d.dim").to be false + + expect(data.include?"spec/test_input/export/export_root/swa/index.dim").to be true + expect(data.include?"spec/test_input/export/export_root/swa/subfolder/a.dim").to be true + expect(data.include?"spec/test_input/export/export_root/swa/subfolder/b.dim").to be true + expect(data.include?"spec/test_input/export/export_root/swa/subfolder/b/c.dim").to be true + expect(data.include?"spec/test_input/export/export_root/swa/subfolder/b/d.dim").to be false + + expect(data.include?"spec/test_input/export/export_root/smd/index.dim").to be true + expect(data.include?"spec/test_input/export/export_root/smd/subfolder/b.dim").to be true + expect(data.include?"spec/test_input/export/export_root/smd/subfolder/a.dim").to be true + expect(data.include?"spec/test_input/export/export_root/smd/subfolder/b/c.dim").to be true + expect(data.include?"spec/test_input/export/export_root/smd/subfolder/b/d.dim").to be false + end + + it 'shall cleanup the output folder before writing the RST files for srs, swa and smd', + doc_refs: ['DoxTrace_Export_Delete'] do + + expect(File.exist?("spec/test_input/export/export_root/srs/dummy.dim")).to be false + expect(File.exist?("spec/test_input/export/export_root/swa/dummy.dim")).to be false + expect(File.exist?("spec/test_input/export/export_root/smd/dummy/dummy.dim")).to be false + FileUtils.rm_f("spec/test_input/export/export_root/srs/dummy.dim") + FileUtils.rm_f("spec/test_input/export/export_root/swa/dummy.dim") + FileUtils.rm_rf("spec/test_input/export/export_root/smd/dummy") + end + + it 'shall include the correct module names', doc_refs: ['DoxTrace_Export_ModuleName'] do + data = @test.dim_original_data + + expect(data["spec/test_input/export/export_root/swa/index.dim"]["module"]).to eq "SWA_Spec" + expect(data["spec/test_input/export/export_root/swa/subfolder/b.dim"]["module"]).to eq "SWA_ModB" + expect(data["spec/test_input/export/export_root/smd/subfolder/a.dim"]["module"]).to eq "SMD_ModA" + expect(data["spec/test_input/export/export_root/smd/subfolder/b/c.dim"]["module"]).to eq "SMD_ModC" + + expect(data["spec/test_input/export/export_root/swa/subfolder/b.dim"]).to have_key("SWA_ModB_2") + expect(data["spec/test_input/export/export_root/smd/subfolder/b.dim"]).to have_key("SMD_ModB_1") + expect(data["spec/test_input/export/export_root/swa/subfolder/a.dim"]).to have_key("SWA_ModA_2") + expect(data["spec/test_input/export/export_root/smd/subfolder/a.dim"]).to have_key("SMD_ModA_1") + expect(data["spec/test_input/export/export_root/swa/subfolder/b/c.dim"]).to have_key("SWA_ModC_2") + expect(data["spec/test_input/export/export_root/smd/subfolder/b/c.dim"]).to have_key("SMD_ModC_1") + end + end + + context 'with only swa and smd' do + before do + FileUtils.mkdir_p("spec/test_input/export_no_srs/export_root/srs") + FileUtils.mkdir_p("spec/test_input/export_no_srs/export_root/swa") + FileUtils.mkdir_p("spec/test_input/export_no_srs/export_root/smd/dummy") + FileUtils.touch("spec/test_input/export_no_srs/export_root/srs/dummy.dim") + FileUtils.touch("spec/test_input/export_no_srs/export_root/swa/dummy.dim") + FileUtils.touch("spec/test_input/export_no_srs/export_root/smd/dummy/dummy.dim") + @test = Test.new("export_no_srs") + @test.run + end + + it 'shall cleanup the output folder before writing the RST files for swa and smd, but not srs', + doc_refs: ['DoxTrace_Export_Delete'] do + + expect(File.exist?("spec/test_input/export_no_srs/export_root/srs/dummy.dim")).to be true + expect(File.exist?("spec/test_input/export_no_srs/export_root/swa/dummy.dim")).to be false + expect(File.exist?("spec/test_input/export_no_srs/export_root/smd/dummy/dummy.dim")).to be false + FileUtils.rm_rf("spec/test_input/export_no_srs/export_root/srs") + FileUtils.rm_f("spec/test_input/export_no_srs/export_root/swa/dummy.dim") + FileUtils.rm_rf("spec/test_input/export_no_srs/export_root/smd/dummy") + end + end + + context 'without a valid dox_trace_dim_root configuration' do + before do + @test = Test.new("export_no_config") + @test.run + end + + it 'shall be skipped and not error returned', doc_refs: ['DoxTrace_Export_Config'] do + expect(@test.exit_code).to be == 0 + expect(File.exist?("#{$test_input_dir}/export_no_config/export_root")).to be false + expect(@test.test_stderr).not_to include 'writing Dim files' + end + end + + context 'with an invalid dox_trace_dim_root configuration' do + before do + @test = Test.new("export_invalid_config") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Export_Config'] do + expect(@test.exit_code).to be > 0 + expect(File.exist?("#{$test_input_dir}/export_invalid_config/export_root")).to be false + expect(@test.test_stderr).not_to include 'writing Dim files' + expect(@test.test_stderr).to include 'exception' + end + end + end +end diff --git a/dox_trace/spec/feature_spec.rb b/dox_trace/spec/feature_spec.rb new file mode 100644 index 0000000..f525d80 --- /dev/null +++ b/dox_trace/spec/feature_spec.rb @@ -0,0 +1,102 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute feature" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("feature") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Feature', 'DoxTrace_HTML_Feature'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("feature", "index.html") + + expect(data.exist?("SRS_Requirement_FeatureSet", "feature")).to be false + expect(data.value("InputRequirement_FeatureSet", "feature")).to eq 'Dd' + + expect(data.exist?("SRS_Requirement_FeatureDefault", "feature")).to be false + expect(data.value("InputRequirement_FeatureDefault", "feature")).to eq '-' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("feature_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("feature_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("feature_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("feature_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("feature_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("feature_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Feature'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "feature"' + end + end + + end +end diff --git a/dox_trace/spec/framework/helper.rb b/dox_trace/spec/framework/helper.rb new file mode 100644 index 0000000..873b1b7 --- /dev/null +++ b/dox_trace/spec/framework/helper.rb @@ -0,0 +1,337 @@ + +require 'json' +require 'fileutils' +require 'timeout' + +require_relative '../../../dim/lib/dim/loader.rb' + +$test_input_dir = "spec/test_input" + +module Sphinx + class Test + attr_reader :test_stdout, :test_stderr, :exit_code + + def initialize(testName, options = "") + @testName = testName + @options = options + + @test_stdout = "" + @test_stderr = "" + @exit_code = 255 + end + + def closeFd(fd) + begin + fd.close + rescue Exception + end + end + + def killProcess(pid) + begin + 5.times do |i| + Process.kill("TERM", pid) + sleep(1) + break unless Process.waitpid(pid, Process::WNOHANG).nil? # nil = process still running + end + rescue Exception + end + begin + Process.kill("KILL",pid) + rescue Exception + end + end + + def run() + begin + rd_out, wr_out = IO.pipe + rd_err, wr_err = IO.pipe + pid = nil + Timeout::timeout(60) do + sphinxCoverage = ENV['sphinx_coverage'] || '' + pid = spawn("make html -C #{$test_input_dir}/#{@testName} #{sphinxCoverage} #{@options}", :err=>wr_err, :out=>wr_out) + closeFd(wr_out) + closeFd(wr_err) + pid, status = Process.wait2 pid + if status.nil? + puts "Process returned with unknown exit status" + return + end + @test_stdout = rd_out.read() + @test_stderr = rd_err.read() + @exit_code = status.exitstatus + end + rescue Timeout::Error + closeFd(rd_out) + closeFd(rd_err) + killProcess(pid) + end + end + + def dim_original_data() + configSrc = "#{$test_input_dir}/config.dim" + configDst = "#{$test_input_dir}/#{@testName}/export_root/config.dim" + FileUtils.cp(configSrc, configDst) + + attrSrc = "#{$test_input_dir}/#{@testName}/attributes.dim" + attrDst = "#{$test_input_dir}/#{@testName}/export_root/attributes.dim" + if File.exist?(attrSrc) + FileUtils.cp(attrSrc, attrDst) + content = File.read(configDst) + content << "Attributes: attributes.dim\n" + File.write(configDst, content) + end + + loader = Dim::Loader.new + loader.load(file: configDst) + return loader.original_data + end + end +end + +class HtmlData + attr_accessor :html + + def initialize(testName, relPath) + @html = File.read("spec/test_input/#{testName}/build/html/#{relPath}") + end + + def format_attribute(attribute) + if attribute == "content" + attribute = "

    " + else + attribute = attribute.gsub("_", " ").split.map(&:capitalize).join(' ') + attribute = "#{attribute}: " + end + return attribute + end + + def getSpecInternal(id) + + pos_id_start = @html.index("id=\"#{id.downcase}\"") + return nil if !pos_id_start + pos_id_end = @html.index("", pos_id_start) + return nil if !pos_id_end + + return @html[pos_id_start..pos_id_end] + end + + def getTableInternal(id, attribute) + attribute = format_attribute(attribute) + + pos_id_start = @html.index("id=\"#{id.downcase}\"") + return nil if !pos_id_start + pos_id_end = @html.index("", pos_id_start) + + pos_attribute = @html.index(attribute, pos_id_start) + return nil if !pos_id_end || !pos_attribute || pos_attribute > pos_id_end + return @html[pos_attribute+attribute.length..pos_id_end] + end + + def value(id, attribute, link_text = false) + table = getTableInternal(id, attribute) + return nil if !table + + if attribute.downcase == "content" + res = table.match(/(.*)<\/p><\/td><\/tr>\s*")[0].split("

    ")[0] + line = "" if !line + + if ["SRS_Requirement_VcSet", "SRS_Srs_VcSet"].include?(id) + res = line.scan(/(.*)(.*)<\/span>/) + return res.join() if !res.empty? + end + + if link_text + res = line.scan(/">([^>]+)<\/span><\/a>/) + else + res = line.scan(/href="([^"]+)/) + end + return res.join(", ") if !res.empty? + + res = table.match(/\A\s*

    (.*)<\/div>/) + return res[1].strip if res + + # attributes in this test usually start with: + # - start of line + # - + # - + # attributes in this test usually end with: + # - + # -
    EOL + # - | + # -
    + # - ").first + end + + def red?(id, attribute) + table = getTableInternal(id, attribute) + return nil if !table + return table.match(/\A\s*(<\/span>)*()*/m) != nil + end + + def empty_class?(id, attribute) + formatted_attribute = format_attribute(attribute) + spec = getSpecInternal(id) + return nil if !spec + return spec.match(/dox-trace-attribute-empty">[ \|]*#{formatted_attribute}/) != nil + end + + def missing_class?(id, attribute) + formatted_attribute = format_attribute(attribute) + spec = getSpecInternal(id) + return nil if !spec + return spec.match(/dox-trace-attribute-missing">[ \|]*#{formatted_attribute}/m) != nil + end + + def struck?(id) + pos_id_start = @html.index("id=\"#{id.downcase}\"") + return nil if !pos_id_start + pos_id_end = @html.index("", pos_id_start) + return @html[pos_id_end+8..-1].match(/\A\s*
    /m) != nil + end + + # traceability report tables + + def tr_getSection(name) + return @html.match(/#{name}(.*?)\n(.*?)\n<\/section>/m)[2] + end + + def tr_nodata?(name) + section = tr_getSection(name) + return section.include?("No data yet") && !section.include?("table") + end + + def tr_desc(name) + section = tr_getSection(name) + line = section.split("\n", 2)[0] + return line.gsub('
    ', '|br|').gsub(/<\/*p>/, "") + end + + def tr_values(name) + section = tr_getSection(name) + body = section.split("")[1] + rows = body.split("

    (.*?)<\/p><\/th>/).map{|h| h[0]}.select{|a| !a.empty?} + mods = rows.map {|r| r.match(/"row-(even|odd)">(.*?)<\/td>/)[2].gsub("", "")} + values = body.scan(/(>(\d+)<\/a>|(0)<\/td>)/).map {|a| a[1].nil? ? a[2] : a[1] } + refs = body.scan(/^(.+?)<\/a><[\/brp]+>$/).flatten + + result = {} + total_v = 0 + mods.each_with_index do |m, m_ind| + result[m] = {} + attr_values.each_with_index do |a, a_ind| + v = Integer(values[m_ind * attr_values.length + a_ind]) + result[m][a] = refs[total_v, v] + total_v += v + end + end + return result + end + + def tr_list(name) + section = tr_getSection(name) + body = section.split("")[1] + rows = body.split("

    (.*?)<\/p><\/th>/).map{|h| h[0]}.select{|a| !a.empty?} + + result = [] + rows.each do |r| + values = [] + r.split("")[1..-1].each do |col| + col.gsub!(",
    ", ", ") + col.gsub!("", "") + refs = col.scan(/(">|)(.+?)(<\/span>|<\/a>)/) + if refs.length > 0 + v = refs.map{|r| r[1]}.join(", ") + # needed if refs and sources/locations are specified + additionals = col.match(/<\/span>([^<>]+?)<\/td>/) + v << additionals[1] if additionals + values << v + else + para = col.match(/

    (.+?)<\/p>/) + if para + values << para[1] + else + values << col.match(/^(.+?)<\/td>/)[1] + end + end + end + entry = {} + attr_values.each_with_index do |a, ind| + entry[a] = values[ind] + end + result << entry + end + return result + end +end + +class Summary + def dump_summary(res) + table = {"" => []} + res.examples.each do |e| + e.metadata.fetch(:doc_refs, [""]).each do |id| + next if id == "IGNORE" + table[id] ||= [] + table[id] << { + "location" => e.location.gsub("./",""), + "description" => e.full_description, + } + end + end + folder = File.dirname(__FILE__) + "/../../documentation/source/pages/requirements-generated" + FileUtils.mkdir_p(folder) + File.write(folder + "/mapping.json", JSON.pretty_generate(table)) + end +end + +RSpec.configure do |config| + config.reporter.register_listener(Summary.new, :dump_summary) + config.before(:all) do |the_test| + $stdout.write "Testing #{the_test.class}:\n" + end + config.after(:all) do |the_test| + puts "\nDONE" + end + + config.after(:each) do |the_test| + if !the_test.instance_variable_get(:@exception).nil? + if the_test.example_group_instance.instance_variable_defined?("@test") + test = the_test.example_group_instance.instance_variable_get("@test") + puts test.test_stdout + puts test.test_stderr + end + end + end +end diff --git a/dox_trace/spec/framework/testmain.rb b/dox_trace/spec/framework/testmain.rb new file mode 100644 index 0000000..be61244 --- /dev/null +++ b/dox_trace/spec/framework/testmain.rb @@ -0,0 +1,29 @@ +require 'fileutils' + +STDOUT.sync = true + +puts "Deleting old test output" +Dir.glob("{spec/**/build,**/htmlcov,**/.coverage}").each do |f| + FileUtils.rm_rf(f) +end + +require 'rspec/core/rake_task' +SPEC_PATTERN ='spec/**/*_spec.rb' + +namespace :test do + desc "Run specs" + RSpec::Core::RakeTask.new() do |t, args| + t.pattern = SPEC_PATTERN + t.rspec_opts = "--dry-run" if $dry_run + end + + desc "Run specs with coverage" + task :coverage do + ENV['sphinx_coverage'] = "SPHINX_COVERAGE=1" + task('test:spec').invoke("coverage") + coverage_files = Dir.glob("spec/test_input/**/.coverage").join(" ") + system("coverage combine --keep #{coverage_files}") + system("coverage html") + system("coverage report") + end +end diff --git a/dox_trace/spec/general_spec.rb b/dox_trace/spec/general_spec.rb new file mode 100644 index 0000000..4bbb261 --- /dev/null +++ b/dox_trace/spec/general_spec.rb @@ -0,0 +1,93 @@ +require_relative 'framework/helper' + +module Sphinx + describe "dox_trace" do + + context 'in general' do + before(:all) do + @test = Test.new("general") + @test.run + end + + it 'shall create anchors for every specification', doc_refs: ['DoxTrace_Syntax_Anchor'] do + expect(@test.exit_code).to be == 0 # no invalid refs + data = HtmlData.new("general", "index.html") + + expect(data.html).to match /href="#srs_requirement_anchor"/ + expect(data.html).to match /href="#srs_information_anchor"/ + expect(data.html).to match /href="#srs_srs_anchor"/ + expect(data.html).to match /href="#swa_spec_anchor"/ + expect(data.html).to match /href="#smd_unit_anchor"/ + expect(data.html).to match /href="#swa_interface_anchor"/ + end + + it 'shall strip the attribute values', doc_refs: ['DoxTrace_Syntax_Stripped'] do + expect(@test.exit_code).to be == 0 # no error due to leading / trailing whitespaces + data = HtmlData.new("general", "index.html") + + expect(data.value("SWA_Spec_DoubleSingle", "status")).to eq "" + expect(data.value("SWA_Spec_SingleDouble", "status")).to eq "" + expect(data.value("SWA_Spec_Stripped", "status")).to eq "valid" + end + + it 'shall treat empty values as empty strings', doc_refs: ['DoxTrace_Syntax_Empty'] do + expect(@test.exit_code).to be == 0 # no error due to leading / trailing whitespaces + data = HtmlData.new("general", "index.html") + + # draft is default + expect(data.value("SWA_Spec_NotSpecified", "status")).to eq "draft" + expect(data.value("SWA_Spec_NoValue", "status")).to eq "" + expect(data.value("SWA_Spec_DoubleSingle", "status")).to eq "" + expect(data.value("SWA_Spec_SingleDouble", "status")).to eq "" + expect(data.value("SWA_Spec_Spaces", "status")).to eq "" + end + + it 'shall load multi-enum attributes correctly', doc_refs: ['DoxTrace_Syntax_Multi'] do + data = HtmlData.new("general", "index.html") + + expect(data.value("SMD_Unit_MultiStripAndUnique", "tags")).to eq "obd, swa, smd" + expect(data.value("SMD_Unit_MultiStripAndUnique", "verification_methods")).to eq "on_target, off_target, manual" + expect(data.value("SMD_Unit_MultiStripAndUnique", "sources")).to eq "conf.py, index.rst, Makefile" + expect(data.value("SMD_Unit_MultiStripAndUnique", "upstream references")).to eq "#srs_information_anchor, #srs_requirement_anchor" + expect(data.value("SMD_Unit_MultiStripAndUnique", "downstream references")).to eq "#smd_unit_anchor" + + # stripped to empty, defaults are used + expect(data.value("SMD_Unit_MultiEmpty", "tags")).to eq "-" + expect(data.value("SMD_Unit_MultiEmpty", "verification_methods")).to eq "off_target" + expect(data.value("SMD_Unit_MultiEmpty", "sources")).to eq "" + expect(data.value("SMD_Unit_MultiEmpty", "upstream references")).to eq "[missing]" + expect(data.value("SMD_Unit_MultiEmpty", "downstream references")).to eq "-" + end + + it 'shall load free-text attributes and the content correctly', doc_refs: ['DoxTrace_Syntax_FreeText'] do + data = HtmlData.new("general", "index.html") + + # take the strings as is - even if they would not be accepted by Dim + expect(data.value("SMD_Unit_Free", "verification_criteria")).to eq ",," + expect(data.value("SMD_Unit_Free", "status")).to eq ",," + expect(data.value("SMD_Unit_Free", "developer")).to eq ",," + expect(data.value("SMD_Unit_Free", "tester")).to eq ",," + expect(data.value("SMD_Unit_Free", "asil")).to eq ",," + expect(data.value("SMD_Unit_Free", "cal")).to eq ",," + expect(data.value("SMD_Unit_Free", "review_status")).to eq ",," + expect(data.value("Requirement_Free", "feature")).to eq ",," + expect(data.value("Requirement_Free", "change_request")).to eq ",," + expect(data.value("Requirement_Free", "comment")).to eq ",," + expect(data.value("Requirement_Free", "miscellaneous")).to eq ",," + expect(data.value("Requirement_Free", "content")).to match /#subheading.*highlight.*123/m + end + + it 'shall preserve newlines in attributes expect line ends with backslash', doc_refs: ['DoxTrace_Syntax_Newlines'] do + data = HtmlData.new("general", "index.html") + + expect(data.value("SRS_Requirement_NewLine1", "custom_complex_text")).to eq "No newline here" + expect(data.value("SRS_Requirement_NewLine2", "custom_complex_text")).to eq "No newline here" + expect(data.value("SRS_Requirement_NewLine3", "custom_complex_text")).to eq "No newline here" + expect(data.value("SRS_Requirement_NewLine4", "custom_complex_text")).to eq "No newline here" + expect(data.value("SRS_Requirement_NewLine5", "custom_complex_text")).to eq "No newline here" + expect(data.value("SRS_Requirement_NewLine6", "custom_complex_text")).to match /Has\S*\n\S*three\S*\n\S*lines/m + expect(data.value("SRS_Requirement_NewLine7", "custom_complex_text")).to match /Has\S*\n\S*two lines/m + end + end + end +end diff --git a/dox_trace/spec/html_spec.rb b/dox_trace/spec/html_spec.rb new file mode 100644 index 0000000..14c15bb --- /dev/null +++ b/dox_trace/spec/html_spec.rb @@ -0,0 +1,125 @@ +require_relative 'framework/helper' + +module Sphinx + describe "dox_trace" do + context 'HTML output' do + before(:all) do + @test = Test.new("html") + @test.run + end + + it 'shall support incremental build and enforce a rebuild if the extension version has changed', + doc_refs: ['DoxTrace_HTML_Incremental', 'DoxTrace_HTML_Version'] do + expect(@test.exit_code).to be == 0 + + expect(File.exist?("#{$test_input_dir}/html/build/html/subpage.html")).to be true + time1 = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + + # incremental build rewrites subpage due to changed configuration + sleep(2) + test2a = Test.new("html", "DOXTRACE_PROJECT_NAME=Abc") + test2a.run + time2a = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + expect(time1).not_to eq(time2a) + test2b = Test.new("html") + test2b.run + time2b = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + + # incremental build does not rewrite subpage because nothing has changed + sleep(2) + test3 = Test.new("html") + test3.run + time3 = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + expect(time2b).to eq(time3) + + # incremental build rewrites subpage due to changed extension version + sleep(2) + test4 = Test.new("html", "MANIPULATE_DOXTRACE_VERSION=1") + test4.run + time4 = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + expect(time3).not_to eq(time4) + + # incremental build does not rewrite subpage because only subpage2 was changed + sleep(2) + FileUtils.touch("#{$test_input_dir}/html/subpage2.rst") + test5 = Test.new("html", "MANIPULATE_DOXTRACE_VERSION=1") + test5.run + time5 = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + expect(time4).to eq(time5) + expect(test5.exit_code).to be == 0 + + # incremental build rewrites subpage because now subpage was changed + sleep(2) + FileUtils.touch("#{$test_input_dir}/html/subpage.rst") + test6 = Test.new("html", "MANIPULATE_DOXTRACE_VERSION=1") + test6.run + time6 = File.mtime("#{$test_input_dir}/html/build/html/subpage.html") + expect(time5).not_to eq(time6) + expect(test5.exit_code).to be == 0 + end + + it 'shall contain a table with attributes for every specification in correct design', + doc_refs: ['DoxTrace_HTML_Table', 'DoxTrace_HTML_Attributes', 'DoxTrace_HTML_Strike', 'DoxTrace_HTML_Background'] do + + data = HtmlData.new("html", "index.html") + expect(data.html.scan(/( \| )*#{a}:<\/strong> (-|\[missing\])/ + if ["Upstream Tags", "Upstream Cal", "Upstream Security", "Upstream Asil", "Derived", "References"].any? {|str| a.include?(str)} + # calculated attributes in grey + expect(data.html).to match(regex) + else + # no grey color means default = black + expect(data.html).not_to match(regex) + end + end + + expect(data.struck?("Requirement_Normal")).to be false + expect(data.struck?("Requirement_Invalid")).to be true + expect(data.struck?("Requirement_Rejected")).to be true + expect(data.struck?("Requirement_NotRelevant")).to be true + + # value and existence of content checked below + # row-even / row-odd are RTD theme defaults with white / grey background color + data.html.gsub!(//, "") + expect(data.html).not_to match(/row-even/) # content deleted above + expect(data.html).to match(/row-odd/) # only the other grey rows are still here + end + + it 'shall contain type and ID for every specification in correct design', doc_refs: ['DoxTrace_HTML_TypeID'] do + data = HtmlData.new("html", "index.html") + + type_id_str = ->(type, id) { + # highlight class = font type / background + # href = link to itself + /#{id}<\/span><\/a><\/code>/ + } + expect(data.html).to match(type_id_str.("requirement", "Requirement_Normal")) + expect(data.html).to match(type_id_str.("information", "Information_Normal")) + expect(data.html).to match(type_id_str.("srs", "SRS_Srs_Normal")) + expect(data.html).to match(type_id_str.("spec", "SWA_Spec_Normal")) + expect(data.html).to match(type_id_str.("unit", "SMD_Unit_Normal")) + expect(data.html).to match(type_id_str.("interface", "SWA_Interface_Normal")) + expect(data.html).to match(type_id_str.("mod", "SWA_Mod_Normal")) + + css = File.read("#{$test_input_dir}/html/build/html/_static/dox_trace.css") + expect(css).to match(/highlight-requirement.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-interface.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-srs.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-unit.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-spec.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-mod.*background: #FFFFFF.*color:#222222.*font-weight: bold/) + expect(css).to match(/highlight-information.*background: #FFFFFF.*color:#999999.*font-weight: bold/) + end + end + end +end diff --git a/dox_trace/spec/ignore_in_export_spec.rb b/dox_trace/spec/ignore_in_export_spec.rb new file mode 100644 index 0000000..48a7dd2 --- /dev/null +++ b/dox_trace/spec/ignore_in_export_spec.rb @@ -0,0 +1,25 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute ignore_in_export" do + context 'if set' do + + before(:all) do + @test = Test.new("ignore_in_export") + @test.run + end + + it 'shall disable the export of the particular specification', doc_refs: ['DoxTrace_Syntax_IgnoreInExport', 'DoxTrace_Export_IgnoreInExport'] do + expect(@test.dim_original_data).not_to have_key("spec/test_input/ignore_in_export/export_root/srs/index.dim") + expect(@test.dim_original_data).not_to have_key("spec/test_input/ignore_in_export/export_root/smd/index.dim") + expect(@test.dim_original_data).to have_key("spec/test_input/ignore_in_export/export_root/swa/index.dim") + + swa = @test.dim_original_data["spec/test_input/ignore_in_export/export_root/swa/index.dim"] + expect(swa).not_to have_key("SWA_Spec_Ignore") + expect(swa).not_to have_key("SWA_Interface_Ignore") + expect(swa).not_to have_key("SWA_Mod_Ignore") + expect(swa).to have_key("SWA_Interface_NotIgnore") + end + end + end +end diff --git a/dox_trace/spec/location_spec.rb b/dox_trace/spec/location_spec.rb new file mode 100644 index 0000000..bd4b8d9 --- /dev/null +++ b/dox_trace/spec/location_spec.rb @@ -0,0 +1,120 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute location" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("location") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Location', 'DoxTrace_HTML_Location'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("location", "subfolder/index.html") + + expect(data.value("SWA_Mod_Empty", "location")).to eq '[missing]' + expect(data.value("SWA_Mod_EmptyStruck", "location")).to eq '-' + + expect(data.value("SWA_Mod_NotExist", "location")).to eq 'modules/doesNotExist' + expect(data.value("SWA_Mod_NotExistStruck", "location")).to eq 'modules/doesNotExist' + + expect(data.value("SWA_Mod_Exist", "location")).to eq '../modules/driver/doc/index.html' + expect(data.value("SWA_Mod_Exist", "location", true)).to eq 'modules/driver' + end + + it 'shall not be exported', doc_refs: ['DoxTrace_Export_Location'] do + dim = File.read("#{$test_input_dir}/location/export_root/swa/subfolder/index.dim") + expect(dim).not_to match(/location/) + end + + it 'shall have correct color in HTML', doc_refs: ['DoxTrace_HTML_Location'] do + data = HtmlData.new("location", "subfolder/index.html") + + expect(data.red?("SWA_Mod_Empty", "location")).to be false + expect(data.red?("SWA_Mod_EmptyStruck", "location")).to be false + expect(data.red?("SWA_Mod_NotExist", "location")).to be true + expect(data.red?("SWA_Mod_NotExistStruck", "location")).to be false + expect(data.red?("SWA_Mod_Exist", "location")).to be false + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("location_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + context 'specified in an requirement directive' do + before(:all) do + @test = Test.new("location_requirement") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "requirement" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + context 'specified in an spec directive' do + before(:all) do + @test = Test.new("location_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("location_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + context 'specified in an unit directive' do + before(:all) do + @test = Test.new("location_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("location_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Location'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "location"' + end + end + + end +end diff --git a/dox_trace/spec/miscellaneous_spec.rb b/dox_trace/spec/miscellaneous_spec.rb new file mode 100644 index 0000000..393fd57 --- /dev/null +++ b/dox_trace/spec/miscellaneous_spec.rb @@ -0,0 +1,93 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute miscellaneous" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("miscellaneous") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Miscellaneous', 'DoxTrace_HTML_Miscellaneous'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("miscellaneous", "index.html") + + expect(data.exist?("SRS_Information_MiscellaneousSet", "miscellaneous")).to be false + expect(data.exist?("SRS_Requirement_MiscellaneousSet", "miscellaneous")).to be false + expect(data.value("InputInformation_MiscellaneousSet", "miscellaneous")).to eq 'Cc' + expect(data.value("InputRequirement_MiscellaneousSet", "miscellaneous")).to eq 'Dd' + + expect(data.exist?("SRS_Information_MiscellaneousDefault", "miscellaneous")).to be false + expect(data.exist?("SRS_Requirement_MiscellaneousDefault", "miscellaneous")).to be false + expect(data.value("InputInformation_MiscellaneousDefault", "miscellaneous")).to eq '-' + expect(data.value("InputRequirement_MiscellaneousDefault", "miscellaneous")).to eq '-' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("miscellaneous_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Miscellaneous'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "miscellaneous"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("miscellaneous_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Miscellaneous'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "miscellaneous"' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("miscellaneous_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Miscellaneous'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "miscellaneous"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("miscellaneous_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Miscellaneous'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "miscellaneous"' + end + end + + context 'specified in an srs directive' do + before(:all) do + @test = Test.new("miscellaneous_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Miscellaneous'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "miscellaneous"' + end + end + + end +end diff --git a/dox_trace/spec/parallel_spec.rb b/dox_trace/spec/parallel_spec.rb new file mode 100644 index 0000000..f2dd896 --- /dev/null +++ b/dox_trace/spec/parallel_spec.rb @@ -0,0 +1,47 @@ +require_relative 'framework/helper' +require 'fileutils' + +module Sphinx + describe "dox_trace shall support" do + context 'single-threaded build' do + before(:all) do + @test = Test.new("parallel") + @test.run + end + + it 'on all platforms', + doc_refs: ['DoxTrace_Build_Single'] do + expect(@test.exit_code).to be == 0 + data_main = HtmlData.new("parallel", "index.html") + data_subpage = HtmlData.new("parallel", "subpage1.html") + + expect(data_main.value("SWA_Spec_Main", "Downstream References")).to eq 'subpage1.html#swa_spec_subpage1, subpage2.html#swa_spec_subpage2' + expect(data_subpage.value("SWA_Spec_Subpage1", "Downstream References")).to eq 'subpage2.html#swa_spec_subpage2' + end + end + + context 'parallel build' do + before(:all) do + FileUtils.rm_rf("spec/test_input/parallel/build") + # MANIPULATE_DOXTRACE_PARALLEL=1 forces some code to be executed on non-posix platforms + # to get 100% code coverage. A real parallel-test is only done on posix platforms. + @test = Test.new("parallel", "SPHINXOPTS=\"-j auto\" MANIPULATE_DOXTRACE_PARALLEL=1") + @test.run + end + + it 'on all platforms', + doc_refs: ['DoxTrace_Build_Multi'] do + expect(@test.exit_code).to be == 0 + data_main = HtmlData.new("parallel", "index.html") + data_subpage = HtmlData.new("parallel", "subpage1.html") + dim_main = @test.dim_original_data["spec/test_input/parallel/export_root/swa/index.dim"] + + expect(data_main.value("SWA_Spec_Main", "Downstream References")).to eq 'subpage1.html#swa_spec_subpage1, subpage2.html#swa_spec_subpage2' + expect(data_subpage.value("SWA_Spec_Subpage1", "Downstream References")).to eq 'subpage2.html#swa_spec_subpage2' + + expect(dim_main["SWA_Spec_Main"]["tester"]).to eq 'Parallel = True' + end + end + + end +end diff --git a/dox_trace/spec/parent_asil_spec.rb b/dox_trace/spec/parent_asil_spec.rb new file mode 100644 index 0000000..1c895df --- /dev/null +++ b/dox_trace/spec/parent_asil_spec.rb @@ -0,0 +1,37 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Upstream Tags" do + context 'for specifications' do + before(:all) do + @test = Test.new("upstream_asil") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_UpstreamAsil'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("upstream_asil", "index.html") + + expect(data.value("SRS_Requirement_A", "upstream_asil")).to eq "-" + expect(data.value("SRS_Srs_A", "upstream_asil")).to eq "-" + expect(data.value("SRS_Information_B", "upstream_asil")).to eq "-" + expect(data.value("SWA_Spec_C", "upstream_asil")).to eq "-" + expect(data.value("SMD_Unit_D", "upstream_asil")).to eq "-" + expect(data.value("SWA_Interface_AA", "upstream_asil")).to eq "-" + expect(data.value("SWA_Mod_A", "upstream_asil")).to eq "-" + expect(data.exist?("InputRequirement_AB", "upstream_asil")).to be false + expect(data.exist?("InputInformation_AC", "upstream_asil")).to be false + + expect(data.value("SWA_Spec_AD", "upstream_asil")).to eq "-" + expect(data.value("SWA_Spec_BB", "upstream_asil")).to eq "-" + expect(data.value("SWA_Spec_BC", "upstream_asil")).to eq "ASIL_A(D)" + expect(data.value("SWA_Spec_BD", "upstream_asil")).to eq "ASIL_B(B)" + expect(data.value("SWA_Spec_child", "upstream_asil")).to eq ["ASIL_B(C)", "ASIL_B(D)"].sort.join(", ") + + expect(data.value("SMD_Spec_ignoreBackRefs", "upstream_asil")).to eq ["ASIL_A", "ASIL_C", "ASIL_D", "ASIL_A(A)", "ASIL_A(B)"].sort.join(", ") + + expect(data.value("SWA_Spec_unique", "upstream_asil")).to eq ["ASIL_A", "ASIL_C"].sort.join(", ") + end + end + end +end diff --git a/dox_trace/spec/parent_cal_spec.rb b/dox_trace/spec/parent_cal_spec.rb new file mode 100644 index 0000000..21d9383 --- /dev/null +++ b/dox_trace/spec/parent_cal_spec.rb @@ -0,0 +1,42 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Upstream Cal" do + context 'for specifications' do + before(:all) do + @test = Test.new("upstream_cal") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_UpstreamCal'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("upstream_cal", "index.html") + + expect(data.value("SRS_Requirement_Cal1", "upstream_cal")).to eq "-" + expect(data.value("SRS_Information_Qm", "upstream_cal")).to eq "-" + expect(data.value("SRS_Srs_Cal2", "upstream_cal")).to eq "-" + expect(data.value("SWA_Spec_notSet", "upstream_cal")).to eq "-" + expect(data.value("SMD_Unit_Cal3", "upstream_cal")).to eq "-" + expect(data.value("SWA_Interface_Qm", "upstream_cal")).to eq "-" + expect(data.value("SWA_Mod_Cal2", "upstream_cal")).to eq "-" + expect(data.exist?("InputRequirement_notSet", "upstream_cal")).to be false + expect(data.exist?("InputInformation_Cal1", "upstream_cal")).to be false + + expect(data.value("SWA_Spec_Cal1P1", "upstream_cal")).to eq "-" + expect(data.value("SWA_Spec_Cal1P2", "upstream_cal")).to eq "-" + expect(data.value("SWA_Spec_QmP", "upstream_cal")).to eq "CAL_1" + expect(data.value("SWA_Spec_notSetP", "upstream_cal")).to eq "CAL_1" + expect(data.value("SWA_Spec_child", "upstream_cal")).to eq ["QM", "not_set"].sort.join(", ") + + expect(data.value("SMD_Spec_ignoreBackRefs1", "upstream_cal")).to eq ["CAL_1", "CAL_2", "not_set"].sort.join(", ") + expect(data.value("SMD_Spec_ignoreBackRefs2", "upstream_cal")).to eq ["CAL_3", "QM", "not_set"].sort.join(", ") + expect(data.value("SMD_Spec_ignoreBackRefs3", "upstream_cal")).to eq "-" + + expect(data.value("SWA_Spec_unique", "upstream_cal")).to eq ["CAL_1", "CAL_2", "not_set"].sort.join(", ") + + expect(data.value("SWA_Spec_Cal", "upstream_cal")).to eq ["CAL_4", "QM"].sort.join(", ") + expect(data.exist?("SWA_Spec_Cal", "upstream_security")).to be false + end + end + end +end diff --git a/dox_trace/spec/parent_security_spec.rb b/dox_trace/spec/parent_security_spec.rb new file mode 100644 index 0000000..57a38cd --- /dev/null +++ b/dox_trace/spec/parent_security_spec.rb @@ -0,0 +1,42 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Upstream Security" do + context 'for specifications' do + before(:all) do + @test = Test.new("upstream_security") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_UpstreamSecurity'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("upstream_security", "index.html") + + expect(data.value("SRS_Requirement_yes", "upstream_security")).to eq "-" + expect(data.value("SRS_Information_no", "upstream_security")).to eq "-" + expect(data.value("SRS_Srs_yes", "upstream_security")).to eq "-" + expect(data.value("SWA_Spec_notSet", "upstream_security")).to eq "-" + expect(data.value("SMD_Unit_yes", "upstream_security")).to eq "-" + expect(data.value("SWA_Interface_no", "upstream_security")).to eq "-" + expect(data.value("SWA_Mod_yes", "upstream_security")).to eq "-" + expect(data.exist?("InputRequirement_notSet", "upstream_security")).to be false + expect(data.exist?("InputInformation_yes", "upstream_security")).to be false + + expect(data.value("SWA_Spec_yesP1", "upstream_security")).to eq "-" + expect(data.value("SWA_Spec_yesP2", "upstream_security")).to eq "-" + expect(data.value("SWA_Spec_noP", "upstream_security")).to eq "yes" + expect(data.value("SWA_Spec_notSetP", "upstream_security")).to eq "yes" + expect(data.value("SWA_Spec_child", "upstream_security")).to eq ["no", "not_set"].sort.join(", ") + + expect(data.value("SMD_Spec_ignoreBackRefs1", "upstream_security")).to eq ["yes", "not_set"].sort.join(", ") + expect(data.value("SMD_Spec_ignoreBackRefs2", "upstream_security")).to eq ["yes", "no", "not_set"].sort.join(", ") + expect(data.value("SMD_Spec_ignoreBackRefs3", "upstream_security")).to eq "-" + + expect(data.value("SWA_Spec_unique", "upstream_security")).to eq ["yes", "not_set"].sort.join(", ") + + expect(data.value("SWA_Spec_Cal", "upstream_security")).to eq ["yes", "no"].sort.join(", ") + expect(data.exist?("SWA_Spec_Cal", "upstream_cal")).to be false + end + end + end +end diff --git a/dox_trace/spec/parent_tags_spec.rb b/dox_trace/spec/parent_tags_spec.rb new file mode 100644 index 0000000..a1b476c --- /dev/null +++ b/dox_trace/spec/parent_tags_spec.rb @@ -0,0 +1,35 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Upstream Tags" do + context 'for specifications' do + before(:all) do + @test = Test.new("upstream_tags") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_UpstreamTags'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("upstream_tags", "index.html") + + expect(data.value("SRS_Requirement_sys", "upstream_tags")).to eq "-" + expect(data.value("SRS_Information_srs", "upstream_tags")).to eq "-" + expect(data.value("SRS_Srs_sys", "upstream_tags")).to eq "-" + expect(data.value("SWA_Spec_swa", "upstream_tags")).to eq "-" + expect(data.value("SMD_Unit_smd", "upstream_tags")).to eq "-" + expect(data.value("SWA_Interface_process", "upstream_tags")).to eq "-" + expect(data.exist?("InputRequirement_tested", "upstream_tags")).to be false + expect(data.exist?("InputInformation_covered", "upstream_tags")).to be false + expect(data.exist?("SWA_Mod_none", "upstream_tags")).to be false + + expect(data.value("SWA_Spec_smd", "upstream_tags")).to eq "-" + expect(data.value("SWA_Spec_swa1", "upstream_tags")).to eq "-" + expect(data.value("SWA_Spec_swa2", "upstream_tags")).to eq ["smd", "obd"].sort.join(", ") + expect(data.value("SWA_Spec_tool", "upstream_tags")).to eq ["obd, swa"].sort.join(", ") + expect(data.value("SWA_Spec_child", "upstream_tags")).to eq ["swa", "memory", "tool"].sort.join(", ") + + expect(data.value("SMD_Spec_ignoreBackRefs", "upstream_tags")).to eq ["sys", "swa", "smd", "process", "covered"].sort.join(", ") + end + end + end +end diff --git a/dox_trace/spec/properties_spec.rb b/dox_trace/spec/properties_spec.rb new file mode 100644 index 0000000..f64ac56 --- /dev/null +++ b/dox_trace/spec/properties_spec.rb @@ -0,0 +1,138 @@ +require_relative 'framework/helper' + +module Sphinx + describe "Properties file" do + context 'values shall be used' do + before(:all) do + @test = Test.new("properties") + @test.run + end + + it 'for non-set attributes if the ID is specified with full name', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Use'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("properties", "index.html") + expect(data.value("SRS_Requirement1_Full", "asil")).to eq 'ASIL_A' + expect(data.value("SRS_Requirement1_Full", "content")).to eq '

    Single line

    ' + end + + it 'for non-set attributes if the ID is specified with module name', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Use'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SRS_Requirement2_Mod", "asil")).to eq 'ASIL_C' + expect(data.value("SRS_Requirement2_Mod", "content")).to match /Multi.*
  • .*line1.*
  • .*line2<\/strong>/m + end + + it 'for non-set attributes if the ID is specified with category name', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Use'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SWA_Custom_CategorySet", "developer")).to eq 'Abc AG' + expect(data.value("SMD_Custom_CategoryNotSet", "developer")).to eq '[missing]' + end + + it 'for non-set attributes if _default_ is specified', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Use'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SRS_Requirement3_Default", "asil")).to eq 'QM' + expect(data.value("NoModuleNameDefault", "asil")).to eq 'QM' + expect(data.value("SRS_Requirement3_Default", "content")).to eq '

    Todo

    ' + expect(data.value("NoModuleNameDefault", "content")).to eq '

    Todo

    ' + end + + it 'unless attributes are already specified', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Use'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SRS_Requirement4_Defined", "asil")).to eq 'ASIL_D' + expect(data.value("SRS_Requirement4_Defined", "content")).to eq '

    Original content.

    ' + end + + it 'also for custom attributes', doc_refs: ['dox_trace_properties_file', 'DoxTrace_Properties_Custom'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SMD_Custom_Prop", "asil")).to eq 'ASIL_D' + expect(data.value("SMD_Custom_Overwritten", "asil")).to eq 'ASIL_C' + end + + it 'for standalone roles and directives', doc_refs: ['DoxTrace_Properties_Standalone'] do + raw = HtmlData.new("properties", "index.html").html + expect(raw).to match /Role defined.*literal.*Single.*line/ + expect(raw).to match /Directive defined.*line1.*line2.*Role default/m + expect(raw).to match /Role default.*literal.*Todo/ + expect(raw).to match /Directive default[^\n]*\n[^\n]*Todo/m + end + + it 'as string even they are defined as boolean in YAML', doc_refs: ['DoxTrace_Properties_Use'] do + data = HtmlData.new("properties", "index.html") + expect(data.value("SWA_Custom_True", "tags")).to eq 'true' + expect(data.value("SWA_Custom_False", "tags")).to eq 'false' + end + end + + context 'not exist' do + before(:all) do + @test = Test.new("properties_no_file") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['dox_trace_properties_file'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'properties.yaml does not exist' + end + end + + context 'not specified but used' do + before(:all) do + @test = Test.new("properties_not_available") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['dox_trace_properties_file'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:21: dox_trace_properties_file not specified in configuration' + end + end + + context 'with invalid syntax' do + before(:all) do + @test = Test.new("properties_wrong_file") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['dox_trace_properties_file'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:21: property bla:fasel not found' + end + end + + context 'with attribute name not found' do + before(:all) do + @test = Test.new("properties_no_name") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['DoxTrace_Properties_Use'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:21: property nope:fasel not found' + end + end + + context 'with attribute value not found' do + before(:all) do + @test = Test.new("properties_no_value") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['DoxTrace_Properties_Use'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:21: property bla:nope not found' + end + end + + context 'value used without colon' do + before(:all) do + @test = Test.new("properties_wrong_syntax") + @test.run + end + + it 'shall abort the the build aborted with an appropriate error message', doc_refs: ['DoxTrace_Properties_Use'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:4: property no_colon does not include exactly one ":"' + end + end + + end +end diff --git a/dox_trace/spec/refs_spec.rb b/dox_trace/spec/refs_spec.rb new file mode 100644 index 0000000..cdf293a --- /dev/null +++ b/dox_trace/spec/refs_spec.rb @@ -0,0 +1,85 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute refs" do + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("refs_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Refs'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "refs"' + end + end + + context 'including an undefined target building with dox_trace_allow_undefined_refs=False' do + before(:all) do + @test = Test.new("refs_undefined_warn") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an warning message', doc_refs: ['DoxTrace_HTML_RefsRed'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include "SWA_Spec_1 refers to non-existing SWA_Spec_100" + end + end + + context 'including undefined targets building with dox_trace_allow_undefined_refs=True' do + before(:all) do + @test = Test.new("refs_undefined_nowarn") + @test.run + end + + it 'shall NOT cause dox_trace to abort with exit code != 0 and NOT print a warning message', doc_refs: ['DoxTrace_HTML_RefsRed'] do + expect(@test.exit_code).to be == 0 + expect(@test.test_stderr).not_to include "SWA_Spec_1 refers to non-existing SWA_Spec_100" + end + + it 'shall display defined targets as links', doc_refs: ['DoxTrace_HTML_UpstreamRefs', 'DoxTrace_HTML_DownstreamRefs', 'DoxTrace_HTML_RefsRed'] do + + data = HtmlData.new("refs_undefined_nowarn", "index.html") + + expect(data.value("SWA_Spec_1", "Downstream References")).to eq '#swa_spec_2, #swa_spec_3' + expect(data.value("SWA_Spec_2", "Downstream References")).to eq '#swa_spec_3' + expect(data.value("SWA_Spec_3", "Downstream References")).to eq 'FASEL' # neither "#" nor "[missing]" + end + + it 'shall display undefined targets in red', doc_refs: ['DoxTrace_HTML_RefsRed'] do + expect(@test.exit_code).to be == 0 + expect(@test.test_stderr).not_to include "SWA_Spec_1 refers to non-existing SWA_Spec_100" + + data = HtmlData.new("refs_undefined_nowarn", "index.html") + + refs = {"SWA_Spec_1" => ["SWA_Spec_100", "BLAH", "#swa_spec_2", "FASEL", "#swa_spec_3"], + "SWA_Spec_2" => ["#swa_spec_3", "BLAH"], + "SWA_Spec_3" => ["FASEL"]} + + refs.each do |source, targets| + line = data.as_is_line(source, "Downstream References") + targets.each do |id| + if id.include?"#" + expect(line).to match(//) + else + expect(line).to match(/#{id}<\/span>/) + end + num_of_red = targets.count{|id| !id.include?"#"} + expect(line).to match(/"(dox-trace-red.*"){#{num_of_red}}/) + end + end + end + + it 'shall not export unresolved references', doc_refs: ['DoxTrace_HTML_RefsExport'] do + data = @test.dim_original_data["spec/test_input/refs_undefined_nowarn/export_root/swa/index.dim"] + + expect(data["SWA_Spec_1"]["refs"]).to eq 'SWA_Spec_2, SWA_Spec_3' + expect(data["SWA_Spec_2"]["refs"]).to eq 'SWA_Spec_3' + expect(data["SWA_Spec_3"]["refs"]).to eq '' + end + end + + end +end diff --git a/dox_trace/spec/reuse_spec.rb b/dox_trace/spec/reuse_spec.rb new file mode 100644 index 0000000..589c474 --- /dev/null +++ b/dox_trace/spec/reuse_spec.rb @@ -0,0 +1,104 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute reuse" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("reuse") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Reuse', 'DoxTrace_HTML_Reuse'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("reuse", "index.html") + + expect(data.value("SWA_Mod_ReuseEmpty", "reuse")).to eq '-' + expect(data.value("SWA_Mod_ReuseTrue", "reuse")).to eq 'true' + end + + it 'shall not be exported', doc_refs: ['DoxTrace_Export_Reuse'] do + dim = File.read("#{$test_input_dir}/reuse/export_root/swa/index.dim") + expect(dim).not_to match(/reuse/) + end + end + + context 'specified in a requirement directive' do + before(:all) do + @test = Test.new("reuse_requirement") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "requirement" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + context 'specified in a information directive' do + before(:all) do + @test = Test.new("reuse_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("reuse_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("reuse_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + context 'specified in a interface directive' do + before(:all) do + @test = Test.new("reuse_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + context 'specified in a srs directive' do + before(:all) do + @test = Test.new("reuse_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Reuse'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "reuse"' + end + end + + end +end diff --git a/dox_trace/spec/review_status_spec.rb b/dox_trace/spec/review_status_spec.rb new file mode 100644 index 0000000..af51841 --- /dev/null +++ b/dox_trace/spec/review_status_spec.rb @@ -0,0 +1,78 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute review_status" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("review_status") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_ReviewStatus'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("review_status", "index.html") + + expect(data.value("InputInformation_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("InputRequirement_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SRS_Information_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SRS_Requirement_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SRS_Srs_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SWA_Spec_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SMD_Unit_ReviewStatusRejected", "review_status")).to eq 'rejected' + expect(data.value("SWA_Interface_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + expect(data.value("SWA_Mod_ReviewStatusNotReviewed", "review_status")).to eq 'not_reviewed' + + expect(data.value("InputRequirement_ReviewStatusDefault", "review_status")).to eq 'not_reviewed' + + expect(data.value("InputRequirement_ReviewStatusAccepted", "review_status")).to eq 'accepted' + expect(data.value("InputRequirement_ReviewStatusRejected", "review_status")).to eq 'rejected' + expect(data.value("InputRequirement_StatusInvalid", "review_status")).to eq 'not_reviewed' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_ReviewStatus', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/review_status/export_root/srs/index.dim"] + expect(srs["SRS_Srs_ReviewStatusNotReviewed"]["review_status"]).to eq 'not_reviewed' + expect(srs["SRS_Srs_ReviewStatusDefault"]["review_status"]).to eq 'accepted' + + swa = @test.dim_original_data["spec/test_input/review_status/export_root/swa/index.dim"] + expect(swa["SWA_Spec_ReviewStatusNotReviewed"]["review_status"]).to eq 'not_reviewed' + expect(swa["SWA_Interface_ReviewStatusNotReviewed"]["review_status"]).to eq 'not_reviewed' + expect(swa["SWA_Mod_ReviewStatusNotReviewed"]["review_status"]).to eq 'not_reviewed' + expect(swa["SWA_Spec_ReviewStatusDefault"]["review_status"]).to eq 'accepted' + expect(swa["SWA_Interface_ReviewStatusDefault"]["review_status"]).to eq 'accepted' + expect(swa["SWA_Mod_ReviewStatusDefault"]["review_status"]).to eq 'accepted' + + smd = @test.dim_original_data["spec/test_input/review_status/export_root/smd/index.dim"] + expect(smd["SMD_Unit_ReviewStatusRejected"]["review_status"]).to eq 'rejected' + expect(smd["SMD_Unit_ReviewStatusDefault"]["review_status"]).to eq 'accepted' + end + + it 'shall only be shown in HTML if not accepted or type is input', doc_refs: ['DoxTrace_HTML_ReviewStatus'] do + data = HtmlData.new("review_status", "index.html") + + expect(data.exist?("InputInformation_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("InputRequirement_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("SRS_Information_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("SRS_Requirement_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("SWA_Spec_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("SMD_Unit_ReviewStatusRejected", "review_status")).to be true + expect(data.exist?("SWA_Interface_ReviewStatusNotReviewed", "review_status")).to be true + expect(data.exist?("SWA_Mod_ReviewStatusNotReviewed", "review_status")).to be true + + expect(data.exist?("InputInformation_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("InputRequirement_ReviewStatusDefault", "review_status")).to be true + expect(data.exist?("SRS_Information_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("SRS_Requirement_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("SWA_Spec_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("SMD_Unit_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("SWA_Interface_ReviewStatusDefault", "review_status")).to be false + expect(data.exist?("SWA_Mod_ReviewStatusDefault", "review_status")).to be false + + expect(data.exist?("InputRequirement_ReviewStatusAccepted", "review_status")).to be true + expect(data.exist?("InputRequirement_ReviewStatusRejected", "review_status")).to be true + expect(data.exist?("InputRequirement_StatusInvalid", "review_status")).to be true + expect(data.exist?("InputInformation_StatusInvalid", "review_status")).to be false + end + end + end +end diff --git a/dox_trace/spec/security_spec.rb b/dox_trace/spec/security_spec.rb new file mode 100644 index 0000000..3b9a876 --- /dev/null +++ b/dox_trace/spec/security_spec.rb @@ -0,0 +1,88 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute security" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("security") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Security'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("security", "index.html") + + expect(data.value("InputInformation_SecurityYes", "security")).to eq 'yes' + expect(data.value("InputRequirement_SecurityYes", "security")).to eq 'yes' + expect(data.value("SRS_Information_SecurityYes", "security")).to eq 'yes' + expect(data.value("SRS_Requirement_SecurityYes", "security")).to eq 'yes' + expect(data.value("SRS_Srs_SecurityYes", "security")).to eq 'yes' + expect(data.value("SWA_Spec_SecurityYes", "security")).to eq 'yes' + expect(data.value("SMD_Unit_SecurityYes", "security")).to eq 'yes' + expect(data.value("SWA_Interface_SecurityYes", "security")).to eq 'yes' + expect(data.value("SWA_Mod_SecurityYes", "security")).to eq 'yes' + + expect(data.value("InputInformation_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("InputRequirement_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SRS_Information_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SRS_Requirement_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SRS_Srs_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SWA_Spec_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SMD_Unit_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SWA_Interface_SecurityDefault", "security")).to eq 'not_set' + expect(data.value("SWA_Mod_SecurityDefault", "security")).to eq 'not_set' + + expect(data.value("SWA_Spec_ReviewStatusRejected", "security")).to eq 'not_set' + end + + it 'shall derive the value from cal if security is not defined', doc_refs: ['DoxTrace_Syntax_CalToSecurity', 'DoxTrace_HTML_Cal'] do + data = HtmlData.new("security", "index.html") + + expect(data.value("SWA_Spec_CalNotSet", "security")).to eq 'not_set' + expect(data.value("SWA_Spec_CalQm", "security")).to eq 'no' + expect(data.value("SWA_Spec_Cal1", "security")).to eq 'yes' + expect(data.value("SWA_Spec_Cal2", "security")).to eq 'yes' + expect(data.value("SWA_Spec_Cal3", "security")).to eq 'yes' + expect(data.value("SWA_Spec_Cal4", "security")).to eq 'yes' + + expect(data.exist?("SWA_Spec_Cal4", "cal")).to be false + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Security', 'DoxTrace_Export_Attributes', 'DoxTrace_Export_Cal'] do + srs = @test.dim_original_data["spec/test_input/security/export_root/srs/index.dim"] + expect(srs["SRS_Srs_SecurityYes"]["security"]).to eq 'yes' + expect(srs["SRS_Srs_SecurityDefault"]["security"]).to eq 'not_set' + + swa = @test.dim_original_data["spec/test_input/security/export_root/swa/index.dim"] + expect(swa["SWA_Spec_SecurityYes"]["security"]).to eq 'yes' + expect(swa["SWA_Interface_SecurityYes"]["security"]).to eq 'yes' + expect(swa["SWA_Mod_SecurityYes"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_SecurityDefault"]["security"]).to eq 'not_set' + expect(swa["SWA_Interface_SecurityDefault"]["security"]).to eq 'not_set' + expect(swa["SWA_Mod_SecurityDefault"]["security"]).to eq 'not_set' + expect(swa["SWA_Spec_ReviewStatusRejected"]["security"]).to eq 'not_set' + + expect(swa["SWA_Spec_CalNotSet"]["security"]).to eq 'not_set' + expect(swa["SWA_Spec_CalQm"]["security"]).to eq 'no' + expect(swa["SWA_Spec_Cal1"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal1"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal1"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal1"]["security"]).to eq 'yes' + + expect(swa["SWA_Spec_CalNotSet"]["security"]).to eq 'not_set' + expect(swa["SWA_Spec_CalQm"]["security"]).to eq 'no' + expect(swa["SWA_Spec_Cal1"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal2"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal3"]["security"]).to eq 'yes' + expect(swa["SWA_Spec_Cal4"]["security"]).to eq 'yes' + + expect(swa["SWA_Spec_Cal4"]["cal"]).to eq nil + + smd = @test.dim_original_data["spec/test_input/security/export_root/smd/index.dim"] + expect(smd["SMD_Unit_SecurityYes"]["security"]).to eq 'yes' + expect(smd["SMD_Unit_SecurityDefault"]["security"]).to eq 'not_set' + end + end + + end +end diff --git a/dox_trace/spec/sources_spec.rb b/dox_trace/spec/sources_spec.rb new file mode 100644 index 0000000..08c276a --- /dev/null +++ b/dox_trace/spec/sources_spec.rb @@ -0,0 +1,96 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute sources" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("sources") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Sources', 'DoxTrace_HTML_Sources'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("sources", "index.html") + data_subpage = HtmlData.new("sources", "doc/subpage.html") + + expect(data.value("SRS_Requirement_SourcesSet", "sources")).to eq 'Makefile' + expect(data.value("InputRequirement_SourcesSet", "sources")).to eq 'Makefile, index.rst' + expect(data.value("SRS_Srs_SourcesSet", "sources")).to eq 'Makefile' + expect(data.value("SWA_Spec_SourcesSet", "sources")).to eq 'src/test.abc' + expect(data.value("SMD_Unit_SourcesSet", "sources")).to eq 'src/test.abc, Makefile' + expect(data.value("SWA_Interface_SourcesSet", "sources")).to eq 'Makefile, src/test.abc' + expect(data.value("SMD_Interface_SourcesSet", "sources")).to eq 'Makefile, src/test.abc' + + expect(data_subpage.value("SMD_Unit_ModuleDoc", "sources")).to eq 'doc/subpage.rst' + + expect(data.exist?("SRS_Requirement_SourcesDefault", "sources")).to be false + expect(data.exist?("InputRequirement_SourcesDefault", "sources")).to be false + expect(data.exist?("SRS_Srs_SourcesDefault", "sources")).to be false + expect(data.exist?("SWA_Spec_SourcesDefault", "sources")).to be false + expect(data.value("SMD_Unit_SourcesDefault", "sources")).to eq '[missing]' + expect(data.exist?("SWA_Interface_SourcesDefault", "sources")).to be false + expect(data.value("SMD_Interface_SourcesDefault", "sources")).to eq '[missing]' + + expect(data.exist?("SWA_Spec_TagsCovered", "sources")).to be false + expect(data.value("SMD_Unit_TagsCovered", "sources")).to eq '-' + expect(data.value("SMD_Interface_TagsCovered", "sources")).to eq '-' + expect(data.exist?("SWA_Spec_StatusInvalid", "sources")).to be false + expect(data.value("SMD_Unit_StatusInvalid", "sources")).to eq '-' + expect(data.exist?("SWA_Interface_StatusInvalid", "sources")).to be false + expect(data.value("SMD_Interface_StatusInvalid", "sources")).to eq '-' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Sources', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/sources/export_root/srs/index.dim"] + expect(srs["SRS_Srs_SourcesSet"]["sources"]).to eq 'Makefile' + expect(srs["SRS_Srs_SourcesDefault"]["sources"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/sources/export_root/swa/index.dim"] + expect(swa["SWA_Spec_SourcesSet"]["sources"]).to eq 'src/test.abc' + expect(swa["SWA_Interface_SourcesSet"]["sources"]).to eq 'Makefile, src/test.abc' + expect(swa["SWA_Spec_SourcesDefault"]["sources"]).to eq '' + expect(swa["SWA_Interface_SourcesDefault"]["sources"]).to eq '' + expect(swa["SWA_Spec_TagsCovered"]["sources"]).to eq '' + expect(swa["SWA_Spec_StatusInvalid"]["sources"]).to eq '' + expect(swa["SWA_Interface_StatusInvalid"]["sources"]).to eq '' + + smd = @test.dim_original_data["spec/test_input/sources/export_root/smd/index.dim"] + expect(smd["SMD_Unit_SourcesSet"]["sources"]).to eq 'src/test.abc, Makefile' + expect(smd["SMD_Interface_SourcesSet"]["sources"]).to eq 'Makefile, src/test.abc' + expect(smd["SMD_Unit_SourcesDefault"]["sources"]).to eq '' + expect(smd["SMD_Interface_SourcesDefault"]["sources"]).to eq '' + expect(smd["SMD_Unit_TagsCovered"]["sources"]).to eq '' + expect(smd["SMD_Interface_TagsCovered"]["sources"]).to eq '' + expect(smd["SMD_Unit_StatusInvalid"]["sources"]).to eq '' + expect(smd["SMD_Interface_StatusInvalid"]["sources"]).to eq '' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("sources_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "sources"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("sources_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Sources'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "sources"' + end + end + + end +end diff --git a/dox_trace/spec/status_spec.rb b/dox_trace/spec/status_spec.rb new file mode 100644 index 0000000..6a9476c --- /dev/null +++ b/dox_trace/spec/status_spec.rb @@ -0,0 +1,59 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute status" do + context 'with correct syntax' do + + before(:all) do + @test = Test.new("status") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Status'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("status", "index.html") + + expect(data.value("InputInformation_StatusValid", "status")).to eq 'valid' + expect(data.value("InputRequirement_StatusValid", "status")).to eq 'valid' + expect(data.value("SRS_Information_StatusValid", "status")).to eq 'valid' + expect(data.value("SRS_Requirement_StatusValid", "status")).to eq 'valid' + expect(data.value("SRS_Srs_StatusValid", "status")).to eq 'valid' + expect(data.value("SWA_Spec_StatusValid", "status")).to eq 'valid' + expect(data.value("SMD_Unit_StatusValid", "status")).to eq 'valid' + expect(data.value("SWA_Interface_StatusValid", "status")).to eq 'valid' + expect(data.value("SWA_Mod_StatusValid", "status")).to eq 'valid' + + expect(data.value("InputInformation_StatusDefault", "status")).to eq 'draft' + expect(data.value("InputRequirement_StatusDefault", "status")).to eq 'draft' + expect(data.value("SRS_Information_StatusDefault", "status")).to eq 'draft' + expect(data.value("SRS_Requirement_StatusDefault", "status")).to eq 'draft' + expect(data.value("SRS_Srs_StatusDefault", "status")).to eq 'draft' + expect(data.value("SWA_Spec_StatusDefault", "status")).to eq 'draft' + expect(data.value("SMD_Unit_StatusDefault", "status")).to eq 'draft' + expect(data.value("SWA_Interface_StatusDefault", "status")).to eq 'draft' + expect(data.value("SWA_Mod_StatusDefault", "status")).to eq 'draft' + + expect(data.value("SWA_Spec_ReviewStatusRejected", "status")).to eq 'draft' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Status', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/status/export_root/srs/index.dim"] + expect(srs["SRS_Srs_StatusValid"]["status"]).to eq 'valid' + expect(srs["SRS_Srs_StatusDefault"]["status"]).to eq 'draft' + + swa = @test.dim_original_data["spec/test_input/status/export_root/swa/index.dim"] + expect(swa["SWA_Spec_StatusValid"]["status"]).to eq 'valid' + expect(swa["SWA_Interface_StatusValid"]["status"]).to eq 'valid' + expect(swa["SWA_Mod_StatusValid"]["status"]).to eq 'valid' + expect(swa["SWA_Spec_StatusDefault"]["status"]).to eq 'draft' + expect(swa["SWA_Interface_StatusDefault"]["status"]).to eq 'draft' + expect(swa["SWA_Mod_StatusDefault"]["status"]).to eq 'draft' + expect(swa["SWA_Spec_ReviewStatusRejected"]["status"]).to eq 'draft' + + smd = @test.dim_original_data["spec/test_input/status/export_root/smd/index.dim"] + expect(smd["SMD_Unit_StatusValid"]["status"]).to eq 'valid' + expect(smd["SMD_Unit_StatusDefault"]["status"]).to eq 'draft' + end + end + end +end diff --git a/dox_trace/spec/tags_spec.rb b/dox_trace/spec/tags_spec.rb new file mode 100644 index 0000000..7e25405 --- /dev/null +++ b/dox_trace/spec/tags_spec.rb @@ -0,0 +1,74 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute tags" do + context 'with correct syntax' do + + before(:all) do + @test = Test.new("tags") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Tags', 'DoxTrace_HTML_Tags'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tags", "index.html") + + expect(data.value("SRS_Information_TagsSet", "tags")).to eq 'srs' + expect(data.value("SRS_Requirement_TagsSet", "tags")).to eq 'swa' + expect(data.value("InputInformation_TagsSet", "tags")).to eq 'memory' + expect(data.value("InputRequirement_TagsSet", "tags")).to eq 'memory, performance' + expect(data.value("SRS_Srs_TagsSet", "tags")).to eq 'swa' + expect(data.value("SWA_Spec_TagsSet", "tags")).to eq 'performance' + expect(data.value("SMD_Unit_TagsSet", "tags")).to eq 'obd, performance' + expect(data.value("SWA_Interface_TagsSet", "tags")).to eq 'sys, tool' + + expect(data.value("InputInformation_TagsDefault", "tags")).to eq '-' + expect(data.value("InputRequirement_TagsDefault", "tags")).to eq '-' + expect(data.value("SRS_Information_TagsDefault", "tags")).to eq '-' + expect(data.value("SRS_Requirement_TagsDefault", "tags")).to eq '-' + expect(data.value("SRS_Srs_TagsDefault", "tags")).to eq '-' + expect(data.value("SWA_Spec_TagsDefault", "tags")).to eq '-' + expect(data.value("SMD_Unit_TagsDefault", "tags")).to eq '-' + expect(data.value("SWA_Interface_TagsDefault", "tags")).to eq '-' + + expect(data.value("SMD_Unit_TagsUnitSet", "tags")).to eq 'obd, unit, performance' + expect(data.value("SWA_Interface_TagsInterfaceSet", "tags")).to eq 'sys, interface, tool' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Tags', 'DoxTrace_Export_Unit', 'DoxTrace_Export_Interface', 'DoxTrace_Export_Mod', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/tags/export_root/srs/index.dim"] + expect(srs["SRS_Srs_TagsSet"]["tags"]).to eq 'swa' + expect(srs["SRS_Srs_TagsDefault"]["tags"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/tags/export_root/swa/index.dim"] + expect(swa["SWA_Spec_TagsSet"]["tags"]).to eq 'performance' + expect(swa["SWA_Interface_TagsSet"]["tags"]).to eq 'sys, tool, interface' + expect(swa["SWA_Mod_Empty"]["tags"]).to eq '' + expect(swa["SWA_Mod_NotExist"]["tags"]).to eq '' + expect(swa["SWA_Mod_Exist"]["tags"]).to eq 'covered' + expect(swa["SWA_Spec_TagsDefault"]["tags"]).to eq '' + expect(swa["SWA_Interface_TagsDefault"]["tags"]).to eq 'interface' + expect(swa["SWA_Interface_TagsInterfaceSet"]["tags"]).to eq 'sys, interface, tool' + + smd = @test.dim_original_data["spec/test_input/tags/export_root/smd/index.dim"] + expect(smd["SMD_Unit_TagsUnitSet"]["tags"]).to eq 'obd, unit, performance' + expect(smd["SMD_Unit_TagsSet"]["tags"]).to eq 'obd, performance, unit' + expect(smd["SMD_Unit_TagsDefault"]["tags"]).to eq 'unit' + end + end + + context 'specified in a mod directive' do + before(:all) do + @test = Test.new("tags_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Tags'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "tags"' + end + end + + end +end diff --git a/dox_trace/spec/test_input/asil/Makefile b/dox_trace/spec/test_input/asil/Makefile new file mode 100644 index 0000000..787c0fd --- /dev/null +++ b/dox_trace/spec/test_input/asil/Makefile @@ -0,0 +1,10 @@ + +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/asil/conf.py b/dox_trace/spec/test_input/asil/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/asil/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/asil/index.rst b/dox_trace/spec/test_input/asil/index.rst new file mode 100644 index 0000000..32cac82 --- /dev/null +++ b/dox_trace/spec/test_input/asil/index.rst @@ -0,0 +1,67 @@ +Asil +==== + +Available +--------- + +.. information:: SRS_Information_AsilB + :asil: ASIL_B + :category: software + +.. requirement:: SRS_Requirement_AsilB + :asil: ASIL_B + :category: software + +.. srs:: SRS_Srs_AsilB + :asil: ASIL_B + +.. information:: InputInformation_AsilB + :asil: ASIL_B + :category: input + +.. requirement:: InputRequirement_AsilB + :asil: ASIL_B + :category: input + +.. spec:: SWA_Spec_AsilB + :asil: ASIL_B + +.. unit:: SMD_Unit_AsilB + :asil: ASIL_B + +.. interface:: SWA_Interface_AsilB + :asil: ASIL_B + +.. mod:: SWA_Mod_AsilB + :asil: ASIL_B + +Default +------- + +.. information:: SRS_Information_AsilDefault + :category: software + +.. requirement:: SRS_Requirement_AsilDefault + :category: software + +.. information:: InputInformation_AsilDefault + :category: input + +.. requirement:: InputRequirement_AsilDefault + :category: input + +.. srs:: SRS_Srs_AsilDefault + +.. spec:: SWA_Spec_AsilDefault + +.. unit:: SMD_Unit_AsilDefault + +.. interface:: SWA_Interface_AsilDefault + +.. mod:: SWA_Mod_AsilDefault + +Additional +---------- + +.. spec:: SWA_Spec_ReviewStatusRejected + :review_status: rejected diff --git a/dox_trace/spec/test_input/cal/Makefile b/dox_trace/spec/test_input/cal/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/cal/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/cal/conf.py b/dox_trace/spec/test_input/cal/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/cal/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/cal/index.rst b/dox_trace/spec/test_input/cal/index.rst new file mode 100644 index 0000000..5569036 --- /dev/null +++ b/dox_trace/spec/test_input/cal/index.rst @@ -0,0 +1,83 @@ +Cal +=== + +Available +--------- + +.. information:: SRS_Information_Cal1 + :cal: CAL_1 + :category: software + +.. requirement:: SRS_Requirement_Cal2 + :cal: CAL_2 + :category: software + +.. information:: InputInformation_Cal3 + :cal: CAL_3 + :category: input + +.. requirement:: InputRequirement_Cal4 + :cal: CAL_4 + :category: input + +.. srs:: SRS_Srs_CalQm + :cal: QM + +.. spec:: SWA_Spec_CalQm + :cal: QM + +.. unit:: SMD_Unit_Cal1 + :cal: CAL_1 + +.. interface:: SWA_Interface_CalQm + :cal: QM + +.. mod:: SWA_Mod_CalNotSet + :cal: not_set + +Default +------- + +.. information:: SRS_Information_CalDefault + :category: software + +.. requirement:: SRS_Requirement_CalDefault + :category: software + +.. information:: InputInformation_CalDefault + :category: input + +.. requirement:: InputRequirement_CalDefault + :category: input + +.. srs:: SRS_Srs_CalDefault + +.. spec:: SWA_Spec_CalDefault + +.. unit:: SMD_Unit_CalDefault + +.. interface:: SWA_Interface_CalDefault + +.. mod:: SWA_Mod_CalDefault + +Additional +---------- + +.. spec:: SWA_Spec_ReviewStatusRejected + :review_status: rejected + +Security +-------- + +.. spec:: SWA_Spec_CalYes + :security: yes + +.. spec:: SWA_Spec_CalNo + :security: no + +.. spec:: SWA_Spec_CalNotSet + :security: not_set + +.. spec:: SWA_Spec_CalYes1 + :security: yes + :cal: CAL_1 diff --git a/dox_trace/spec/test_input/category/Makefile b/dox_trace/spec/test_input/category/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category/conf.py b/dox_trace/spec/test_input/category/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category/index.rst b/dox_trace/spec/test_input/category/index.rst new file mode 100644 index 0000000..513cabb --- /dev/null +++ b/dox_trace/spec/test_input/category/index.rst @@ -0,0 +1,37 @@ +Category +======== + +Available +--------- + +.. information:: SRS_Information_CategorySet + :category: software + :comment: ignored + +.. requirement:: SRS_Requirement_CategorySet + :category: software + :comment: ignored + +.. information:: InputInformation_CategorySet + :category: input + :comment: not_ignored + +.. requirement:: InputRequirement_CategorySet + :category: input + :comment: not_ignored + +Default +------- + +.. information:: DefaultInformation_CategoryDefault + :comment: not_ignored + +.. requirement:: DefaultRequirement_CategoryDefault + :comment: not_ignored + +Dummy +----- + +Otherwise no export will be created. + +.. spec:: SWA_Spec_Dummy diff --git a/dox_trace/spec/test_input/category_interface/Makefile b/dox_trace/spec/test_input/category_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category_interface/conf.py b/dox_trace/spec/test_input/category_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category_interface/index.rst b/dox_trace/spec/test_input/category_interface/index.rst new file mode 100644 index 0000000..b4f1b63 --- /dev/null +++ b/dox_trace/spec/test_input/category_interface/index.rst @@ -0,0 +1,8 @@ +Category Interface +================== + +Not Available +------------- + +.. interface:: SWA_Interface_NotAvailable + :category: input diff --git a/dox_trace/spec/test_input/category_mod/Makefile b/dox_trace/spec/test_input/category_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category_mod/conf.py b/dox_trace/spec/test_input/category_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category_mod/index.rst b/dox_trace/spec/test_input/category_mod/index.rst new file mode 100644 index 0000000..d7bd625 --- /dev/null +++ b/dox_trace/spec/test_input/category_mod/index.rst @@ -0,0 +1,8 @@ +Category Mod +============ + +Not Available +------------- + +.. mod:: SWA_Mod_NotAvailable + :category: input diff --git a/dox_trace/spec/test_input/category_spec/Makefile b/dox_trace/spec/test_input/category_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category_spec/conf.py b/dox_trace/spec/test_input/category_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category_spec/index.rst b/dox_trace/spec/test_input/category_spec/index.rst new file mode 100644 index 0000000..75f78b3 --- /dev/null +++ b/dox_trace/spec/test_input/category_spec/index.rst @@ -0,0 +1,8 @@ +Category Spec +============= + +Not Available +------------- + +.. spec:: SWA_Spec_NotAvailable + :category: input diff --git a/dox_trace/spec/test_input/category_srs/Makefile b/dox_trace/spec/test_input/category_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category_srs/conf.py b/dox_trace/spec/test_input/category_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category_srs/index.rst b/dox_trace/spec/test_input/category_srs/index.rst new file mode 100644 index 0000000..bc09d24 --- /dev/null +++ b/dox_trace/spec/test_input/category_srs/index.rst @@ -0,0 +1,8 @@ +Category Srs +============ + +Not Available +------------- + +.. srs:: SRS_Srs_NotAvailable + :category: input diff --git a/dox_trace/spec/test_input/category_unit/Makefile b/dox_trace/spec/test_input/category_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/category_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/category_unit/conf.py b/dox_trace/spec/test_input/category_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/category_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/category_unit/index.rst b/dox_trace/spec/test_input/category_unit/index.rst new file mode 100644 index 0000000..6273950 --- /dev/null +++ b/dox_trace/spec/test_input/category_unit/index.rst @@ -0,0 +1,8 @@ +Category Unit +============= + +Not Available +------------- + +.. unit:: SMD_Unit_NotAvailable + :category: input diff --git a/dox_trace/spec/test_input/change_request/Makefile b/dox_trace/spec/test_input/change_request/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request/conf.py b/dox_trace/spec/test_input/change_request/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request/index.rst b/dox_trace/spec/test_input/change_request/index.rst new file mode 100644 index 0000000..9128a7f --- /dev/null +++ b/dox_trace/spec/test_input/change_request/index.rst @@ -0,0 +1,22 @@ +Change Request +============== + +Available +--------- + +.. requirement:: SRS_Requirement_ChangeRequestSet + :change_request: Bb + :category: software + +.. requirement:: InputRequirement_ChangeRequestSet + :change_request: Dd + :category: input + +Default +------- + +.. requirement:: SRS_Requirement_ChangeRequestDefault + :category: software + +.. requirement:: InputRequirement_ChangeRequestDefault + :category: input diff --git a/dox_trace/spec/test_input/change_request_information/Makefile b/dox_trace/spec/test_input/change_request_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_information/conf.py b/dox_trace/spec/test_input/change_request_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_information/index.rst b/dox_trace/spec/test_input/change_request_information/index.rst new file mode 100644 index 0000000..c88f09b --- /dev/null +++ b/dox_trace/spec/test_input/change_request_information/index.rst @@ -0,0 +1,9 @@ +Change Request Information +========================== + +Not Available +------------- + +.. information:: SRS_Information_NotAvailable + :change_request: not available + :category: software diff --git a/dox_trace/spec/test_input/change_request_interface/Makefile b/dox_trace/spec/test_input/change_request_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_interface/conf.py b/dox_trace/spec/test_input/change_request_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_interface/index.rst b/dox_trace/spec/test_input/change_request_interface/index.rst new file mode 100644 index 0000000..3c9ac69 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_interface/index.rst @@ -0,0 +1,8 @@ +Change Request Interface +======================== + +Not Available +------------- + +.. interface:: SWA_Interface_NotAvailable + :change_request: not available diff --git a/dox_trace/spec/test_input/change_request_mod/Makefile b/dox_trace/spec/test_input/change_request_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_mod/conf.py b/dox_trace/spec/test_input/change_request_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_mod/index.rst b/dox_trace/spec/test_input/change_request_mod/index.rst new file mode 100644 index 0000000..b6a296d --- /dev/null +++ b/dox_trace/spec/test_input/change_request_mod/index.rst @@ -0,0 +1,8 @@ +Change Request Mod +================== + +Not Available +------------- + +.. mod:: SWA_Mod_NotAvailable + :change_request: not available diff --git a/dox_trace/spec/test_input/change_request_spec/Makefile b/dox_trace/spec/test_input/change_request_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_spec/conf.py b/dox_trace/spec/test_input/change_request_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_spec/index.rst b/dox_trace/spec/test_input/change_request_spec/index.rst new file mode 100644 index 0000000..94c747b --- /dev/null +++ b/dox_trace/spec/test_input/change_request_spec/index.rst @@ -0,0 +1,8 @@ +Change Request Spec +=================== + +Not Available +------------- + +.. spec:: SWA_Spec_NotAvailable + :change_request: not available diff --git a/dox_trace/spec/test_input/change_request_srs/Makefile b/dox_trace/spec/test_input/change_request_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_srs/conf.py b/dox_trace/spec/test_input/change_request_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_srs/index.rst b/dox_trace/spec/test_input/change_request_srs/index.rst new file mode 100644 index 0000000..fdde73b --- /dev/null +++ b/dox_trace/spec/test_input/change_request_srs/index.rst @@ -0,0 +1,8 @@ +Change Request Srs +================== + +Not Available +------------- + +.. srs:: SRS_Srs_NotAvailable + :change_request: not available diff --git a/dox_trace/spec/test_input/change_request_unit/Makefile b/dox_trace/spec/test_input/change_request_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/change_request_unit/conf.py b/dox_trace/spec/test_input/change_request_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/change_request_unit/index.rst b/dox_trace/spec/test_input/change_request_unit/index.rst new file mode 100644 index 0000000..52a54f5 --- /dev/null +++ b/dox_trace/spec/test_input/change_request_unit/index.rst @@ -0,0 +1,8 @@ +Change Request Unit +=================== + +Not Available +------------- + +.. unit:: SMD_Unit_NotAvailable + :change_request: not available diff --git a/dox_trace/spec/test_input/check_cyclic_direct/Makefile b/dox_trace/spec/test_input/check_cyclic_direct/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_direct/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_cyclic_direct/conf.py b/dox_trace/spec/test_input/check_cyclic_direct/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_direct/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_cyclic_direct/index.rst b/dox_trace/spec/test_input/check_cyclic_direct/index.rst new file mode 100644 index 0000000..8f52ecc --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_direct/index.rst @@ -0,0 +1,6 @@ +Check Cyclic Direct +=================== + +.. requirement:: SRS_Requirement_Direct + :refs: SRS_Requirement_Direct + :category: software \ No newline at end of file diff --git a/dox_trace/spec/test_input/check_cyclic_indirect/Makefile b/dox_trace/spec/test_input/check_cyclic_indirect/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_cyclic_indirect/conf.py b/dox_trace/spec/test_input/check_cyclic_indirect/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_cyclic_indirect/index.rst b/dox_trace/spec/test_input/check_cyclic_indirect/index.rst new file mode 100644 index 0000000..1156bf8 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect/index.rst @@ -0,0 +1,17 @@ +Check Cyclic Indirect +===================== + +.. requirement:: SRS_Requirement_Indirect1 + :refs: SRS_Requirement_Indirect2 + :category: software + +.. requirement:: SRS_Requirement_Indirect2 + :refs: SRS_Requirement_Indirect3, SRS_Requirement_Indirect4 + :category: software + +.. requirement:: SRS_Requirement_Indirect3 + :category: software + +.. requirement:: SRS_Requirement_Indirect4 + :refs: SRS_Requirement_Indirect1 + :category: software \ No newline at end of file diff --git a/dox_trace/spec/test_input/check_cyclic_indirect_levels/Makefile b/dox_trace/spec/test_input/check_cyclic_indirect_levels/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect_levels/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_cyclic_indirect_levels/conf.py b/dox_trace/spec/test_input/check_cyclic_indirect_levels/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect_levels/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_cyclic_indirect_levels/index.rst b/dox_trace/spec/test_input/check_cyclic_indirect_levels/index.rst new file mode 100644 index 0000000..9d241b1 --- /dev/null +++ b/dox_trace/spec/test_input/check_cyclic_indirect_levels/index.rst @@ -0,0 +1,30 @@ +Check Cyclic Indirect Levels +============================ + +.. requirement:: Input_Requirement_Indirect1 + :refs: Input_Requirement_Indirect2 + :category: input + +.. requirement:: Input_Requirement_Indirect2 + :refs: Input_Requirement_Indirect3, SRS_Requirement_Indirect4 + :category: input + +.. requirement:: Input_Requirement_Indirect3 + :category: input + +.. requirement:: SRS_Requirement_Indirect4 + :refs: Input_Requirement_Indirect1 + :category: software + + + +.. spec:: SWA_Spec_Indirect1 + :refs: SWA_Spec_Indirect2 + +.. spec:: SWA_Spec_Indirect2 + :refs: SWA_Spec_Indirect3, SMD_Spec_Indirect4 + +.. spec:: SWA_Spec_Indirect3 + +.. spec:: SMD_Spec_Indirect4 + :refs: SWA_Spec_Indirect1 diff --git a/dox_trace/spec/test_input/check_invalid_case/Makefile b/dox_trace/spec/test_input/check_invalid_case/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_case/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_case/conf.py b/dox_trace/spec/test_input/check_invalid_case/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_case/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_case/index.rst b/dox_trace/spec/test_input/check_invalid_case/index.rst new file mode 100644 index 0000000..853d051 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_case/index.rst @@ -0,0 +1,9 @@ +Check Invalid Case +================== + +.. requirement:: SRS_Requirement_InvalidCase + :refs: SRS_Requirement_target + :category: software + +.. requirement:: SRS_Requirement_Target + :category: software diff --git a/dox_trace/spec/test_input/check_invalid_comment_ignored/Makefile b/dox_trace/spec/test_input/check_invalid_comment_ignored/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_ignored/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_ignored/conf.py b/dox_trace/spec/test_input/check_invalid_comment_ignored/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_ignored/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_ignored/index.rst b/dox_trace/spec/test_input/check_invalid_comment_ignored/index.rst new file mode 100644 index 0000000..aa3531b --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_ignored/index.rst @@ -0,0 +1,13 @@ +Check Invalid Comment Ignored +============================= + +.. requirement: Ignored... + +.. some_comment: + + The words + unit and srs + are not in the first line. + +.. some_other comment: Here + the word unit is also not in the first line. diff --git a/dox_trace/spec/test_input/check_invalid_comment_interface/Makefile b/dox_trace/spec/test_input/check_invalid_comment_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_interface/conf.py b/dox_trace/spec/test_input/check_invalid_comment_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_interface/index.rst b/dox_trace/spec/test_input/check_invalid_comment_interface/index.rst new file mode 100644 index 0000000..79ab38b --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_interface/index.rst @@ -0,0 +1,4 @@ +Check Invalid Comment Interface +=============================== + +.. interface diff --git a/dox_trace/spec/test_input/check_invalid_comment_mod/Makefile b/dox_trace/spec/test_input/check_invalid_comment_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_mod/conf.py b/dox_trace/spec/test_input/check_invalid_comment_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_mod/index.rst b/dox_trace/spec/test_input/check_invalid_comment_mod/index.rst new file mode 100644 index 0000000..f8e1959 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_mod/index.rst @@ -0,0 +1,5 @@ +Check Invalid Comment Mod +========================= + +.. :mod + Next line diff --git a/dox_trace/spec/test_input/check_invalid_comment_spec/Makefile b/dox_trace/spec/test_input/check_invalid_comment_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_spec/conf.py b/dox_trace/spec/test_input/check_invalid_comment_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_spec/index.rst b/dox_trace/spec/test_input/check_invalid_comment_spec/index.rst new file mode 100644 index 0000000..fc6d049 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_spec/index.rst @@ -0,0 +1,5 @@ +Check Invalid Comment Spec +========================== + +.. spec: + missing a : diff --git a/dox_trace/spec/test_input/check_invalid_comment_srs/Makefile b/dox_trace/spec/test_input/check_invalid_comment_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_srs/conf.py b/dox_trace/spec/test_input/check_invalid_comment_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_srs/index.rst b/dox_trace/spec/test_input/check_invalid_comment_srs/index.rst new file mode 100644 index 0000000..de02692 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_srs/index.rst @@ -0,0 +1,5 @@ +Check Invalid Comment Srs +========================= + +.. srs.. + Next line diff --git a/dox_trace/spec/test_input/check_invalid_comment_unit/Makefile b/dox_trace/spec/test_input/check_invalid_comment_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_comment_unit/conf.py b/dox_trace/spec/test_input/check_invalid_comment_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_comment_unit/index.rst b/dox_trace/spec/test_input/check_invalid_comment_unit/index.rst new file mode 100644 index 0000000..ed3d3c3 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_comment_unit/index.rst @@ -0,0 +1,4 @@ +Check Invalid Comment Unit +========================== + +.. :unit: diff --git a/dox_trace/spec/test_input/check_invalid_ref/Makefile b/dox_trace/spec/test_input/check_invalid_ref/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_ref/conf.py b/dox_trace/spec/test_input/check_invalid_ref/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_ref/index.rst b/dox_trace/spec/test_input/check_invalid_ref/index.rst new file mode 100644 index 0000000..f44efb0 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref/index.rst @@ -0,0 +1,8 @@ +.. _invalid_target: + +Check Invalid Ref +================= + +.. requirement:: SRS_Requirement_InvalidRef + :refs: invalid_target + :category: software diff --git a/dox_trace/spec/test_input/check_invalid_ref_suppress/Makefile b/dox_trace/spec/test_input/check_invalid_ref_suppress/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref_suppress/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_ref_suppress/conf.py b/dox_trace/spec/test_input/check_invalid_ref_suppress/conf.py new file mode 100644 index 0000000..aeed20c --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref_suppress/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +suppress_warnings = ["ref.ref", "ref.doc"] diff --git a/dox_trace/spec/test_input/check_invalid_ref_suppress/index.rst b/dox_trace/spec/test_input/check_invalid_ref_suppress/index.rst new file mode 100644 index 0000000..f44efb0 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_ref_suppress/index.rst @@ -0,0 +1,8 @@ +.. _invalid_target: + +Check Invalid Ref +================= + +.. requirement:: SRS_Requirement_InvalidRef + :refs: invalid_target + :category: software diff --git a/dox_trace/spec/test_input/check_invalid_sources_interface/Makefile b/dox_trace/spec/test_input/check_invalid_sources_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_sources_interface/conf.py b/dox_trace/spec/test_input/check_invalid_sources_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_sources_interface/index.rst b/dox_trace/spec/test_input/check_invalid_sources_interface/index.rst new file mode 100644 index 0000000..69d4ab4 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_interface/index.rst @@ -0,0 +1,5 @@ +Check Invalid Sources Interface +=============================== + +.. interface:: SWA_Interface_InvalidSources + :sources: does/not/exist.cpp diff --git a/dox_trace/spec/test_input/check_invalid_sources_requirement/Makefile b/dox_trace/spec/test_input/check_invalid_sources_requirement/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_requirement/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_sources_requirement/conf.py b/dox_trace/spec/test_input/check_invalid_sources_requirement/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_requirement/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_sources_requirement/index.rst b/dox_trace/spec/test_input/check_invalid_sources_requirement/index.rst new file mode 100644 index 0000000..cb00060 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_requirement/index.rst @@ -0,0 +1,6 @@ +Check Invalid Sources Requirement +================================= + +.. requirement:: SRS_Requirement_InvalidSources + :sources: does/not/exist.cpp + :category: software diff --git a/dox_trace/spec/test_input/check_invalid_sources_spec/Makefile b/dox_trace/spec/test_input/check_invalid_sources_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_sources_spec/conf.py b/dox_trace/spec/test_input/check_invalid_sources_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_sources_spec/index.rst b/dox_trace/spec/test_input/check_invalid_sources_spec/index.rst new file mode 100644 index 0000000..064976e --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_spec/index.rst @@ -0,0 +1,5 @@ +Check Invalid Sources Spec +========================== + +.. spec:: SWA_Spec_InvalidSources + :sources: does/not/exist.cpp diff --git a/dox_trace/spec/test_input/check_invalid_sources_srs/Makefile b/dox_trace/spec/test_input/check_invalid_sources_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_sources_srs/conf.py b/dox_trace/spec/test_input/check_invalid_sources_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_sources_srs/index.rst b/dox_trace/spec/test_input/check_invalid_sources_srs/index.rst new file mode 100644 index 0000000..d328106 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_srs/index.rst @@ -0,0 +1,5 @@ +Check Invalid Sources Srs +========================= + +.. srs:: SRS_Srs_InvalidSources + :sources: does/not/exist.cpp diff --git a/dox_trace/spec/test_input/check_invalid_sources_unit/Makefile b/dox_trace/spec/test_input/check_invalid_sources_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_invalid_sources_unit/conf.py b/dox_trace/spec/test_input/check_invalid_sources_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_invalid_sources_unit/index.rst b/dox_trace/spec/test_input/check_invalid_sources_unit/index.rst new file mode 100644 index 0000000..94803f5 --- /dev/null +++ b/dox_trace/spec/test_input/check_invalid_sources_unit/index.rst @@ -0,0 +1,5 @@ +Check Invalid Sources Unit +========================== + +.. unit:: SMD_Unit_InvalidSources + :sources: Makefile, does/not/exist.cpp diff --git a/dox_trace/spec/test_input/check_naming_double_underscore/Makefile b/dox_trace/spec/test_input/check_naming_double_underscore/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_double_underscore/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_double_underscore/conf.py b/dox_trace/spec/test_input/check_naming_double_underscore/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_double_underscore/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_double_underscore/index.rst b/dox_trace/spec/test_input/check_naming_double_underscore/index.rst new file mode 100644 index 0000000..c594256 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_double_underscore/index.rst @@ -0,0 +1,4 @@ +Check Naming Double Underscore +============================== + +.. spec:: SWA__ diff --git a/dox_trace/spec/test_input/check_naming_lower_case/Makefile b/dox_trace/spec/test_input/check_naming_lower_case/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_lower_case/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_lower_case/conf.py b/dox_trace/spec/test_input/check_naming_lower_case/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_lower_case/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_lower_case/index.rst b/dox_trace/spec/test_input/check_naming_lower_case/index.rst new file mode 100644 index 0000000..c301e12 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_lower_case/index.rst @@ -0,0 +1,4 @@ +Check Naming Lower Case +======================= + +.. spec:: swa_x_y diff --git a/dox_trace/spec/test_input/check_naming_three_underscores/Makefile b/dox_trace/spec/test_input/check_naming_three_underscores/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_three_underscores/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_three_underscores/conf.py b/dox_trace/spec/test_input/check_naming_three_underscores/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_three_underscores/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_three_underscores/index.rst b/dox_trace/spec/test_input/check_naming_three_underscores/index.rst new file mode 100644 index 0000000..4b422b0 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_three_underscores/index.rst @@ -0,0 +1,4 @@ +Check Naming Three Underscores +============================== + +.. spec:: SWA_X_Y_Z diff --git a/dox_trace/spec/test_input/check_naming_too_short/Makefile b/dox_trace/spec/test_input/check_naming_too_short/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_too_short/conf.py b/dox_trace/spec/test_input/check_naming_too_short/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_too_short/index.rst b/dox_trace/spec/test_input/check_naming_too_short/index.rst new file mode 100644 index 0000000..2910154 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short/index.rst @@ -0,0 +1,4 @@ +Check Naming Too Short +====================== + +.. unit:: SMD_ModuleName_ diff --git a/dox_trace/spec/test_input/check_naming_too_short_deprecated/Makefile b/dox_trace/spec/test_input/check_naming_too_short_deprecated/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short_deprecated/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_too_short_deprecated/conf.py b/dox_trace/spec/test_input/check_naming_too_short_deprecated/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short_deprecated/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/check_naming_too_short_deprecated/index.rst b/dox_trace/spec/test_input/check_naming_too_short_deprecated/index.rst new file mode 100644 index 0000000..67d031e --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_too_short_deprecated/index.rst @@ -0,0 +1,4 @@ +Check Naming Too Short Deprecated +================================= + +.. unit:: SMD_ diff --git a/dox_trace/spec/test_input/check_naming_valid/Makefile b/dox_trace/spec/test_input/check_naming_valid/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_valid/conf.py b/dox_trace/spec/test_input/check_naming_valid/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_valid/index.rst b/dox_trace/spec/test_input/check_naming_valid/index.rst new file mode 100644 index 0000000..cf27827 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid/index.rst @@ -0,0 +1,26 @@ +Check Naming Valid +================== + +.. requirement:: InputRequirement + :category: input + +.. information:: InputInformation + :category: input + +.. requirement:: SoftwareRequirement + :category: software + +.. information:: SoftwareInformation + :category: software + +.. spec:: SWA_spec_X + +.. spec:: SMD_spec_X + +.. unit:: SMD_unit_X + +.. interface:: SWA_interface_X + +.. mod:: SWA_mod_X + +.. srs:: SRS_src_X diff --git a/dox_trace/spec/test_input/check_naming_valid_tolerant/Makefile b/dox_trace/spec/test_input/check_naming_valid_tolerant/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid_tolerant/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_valid_tolerant/conf.py b/dox_trace/spec/test_input/check_naming_valid_tolerant/conf.py new file mode 100644 index 0000000..50ccec0 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid_tolerant/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_tolerant_naming_convention = True diff --git a/dox_trace/spec/test_input/check_naming_valid_tolerant/index.rst b/dox_trace/spec/test_input/check_naming_valid_tolerant/index.rst new file mode 100644 index 0000000..52f4316 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_valid_tolerant/index.rst @@ -0,0 +1,26 @@ +Check Naming Valid Deprecated +============================= + +.. requirement:: InputRequirement + :category: input + +.. information:: InputInformation + :category: input + +.. requirement:: SoftwareRequirement + :category: software + +.. information:: SoftwareInformation + :category: software + +.. spec:: SWA_spec + +.. spec:: SMD_spec + +.. unit:: SMD_unit + +.. interface:: SWA_interface + +.. mod:: SWA_mod + +.. srs:: SRS_x_y diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/Makefile b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/conf.py b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/index.rst b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/index.rst new file mode 100644 index 0000000..5f804ec --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_interface/index.rst @@ -0,0 +1,4 @@ +Check Naming Wrong Prefix Interface +=================================== + +.. interface:: SMD_X_Y diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/Makefile b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/conf.py b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/index.rst b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/index.rst new file mode 100644 index 0000000..769fcd2 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_mod/index.rst @@ -0,0 +1,4 @@ +Check Naming Wrong Prefix Mod +============================= + +.. mod:: SMD_X_Y diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/Makefile b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/conf.py b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/index.rst b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/index.rst new file mode 100644 index 0000000..cd11c73 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_srs/index.rst @@ -0,0 +1,4 @@ +Check Naming Wrong Prefix Srs +============================= + +.. srs:: SWA_X_Y diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/Makefile b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/conf.py b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/conf.py new file mode 100644 index 0000000..50ccec0 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_tolerant_naming_convention = True diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/index.rst b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/index.rst new file mode 100644 index 0000000..617572b --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_tolerant/index.rst @@ -0,0 +1,4 @@ +Check Naming Wrong Prefix Tolerant +================================== + +.. unit:: SRS_X diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/Makefile b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/conf.py b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/index.rst b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/index.rst new file mode 100644 index 0000000..1438cd1 --- /dev/null +++ b/dox_trace/spec/test_input/check_naming_wrong_prefix_unit/index.rst @@ -0,0 +1,4 @@ +Check Naming Wrong Prefix Unit +============================== + +.. unit:: SWA_X_Y diff --git a/dox_trace/spec/test_input/check_newline_id/Makefile b/dox_trace/spec/test_input/check_newline_id/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_newline_id/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_newline_id/conf.py b/dox_trace/spec/test_input/check_newline_id/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_newline_id/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_newline_id/index.rst b/dox_trace/spec/test_input/check_newline_id/index.rst new file mode 100644 index 0000000..69b1bb8 --- /dev/null +++ b/dox_trace/spec/test_input/check_newline_id/index.rst @@ -0,0 +1,8 @@ +Check Newline ID +================ + +.. requirement:: SRS_Requirement_Direct + Continue + :category: software + + Content diff --git a/dox_trace/spec/test_input/check_outdated_python/Makefile b/dox_trace/spec/test_input/check_outdated_python/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_python/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_outdated_python/conf.py b/dox_trace/spec/test_input/check_outdated_python/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_python/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_outdated_python/index.rst b/dox_trace/spec/test_input/check_outdated_python/index.rst new file mode 100644 index 0000000..d32291f --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_python/index.rst @@ -0,0 +1,2 @@ +Check Outdated Python +===================== diff --git a/dox_trace/spec/test_input/check_outdated_sphinx/Makefile b/dox_trace/spec/test_input/check_outdated_sphinx/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_sphinx/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_outdated_sphinx/conf.py b/dox_trace/spec/test_input/check_outdated_sphinx/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_sphinx/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_outdated_sphinx/index.rst b/dox_trace/spec/test_input/check_outdated_sphinx/index.rst new file mode 100644 index 0000000..d32291f --- /dev/null +++ b/dox_trace/spec/test_input/check_outdated_sphinx/index.rst @@ -0,0 +1,2 @@ +Check Outdated Python +===================== diff --git a/dox_trace/spec/test_input/check_unique_id/Makefile b/dox_trace/spec/test_input/check_unique_id/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/check_unique_id/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/check_unique_id/conf.py b/dox_trace/spec/test_input/check_unique_id/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/check_unique_id/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/check_unique_id/index.rst b/dox_trace/spec/test_input/check_unique_id/index.rst new file mode 100644 index 0000000..9f3fe28 --- /dev/null +++ b/dox_trace/spec/test_input/check_unique_id/index.rst @@ -0,0 +1,9 @@ +Check Unique ID +=============== + +.. toctree:: + + subpage + +.. requirement:: SRS_Requirement_NotUnique + :category: software diff --git a/dox_trace/spec/test_input/check_unique_id/subpage.rst b/dox_trace/spec/test_input/check_unique_id/subpage.rst new file mode 100644 index 0000000..3be5dc4 --- /dev/null +++ b/dox_trace/spec/test_input/check_unique_id/subpage.rst @@ -0,0 +1,5 @@ +Subpage +======= + +.. requirement:: SRS_Requirement_NotUnique + :category: software diff --git a/dox_trace/spec/test_input/comment/Makefile b/dox_trace/spec/test_input/comment/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment/conf.py b/dox_trace/spec/test_input/comment/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment/index.rst b/dox_trace/spec/test_input/comment/index.rst new file mode 100644 index 0000000..cabb29a --- /dev/null +++ b/dox_trace/spec/test_input/comment/index.rst @@ -0,0 +1,36 @@ +Comment +======= + +Available +--------- + +.. information:: SRS_Information_CommentSet + :comment: Aa + :category: software + +.. requirement:: SRS_Requirement_CommentSet + :comment: Bb + :category: software + +.. information:: InputInformation_CommentSet + :comment: Cc + :category: input + +.. requirement:: InputRequirement_CommentSet + :comment: Dd + :category: input + +Default +------- + +.. information:: SRS_Information_CommentDefault + :category: software + +.. requirement:: SRS_Requirement_CommentDefault + :category: software + +.. information:: InputInformation_CommentDefault + :category: input + +.. requirement:: InputRequirement_CommentDefault + :category: input diff --git a/dox_trace/spec/test_input/comment_interface/Makefile b/dox_trace/spec/test_input/comment_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment_interface/conf.py b/dox_trace/spec/test_input/comment_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment_interface/index.rst b/dox_trace/spec/test_input/comment_interface/index.rst new file mode 100644 index 0000000..e17f8a4 --- /dev/null +++ b/dox_trace/spec/test_input/comment_interface/index.rst @@ -0,0 +1,8 @@ +Comment Interface +================= + +Not Available +------------- + +.. interface:: SWA_Interface_NotAvailable + :comment: not available diff --git a/dox_trace/spec/test_input/comment_mod/Makefile b/dox_trace/spec/test_input/comment_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment_mod/conf.py b/dox_trace/spec/test_input/comment_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment_mod/index.rst b/dox_trace/spec/test_input/comment_mod/index.rst new file mode 100644 index 0000000..141934c --- /dev/null +++ b/dox_trace/spec/test_input/comment_mod/index.rst @@ -0,0 +1,8 @@ +Comment Mod +=========== + +Not Available +------------- + +.. mod:: SWA_Mod_NotAvailable + :comment: not available diff --git a/dox_trace/spec/test_input/comment_spec/Makefile b/dox_trace/spec/test_input/comment_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment_spec/conf.py b/dox_trace/spec/test_input/comment_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment_spec/index.rst b/dox_trace/spec/test_input/comment_spec/index.rst new file mode 100644 index 0000000..034473e --- /dev/null +++ b/dox_trace/spec/test_input/comment_spec/index.rst @@ -0,0 +1,8 @@ +Comment Spec +============ + +Not Available +------------- + +.. spec:: SWA_Spec_NotAvailable + :comment: not available diff --git a/dox_trace/spec/test_input/comment_srs/Makefile b/dox_trace/spec/test_input/comment_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment_srs/conf.py b/dox_trace/spec/test_input/comment_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment_srs/index.rst b/dox_trace/spec/test_input/comment_srs/index.rst new file mode 100644 index 0000000..b41a10c --- /dev/null +++ b/dox_trace/spec/test_input/comment_srs/index.rst @@ -0,0 +1,8 @@ +Comment Srs +=========== + +Not Available +------------- + +.. srs:: SRS_Srs_NotAvailable + :comment: not available diff --git a/dox_trace/spec/test_input/comment_unit/Makefile b/dox_trace/spec/test_input/comment_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/comment_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/comment_unit/conf.py b/dox_trace/spec/test_input/comment_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/comment_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/comment_unit/index.rst b/dox_trace/spec/test_input/comment_unit/index.rst new file mode 100644 index 0000000..c48c538 --- /dev/null +++ b/dox_trace/spec/test_input/comment_unit/index.rst @@ -0,0 +1,8 @@ +Comment Unit +============ + +Not Available +------------- + +.. unit:: SMD_Unit_NotAvailable + :comment: not available diff --git a/dox_trace/spec/test_input/config.dim b/dox_trace/spec/test_input/config.dim new file mode 100644 index 0000000..1e5d68f --- /dev/null +++ b/dox_trace/spec/test_input/config.dim @@ -0,0 +1,10 @@ +Config: + - originator: Abc AG + files: "srs/**/*.dim" + category: software + - originator: Abc AG + files: "swa/**/*.dim" + category: architecture + - originator: Abc AG + files: "smd/**/*.dim" + category: module diff --git a/dox_trace/spec/test_input/config/Makefile b/dox_trace/spec/test_input/config/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/config/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/config/conf.py b/dox_trace/spec/test_input/config/conf.py new file mode 100644 index 0000000..27a71ab --- /dev/null +++ b/dox_trace/spec/test_input/config/conf.py @@ -0,0 +1,19 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": { + "directives": ["requirement", "information", "srs", "spec", "mod", "unit", "interface"], + "categories": ["input", "software"], + "type": "text", + }, +} diff --git a/dox_trace/spec/test_input/config/filled.rst b/dox_trace/spec/test_input/config/filled.rst new file mode 100644 index 0000000..f5ebac9 --- /dev/null +++ b/dox_trace/spec/test_input/config/filled.rst @@ -0,0 +1,105 @@ +Filled +====== + +.. requirement:: Input_ConfigPreview_RequirementDummy + :category: input + :ignore_in_export: + :refs: Input_ConfigPreview_RequirementFilled, Input_ConfigPreview_InformationFilled, + SRS_ConfigPreview_RequirementFilled, SRS_ConfigPreview_InformationFilled, + SRS_ConfigPreview_SrsFilled, SWA_ConfigPreview_SpecFilled, SWA_ConfigPreview_ModFilled, + SWA_ConfigPreview_InterfaceFilled, SMD_ConfigPreview_UnitFilled + :tags: covered + :feature: TheFeature + :change_request: TheCR + +.. requirement:: Input_ConfigPreview_RequirementFilled + :category: input + :ignore_in_export: + :tags: covered + :developer: TheDeveloper + :tester: TheTester + :test_setups: none + :verification_criteria: TheVC + :comment: TheComment + :miscellaneous: TheMisc + :feature: TheFeature + :change_request: TheCR + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + +.. information:: Input_ConfigPreview_InformationFilled + :category: input + :ignore_in_export: + :tags: covered + :comment: TheComment + :miscellaneous: TheMisc + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + +.. requirement:: SRS_ConfigPreview_RequirementFilled + :category: software + :ignore_in_export: + :tags: covered + :developer: TheDeveloper + :tester: TheTester + :test_setups: none + :verification_criteria: TheVC + :comment: TheComment + :sources: filled.rst + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + +.. information:: SRS_ConfigPreview_InformationFilled + :category: software + :ignore_in_export: + :tags: covered + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + +.. srs:: SRS_ConfigPreview_SrsFilled + :ignore_in_export: + :tags: covered + :verification_criteria: TheVC + :sources: filled.rst + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + :developer: Developer + :tester: Tester + +.. spec:: SWA_ConfigPreview_SpecFilled + :ignore_in_export: + :tags: covered + :verification_criteria: TheVC + :sources: filled.rst + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + :developer: Developer + :tester: Tester + +.. mod:: SWA_ConfigPreview_ModFilled + :ignore_in_export: + :developer: TheDeveloper + :reuse: yes + :usage: Commercial + :location: TheLocation + :custom: TheCustom + +.. interface:: SWA_ConfigPreview_InterfaceFilled + :ignore_in_export: + :tags: covered + :developer: TheDeveloper + :tester: TheTester + :verification_criteria: TheVC + :sources: filled.rst + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom + +.. unit:: SMD_ConfigPreview_UnitFilled + :ignore_in_export: + :tags: covered + :developer: TheDeveloper + :tester: TheTester + :verification_criteria: TheVC + :sources: filled.rst + :refs: SWA_ConfigPreview_ModFilled + :custom: TheCustom diff --git a/dox_trace/spec/test_input/config/index.rst b/dox_trace/spec/test_input/config/index.rst new file mode 100644 index 0000000..998dcc9 --- /dev/null +++ b/dox_trace/spec/test_input/config/index.rst @@ -0,0 +1,51 @@ +Config +====== + +Settings +-------- + +.. dox_trace_config:: + +Preview +------- + +Different specification types without any explicit value set: + +.. requirement:: Input_ConfigPreview_Requirement + :category: input + :ignore_in_export: + +.. information:: Input_ConfigPreview_Information + :category: input + :ignore_in_export: + +.. requirement:: SRS_ConfigPreview_Requirement + :category: software + :ignore_in_export: + +.. information:: SRS_ConfigPreview_Information + :category: software + :ignore_in_export: + +.. srs:: SRS_ConfigPreview_Srs + :ignore_in_export: + +.. spec:: SWA_ConfigPreview_Spec + :ignore_in_export: + +.. mod:: SWA_ConfigPreview_Mod + :ignore_in_export: + +.. interface:: SWA_ConfigPreview_Interface + :ignore_in_export: + +.. unit:: SMD_ConfigPreview_Unit + :ignore_in_export: + +Testing Config +-------------- + +.. toctree:: + + filled + special diff --git a/dox_trace/spec/test_input/config/special.rst b/dox_trace/spec/test_input/config/special.rst new file mode 100644 index 0000000..23fcb10 --- /dev/null +++ b/dox_trace/spec/test_input/config/special.rst @@ -0,0 +1,67 @@ +Special Cases +============= + +Struck +------ + +.. spec:: SWA_ConfigPreview_SpecStruck + :ignore_in_export: + :status: invalid + +.. requirement:: SRS_ConfigPreview_RequirementStruck + :category: software + :ignore_in_export: + :status: invalid + +.. mod:: SWA_ConfigPreview_ModStruck + :ignore_in_export: + :status: invalid + +.. unit:: SMD_ConfigPreview_UnitStruck + :ignore_in_export: + :status: invalid + +Tags +---- + +.. spec:: SWA_ConfigPreview_SpecParentTagsParent + :ignore_in_export: + :tags: covered + :refs: SWA_ConfigPreview_SpecParentTagsBoth, SWA_ConfigPreview_SpecParentTagsOnlyParent + +.. spec:: SWA_ConfigPreview_SpecParentTagsNone + :ignore_in_export: + +.. spec:: SWA_ConfigPreview_SpecParentTagsBoth + :ignore_in_export: + :tags: covered + +.. spec:: SWA_ConfigPreview_SpecParentTagsOnlyParent + :ignore_in_export: + +.. spec:: SWA_ConfigPreview_SpecParentTagsOnlyChild + :ignore_in_export: + :tags: covered + +Hide if Empty +------------- + +.. spec:: SWA_ConfigPreview_SpecParentTagsHideIfEmpty + :ignore_in_export: + +Newline For DevTestAttr +----------------------- + +.. requirement:: Input_ConfigPreview_RequirementDevTestAlways + :category: input + :ignore_in_export: + :developer: TheDeveloper + +.. requirement:: Input_ConfigPreview_RequirementDevTestMissing + :category: input + :ignore_in_export: + +.. requirement:: Input_ConfigPreview_RequirementDevTestEmpty + :category: input + :ignore_in_export: + :status: invalid diff --git a/dox_trace/spec/test_input/content/Makefile b/dox_trace/spec/test_input/content/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/content/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/content/conf.py b/dox_trace/spec/test_input/content/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/content/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/content/index.rst b/dox_trace/spec/test_input/content/index.rst new file mode 100644 index 0000000..5f26574 --- /dev/null +++ b/dox_trace/spec/test_input/content/index.rst @@ -0,0 +1,53 @@ +Content +======= + +Missing +------- + +.. requirement:: SRS_Requirement_Missing + :category: software + +.. information:: SRS_Information_Missing + :category: software + +.. requirement:: InputRequirement_Missing + :category: input + +.. information:: InputInformation_Missing + :category: input + +.. srs:: SRS_Srs_Missing + +.. spec:: SWA_Spec_Missing + +.. unit:: SMD_Unit_Missing + +.. interface:: SWA_Interface_Missing + +.. mod:: SWA_Mod_Missing + +Struck +------ + +.. spec:: SWA_Spec_Struck + :status: invalid + +Not Empty +--------- + +.. spec:: SWA_Spec_Content1 + + Some text. + +.. spec:: SWA_Spec_Content2 + + .. code-block:: c++ + + counter = counter + 1; + + End of example. + +.. requirement:: SRS_Requirement_Content3 + :category: software + + :raw-html:`This is bold.` diff --git a/dox_trace/spec/test_input/custom_categories/Makefile b/dox_trace/spec/test_input/custom_categories/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_categories/conf.py b/dox_trace/spec/test_input/custom_categories/conf.py new file mode 100644 index 0000000..1a9a60e --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories/conf.py @@ -0,0 +1,26 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom1": {"directives": ["requirement"], "categories": ["software", "input"], "type": "text"}, + "custom2": { + "directives": ["requirement", "information"], + "categories": ["software"], + "type": "text", + }, + "custom3": {"directives": ["unit"], "categories": ["software"], "type": "text"}, + "custom4": { + "directives": ["requirement"], + "categories": ["system", "software", "input"], + "type": "text", + }, +} diff --git a/dox_trace/spec/test_input/custom_categories/index.rst b/dox_trace/spec/test_input/custom_categories/index.rst new file mode 100644 index 0000000..39346b1 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories/index.rst @@ -0,0 +1,35 @@ +Custom Attributes +================= + +.. requirement:: Custom_ReqInput + :category: input + :custom1: 1 + :custom2: 2 + :custom4: 4 + +.. requirement:: Custom_ReqSystem + :category: system + :custom1: 1 + :custom2: 2 + :custom4: 4 + +.. requirement:: SRS_Custom_ReqSoftware + :category: software + :custom1: 1 + :custom2: 2 + :custom4: 4 + +.. information:: Custom_InfoInput + :category: input + :custom2: 2 + +.. information:: Custom_InfoSystem + :category: system + :custom2: 2 + +.. information:: SRS_Custom_InfoSoftware + :category: software + :custom2: 2 + +.. unit:: SMD_Custom_Unit + :custom3: 3 diff --git a/dox_trace/spec/test_input/custom_categories_invalid_empty/Makefile b/dox_trace/spec/test_input/custom_categories_invalid_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_categories_invalid_empty/conf.py b/dox_trace/spec/test_input/custom_categories_invalid_empty/conf.py new file mode 100644 index 0000000..20d814f --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_empty/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": {"directives": ["requirement"], "categories": [], "type": "text"} +} diff --git a/dox_trace/spec/test_input/custom_categories_invalid_empty/index.rst b/dox_trace/spec/test_input/custom_categories_invalid_empty/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_empty/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_categories_invalid_missing/Makefile b/dox_trace/spec/test_input/custom_categories_invalid_missing/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_missing/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_categories_invalid_missing/conf.py b/dox_trace/spec/test_input/custom_categories_invalid_missing/conf.py new file mode 100644 index 0000000..0ae9328 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_missing/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["requirement"], "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_categories_invalid_missing/index.rst b/dox_trace/spec/test_input/custom_categories_invalid_missing/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_missing/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_categories_invalid_type/Makefile b/dox_trace/spec/test_input/custom_categories_invalid_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_categories_invalid_type/conf.py b/dox_trace/spec/test_input/custom_categories_invalid_type/conf.py new file mode 100644 index 0000000..f3c0c95 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_type/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": {"directives": ["information"], "categories": "software", "type": "text"} +} diff --git a/dox_trace/spec/test_input/custom_categories_invalid_type/index.rst b/dox_trace/spec/test_input/custom_categories_invalid_type/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_type/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_categories_invalid_value/Makefile b/dox_trace/spec/test_input/custom_categories_invalid_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_categories_invalid_value/conf.py b/dox_trace/spec/test_input/custom_categories_invalid_value/conf.py new file mode 100644 index 0000000..53acbb3 --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_value/conf.py @@ -0,0 +1,19 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": { + "directives": ["information"], + "categories": ["software", "hardware"], + "type": "text", + } +} diff --git a/dox_trace/spec/test_input/custom_categories_invalid_value/index.rst b/dox_trace/spec/test_input/custom_categories_invalid_value/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_categories_invalid_value/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_default/Makefile b/dox_trace/spec/test_input/custom_default/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_default/conf.py b/dox_trace/spec/test_input/custom_default/conf.py new file mode 100644 index 0000000..36b7777 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default/conf.py @@ -0,0 +1,23 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom1": {"directives": ["spec"], "type": "text"}, + "custom2": {"directives": ["spec"], "type": "text", "default": ""}, + "custom3": {"directives": ["spec"], "type": "text", "default": "d3"}, + "custom4": {"directives": ["spec"], "type": "enum"}, + "custom5": {"directives": ["spec"], "type": "enum", "default": []}, + "custom6": {"directives": ["spec"], "type": "enum", "default": ["d6", "d7", "d6"]}, + "custom7": {"directives": ["spec"], "type": "refs"}, + "custom8": {"directives": ["spec"], "type": "refs", "default": []}, + "custom9": {"directives": ["spec"], "type": "refs", "default": ["SMD_Custom_R1"]}, +} diff --git a/dox_trace/spec/test_input/custom_default/index.rst b/dox_trace/spec/test_input/custom_default/index.rst new file mode 100644 index 0000000..cfffbc3 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default/index.rst @@ -0,0 +1,22 @@ +Custom Attributes +================= + +.. spec:: SMD_Custom_R1 + +.. spec:: SWA_Custom_R2 + +.. spec:: SWA_Custom_Set + :custom1: 1 + :custom2: 2 + :custom3: 3 + :custom4: 4 + :custom5: 5 + :custom6: 6 + :custom7: SWA_Custom_R2 + :custom8: SWA_Custom_R2 + :custom9: SWA_Custom_R2 + +.. spec:: SWA_Custom_NotSet + +.. spec:: SWA_Custom_Empty + diff --git a/dox_trace/spec/test_input/custom_default_invalid_nontext/Makefile b/dox_trace/spec/test_input/custom_default_invalid_nontext/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_nontext/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_default_invalid_nontext/conf.py b/dox_trace/spec/test_input/custom_default_invalid_nontext/conf.py new file mode 100644 index 0000000..47a1170 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_nontext/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": {"directives": ["unit"], "default": "none", "type": "enum"} +} diff --git a/dox_trace/spec/test_input/custom_default_invalid_nontext/index.rst b/dox_trace/spec/test_input/custom_default_invalid_nontext/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_nontext/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_default_invalid_text/Makefile b/dox_trace/spec/test_input/custom_default_invalid_text/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_text/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_default_invalid_text/conf.py b/dox_trace/spec/test_input/custom_default_invalid_text/conf.py new file mode 100644 index 0000000..a0077c8 --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_text/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": {"directives": ["unit"], "default": ["none"], "type": "text"} +} diff --git a/dox_trace/spec/test_input/custom_default_invalid_text/index.rst b/dox_trace/spec/test_input/custom_default_invalid_text/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_default_invalid_text/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_directives/Makefile b/dox_trace/spec/test_input/custom_directives/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives/conf.py b/dox_trace/spec/test_input/custom_directives/conf.py new file mode 100644 index 0000000..f3ec77d --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives/conf.py @@ -0,0 +1,27 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom1": {"directives": ["unit"], "type": "text"}, + "custom2": {"directives": ["spec"], "type": "text"}, + "custom3": {"directives": ["interface"], "type": "text"}, + "custom4": {"directives": ["mod"], "type": "text"}, + "custom5": {"directives": ["requirement"], "categories": ["software"], "type": "text"}, + "custom6": {"directives": ["information"], "categories": ["software"], "type": "text"}, + "custom7": { + "directives": ["unit", "spec", "interface", "mod", "requirement", "information", "srs"], + "categories": ["software"], + "type": "text", + }, + "custom8": {"directives": ["unit", "unit", "spec", "unit"], "type": "text"}, + "custom9": {"directives": ["srs"], "type": "text"}, +} diff --git a/dox_trace/spec/test_input/custom_directives/index.rst b/dox_trace/spec/test_input/custom_directives/index.rst new file mode 100644 index 0000000..7e7c0f5 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives/index.rst @@ -0,0 +1,34 @@ +Custom Attributes +================= + +.. unit:: SMD_Custom_R1 + :custom1: 1 + :custom7: 7 + :custom8: 8 + +.. spec:: SWA_Custom_R2 + :custom2: 2 + :custom7: 7 + :custom8: 8 + +.. interface:: SWA_Custom_R3 + :custom3: 3 + :custom7: 7 + +.. mod:: SWA_Custom_R4 + :custom4: 4 + :custom7: 7 + +.. requirement:: SRS_Custom_R5 + :custom5: 5 + :custom7: 7 + :category: software + +.. information:: SRS_Custom_R6 + :custom6: 6 + :custom7: 7 + :category: software + +.. srs:: SRS_Custom_R7 + :custom7: 7 + :custom9: 9 diff --git a/dox_trace/spec/test_input/custom_directives_invalid_empty/Makefile b/dox_trace/spec/test_input/custom_directives_invalid_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives_invalid_empty/conf.py b/dox_trace/spec/test_input/custom_directives_invalid_empty/conf.py new file mode 100644 index 0000000..e9e8011 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_empty/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": [], "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_directives_invalid_empty/index.rst b/dox_trace/spec/test_input/custom_directives_invalid_empty/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_empty/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_directives_invalid_missing/Makefile b/dox_trace/spec/test_input/custom_directives_invalid_missing/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_missing/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives_invalid_missing/conf.py b/dox_trace/spec/test_input/custom_directives_invalid_missing/conf.py new file mode 100644 index 0000000..8131721 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_missing/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"type": "text"}} diff --git a/dox_trace/spec/test_input/custom_directives_invalid_missing/index.rst b/dox_trace/spec/test_input/custom_directives_invalid_missing/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_missing/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_directives_invalid_spec/Makefile b/dox_trace/spec/test_input/custom_directives_invalid_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives_invalid_spec/conf.py b/dox_trace/spec/test_input/custom_directives_invalid_spec/conf.py new file mode 100644 index 0000000..ce7ed30 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_spec/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"], "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_directives_invalid_spec/index.rst b/dox_trace/spec/test_input/custom_directives_invalid_spec/index.rst new file mode 100644 index 0000000..5246fea --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_spec/index.rst @@ -0,0 +1,5 @@ +Custom Attributes +================= + +.. spec:: SWA_Custom_Spec + :custom: Only valid for unit diff --git a/dox_trace/spec/test_input/custom_directives_invalid_type/Makefile b/dox_trace/spec/test_input/custom_directives_invalid_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives_invalid_type/conf.py b/dox_trace/spec/test_input/custom_directives_invalid_type/conf.py new file mode 100644 index 0000000..de9b9a2 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_type/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": "unit", "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_directives_invalid_type/index.rst b/dox_trace/spec/test_input/custom_directives_invalid_type/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_type/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_directives_invalid_value/Makefile b/dox_trace/spec/test_input/custom_directives_invalid_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_directives_invalid_value/conf.py b/dox_trace/spec/test_input/custom_directives_invalid_value/conf.py new file mode 100644 index 0000000..11df0b7 --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_value/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["file"], "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_directives_invalid_value/index.rst b/dox_trace/spec/test_input/custom_directives_invalid_value/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_directives_invalid_value/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_export/Makefile b/dox_trace/spec/test_input/custom_export/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_export/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_export/conf.py b/dox_trace/spec/test_input/custom_export/conf.py new file mode 100644 index 0000000..6b02135 --- /dev/null +++ b/dox_trace/spec/test_input/custom_export/conf.py @@ -0,0 +1,20 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom1": {"directives": ["unit"], "type": "text", "export": "yes"}, + "custom2": {"directives": ["unit"], "type": "text", "export": "no"}, + "custom3": {"directives": ["unit"], "type": "text"}, + "custom_complex_text": {"directives": ["mod"], "type": "text", "export": "yes"}, + "custom_enum": {"directives": ["mod"], "type": "enum", "export": "yes"}, + "custom_refs": {"directives": ["mod"], "type": "refs", "export": "yes"}, +} diff --git a/dox_trace/spec/test_input/custom_export/index.rst b/dox_trace/spec/test_input/custom_export/index.rst new file mode 100644 index 0000000..af73e8a --- /dev/null +++ b/dox_trace/spec/test_input/custom_export/index.rst @@ -0,0 +1,21 @@ +.. _custom_attr: + +Custom Attributes +================= + +.. unit:: SMD_Custom_R0 + +.. unit:: SMD_Custom_R1 + :custom1: 1 + :custom2: 2 + :custom3: 3 + +.. mod:: SWA_Custom_R2 + :custom_complex_text: **bold** + - first + - second + :custom_enum: a,b,b,c + :custom_refs: SMD_Custom_R0,SWA_Custom_R2, , SMD_Custom_R1 + +.. mod:: SWA_Custom_R3 + :custom_refs: custom_attr diff --git a/dox_trace/spec/test_input/custom_export_invalid_type/Makefile b/dox_trace/spec/test_input/custom_export_invalid_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_export_invalid_type/conf.py b/dox_trace/spec/test_input/custom_export_invalid_type/conf.py new file mode 100644 index 0000000..009178d --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_type/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"], "export": 123, "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_export_invalid_type/index.rst b/dox_trace/spec/test_input/custom_export_invalid_type/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_type/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_export_invalid_value/Makefile b/dox_trace/spec/test_input/custom_export_invalid_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_export_invalid_value/conf.py b/dox_trace/spec/test_input/custom_export_invalid_value/conf.py new file mode 100644 index 0000000..abe2f36 --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_value/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"], "export": "nope", "type": "text"}} diff --git a/dox_trace/spec/test_input/custom_export_invalid_value/index.rst b/dox_trace/spec/test_input/custom_export_invalid_value/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_export_invalid_value/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_name/Makefile b/dox_trace/spec/test_input/custom_name/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_name/conf.py b/dox_trace/spec/test_input/custom_name/conf.py new file mode 100644 index 0000000..7a3ee38 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom": {"directives": ["spec"], "type": "text"}, +} diff --git a/dox_trace/spec/test_input/custom_name/index.rst b/dox_trace/spec/test_input/custom_name/index.rst new file mode 100644 index 0000000..343947c --- /dev/null +++ b/dox_trace/spec/test_input/custom_name/index.rst @@ -0,0 +1,5 @@ +Custom Attributes +================= + +.. spec:: SWA_Custom_Set + :custom: 123 diff --git a/dox_trace/spec/test_input/custom_name_invalid_exists/Makefile b/dox_trace/spec/test_input/custom_name_invalid_exists/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_exists/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_name_invalid_exists/conf.py b/dox_trace/spec/test_input/custom_name_invalid_exists/conf.py new file mode 100644 index 0000000..aa1e170 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_exists/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"review_status": {"directives": ["unit"], "type": "enum"}} diff --git a/dox_trace/spec/test_input/custom_name_invalid_exists/index.rst b/dox_trace/spec/test_input/custom_name_invalid_exists/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_exists/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_name_invalid_text/Makefile b/dox_trace/spec/test_input/custom_name_invalid_text/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_text/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_name_invalid_text/conf.py b/dox_trace/spec/test_input/custom_name_invalid_text/conf.py new file mode 100644 index 0000000..9b47cf7 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_text/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"text": {"directives": ["unit"], "type": "enum"}} diff --git a/dox_trace/spec/test_input/custom_name_invalid_text/index.rst b/dox_trace/spec/test_input/custom_name_invalid_text/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_text/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_name_invalid_type/Makefile b/dox_trace/spec/test_input/custom_name_invalid_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_name_invalid_type/conf.py b/dox_trace/spec/test_input/custom_name_invalid_type/conf.py new file mode 100644 index 0000000..0fc8134 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_type/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {123: {"directives": ["unit"], "type": "enum"}} diff --git a/dox_trace/spec/test_input/custom_name_invalid_type/index.rst b/dox_trace/spec/test_input/custom_name_invalid_type/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_type/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_name_invalid_value/Makefile b/dox_trace/spec/test_input/custom_name_invalid_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_name_invalid_value/conf.py b/dox_trace/spec/test_input/custom_name_invalid_value/conf.py new file mode 100644 index 0000000..51d2d0a --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_value/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": "text"} diff --git a/dox_trace/spec/test_input/custom_name_invalid_value/index.rst b/dox_trace/spec/test_input/custom_name_invalid_value/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_name_invalid_value/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_type/Makefile b/dox_trace/spec/test_input/custom_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_type/conf.py b/dox_trace/spec/test_input/custom_type/conf.py new file mode 100644 index 0000000..eaa4301 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type/conf.py @@ -0,0 +1,17 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = { + "custom_complex_text": {"directives": ["spec"], "type": "text"}, + "custom2": {"directives": ["spec"], "type": "enum"}, + "custom3": {"directives": ["spec"], "type": "refs"}, +} diff --git a/dox_trace/spec/test_input/custom_type/index.rst b/dox_trace/spec/test_input/custom_type/index.rst new file mode 100644 index 0000000..ab369f4 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type/index.rst @@ -0,0 +1,27 @@ +.. _custom_attr: + +Custom Attributes +================= + +.. spec:: SMD_Custom_R1 + +.. spec:: SWA_Custom_R2 + +.. spec:: SWA_Custom_S1 + :custom_complex_text: 1 + :custom2: 2 + :custom3: SMD_Custom_R1 + +.. spec:: SWA_Custom_S2 + :custom_complex_text: **bold** + - bullet1 + - bullet2 + not_bold + :custom2: 2,3,, 2 + :custom3: SMD_Custom_R1, SWA_Custom_R2, SMD_Custom_R1, custom_attr + +.. spec:: SWA_Custom_S3 + :custom3: SMD_Custom_R1 + +.. spec:: SWA_Custom_S4 + :custom3: custom_attr \ No newline at end of file diff --git a/dox_trace/spec/test_input/custom_type_invalid_missing/Makefile b/dox_trace/spec/test_input/custom_type_invalid_missing/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_missing/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_type_invalid_missing/conf.py b/dox_trace/spec/test_input/custom_type_invalid_missing/conf.py new file mode 100644 index 0000000..7b60543 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_missing/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"]}} diff --git a/dox_trace/spec/test_input/custom_type_invalid_missing/index.rst b/dox_trace/spec/test_input/custom_type_invalid_missing/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_missing/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_type_invalid_type/Makefile b/dox_trace/spec/test_input/custom_type_invalid_type/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_type/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_type_invalid_type/conf.py b/dox_trace/spec/test_input/custom_type_invalid_type/conf.py new file mode 100644 index 0000000..4cc7963 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_type/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"], "type": 123}} diff --git a/dox_trace/spec/test_input/custom_type_invalid_type/index.rst b/dox_trace/spec/test_input/custom_type_invalid_type/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_type/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/custom_type_invalid_value/Makefile b/dox_trace/spec/test_input/custom_type_invalid_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/custom_type_invalid_value/conf.py b/dox_trace/spec/test_input/custom_type_invalid_value/conf.py new file mode 100644 index 0000000..7772f5f --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_value/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = "Test Project" + +dox_trace_custom_attributes = {"custom": {"directives": ["unit"], "type": "nope"}} diff --git a/dox_trace/spec/test_input/custom_type_invalid_value/index.rst b/dox_trace/spec/test_input/custom_type_invalid_value/index.rst new file mode 100644 index 0000000..92018ae --- /dev/null +++ b/dox_trace/spec/test_input/custom_type_invalid_value/index.rst @@ -0,0 +1,4 @@ +Custom Attributes +================= + +None diff --git a/dox_trace/spec/test_input/derived_change_request/Makefile b/dox_trace/spec/test_input/derived_change_request/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/derived_change_request/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/derived_change_request/conf.py b/dox_trace/spec/test_input/derived_change_request/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/derived_change_request/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/derived_change_request/index.rst b/dox_trace/spec/test_input/derived_change_request/index.rst new file mode 100644 index 0000000..37d6912 --- /dev/null +++ b/dox_trace/spec/test_input/derived_change_request/index.rst @@ -0,0 +1,119 @@ +Derived Change Request +====================== + +Shown +----- + +.. requirement:: SRS_Requirement_Shown + :category: software + +.. spec:: SWA_Spec_Shown + +.. unit:: SMD_Unit_Shown + +.. interface:: SWA_Interface_Shown + +.. srs:: SRS_Srs_Shown + +Not Shown +--------- + +.. requirement:: InputRequirement_NotShown + :category: input + +.. information:: InputInformation_NotShown + :category: input + +.. information:: SRS_Information_NotShown + :category: software + +.. mod:: SWA_Mod_NotShown + +Parent and Grandparents +----------------------- + +.. requirement:: Requirement_H + :category: input + :refs: Requirement_J + :change_request: H + +.. requirement:: Requirement_I + :category: input + :refs: Requirement_K + :change_request: I + +.. requirement:: Requirement_J + :category: input + :refs: SRS_Requirement_child + :change_request: J + +.. requirement:: Requirement_K + :category: input + :refs: SRS_Requirement_child + :change_request: K + +.. requirement:: Requirement_L + :category: input + :refs: SRS_Req_Parent + :change_request: L + +.. requirement:: SRS_Req_Parent + :refs: SRS_Requirement_child + :category: software + +.. requirement:: SRS_Requirement_child + :category: software + +Dismiss +------- + +.. requirement:: Requirement_A + :refs: Requirement_C, SWA_Spec_unique + :change_request: A + :category: input + +.. requirement:: Requirement_B + :refs: SWA_Spec_strike, SRS_information_notStruck, SWA_Spec_unique + :change_request: B + :category: input + +.. requirement:: Requirement_C + :refs: SWA_Spec_ignoreBackRefs + :change_request: C + :status: invalid + :category: input + +.. spec:: SWA_Spec_strike + :refs: SWA_Spec_ignoreBackRefs + :status: invalid + +.. information:: SRS_information_notStruck + :refs: SWA_Spec_ignoreBackRefs + :category: software + +.. spec:: SWA_Spec_ignoreBackRefs + +Unique +------ + +.. requirement:: Requirement_B2 + :refs: SWA_Spec_unique + :change_request: B + :category: input + +.. spec:: SWA_Spec_unique + +Multiline +--------- + +.. requirement:: Requirement_M1 + :refs: SWA_Spec_multi + :change_request: :raw-html:`X
    Y` + :category: input + +.. requirement:: Requirement_M2 + :refs: SWA_Spec_multi + :change_request: :raw-html:`X` + :category: input + +.. spec:: SWA_Spec_multi \ No newline at end of file diff --git a/dox_trace/spec/test_input/derived_feature/Makefile b/dox_trace/spec/test_input/derived_feature/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/derived_feature/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/derived_feature/conf.py b/dox_trace/spec/test_input/derived_feature/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/derived_feature/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/derived_feature/index.rst b/dox_trace/spec/test_input/derived_feature/index.rst new file mode 100644 index 0000000..3bfd207 --- /dev/null +++ b/dox_trace/spec/test_input/derived_feature/index.rst @@ -0,0 +1,119 @@ +Derived Feature +=============== + +Shown +----- + +.. requirement:: SRS_Requirement_Shown + :category: software + +.. spec:: SWA_Spec_Shown + +.. unit:: SMD_Unit_Shown + +.. interface:: SWA_Interface_Shown + +.. srs:: SRS_Srs_Shown + +Not Shown +--------- + +.. requirement:: InputRequirement_NotShown + :category: input + +.. information:: InputInformation_NotShown + :category: input + +.. information:: SRS_Information_NotShown + :category: software + +.. mod:: SWA_Mod_NotShown + +Parent and Grandparents +----------------------- + +.. requirement:: Requirement_H + :category: input + :refs: Requirement_J + :feature: H + +.. requirement:: Requirement_I + :category: input + :refs: Requirement_K + :feature: I + +.. requirement:: Requirement_J + :category: input + :refs: SRS_Requirement_child + :feature: J + +.. requirement:: Requirement_K + :category: input + :refs: SRS_Requirement_child + :feature: K + +.. requirement:: Requirement_L + :category: input + :refs: SRS_Req_Parent + :feature: L + +.. requirement:: SRS_Req_Parent + :refs: SRS_Requirement_child + :category: software + +.. requirement:: SRS_Requirement_child + :category: software + +Dismiss +------- + +.. requirement:: Requirement_A + :refs: Requirement_C, SWA_Spec_unique + :feature: A + :category: input + +.. requirement:: Requirement_B + :refs: SWA_Spec_strike, SRS_information_notStruck, SWA_Spec_unique + :feature: B + :category: input + +.. requirement:: Requirement_C + :refs: SWA_Spec_ignoreBackRefs + :feature: C + :status: invalid + :category: input + +.. spec:: SWA_Spec_strike + :refs: SWA_Spec_ignoreBackRefs + :status: invalid + +.. information:: SRS_information_notStruck + :refs: SWA_Spec_ignoreBackRefs + :category: software + +.. spec:: SWA_Spec_ignoreBackRefs + +Unique +------ + +.. requirement:: Requirement_B2 + :refs: SWA_Spec_unique + :feature: B + :category: input + +.. spec:: SWA_Spec_unique + +Multiline +--------- + +.. requirement:: Requirement_M1 + :refs: SWA_Spec_multi + :feature: :raw-html:`X
    Y` + :category: input + +.. requirement:: Requirement_M2 + :refs: SWA_Spec_multi + :feature: :raw-html:`X` + :category: input + +.. spec:: SWA_Spec_multi diff --git a/dox_trace/spec/test_input/developer/Makefile b/dox_trace/spec/test_input/developer/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/developer/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/developer/conf.py b/dox_trace/spec/test_input/developer/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/developer/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/developer/index.rst b/dox_trace/spec/test_input/developer/index.rst new file mode 100644 index 0000000..548c8dc --- /dev/null +++ b/dox_trace/spec/test_input/developer/index.rst @@ -0,0 +1,61 @@ +Developer +========= + +Available +--------- + +.. requirement:: SRS_Requirement_DeveloperXY + :developer: XY + :category: software + +.. requirement:: InputRequirement_DeveloperXY + :developer: XY + :category: input + +.. srs:: SRS_Srs_DeveloperXY + :developer: XY + +.. spec:: SWA_Spec_DeveloperXY + :developer: XY + +.. unit:: SMD_Unit_DeveloperXY + :developer: XY + +.. interface:: SWA_Interface_DeveloperXY + :developer: XY + +.. mod:: SWA_Mod_DeveloperXY + :developer: XY + +Default +------- + +.. requirement:: SRS_Requirement_DeveloperDefault + :category: software + +.. requirement:: InputRequirement_DeveloperDefault + :category: input + +.. srs:: SRS_Srs_DeveloperDefault + +.. spec:: SWA_Spec_DeveloperDefault + +.. unit:: SMD_Unit_DeveloperDefault + +.. interface:: SWA_Interface_DeveloperDefault + +.. mod:: SWA_Mod_DeveloperDefault + +Additional +---------- + +.. requirement:: SRS_Requirement_DeveloperDefaultStruck + :category: software + :status: invalid + +.. requirement:: InputRequirement_DeveloperDefaultStruck + :category: input + :status: invalid + +.. srs:: SRS_Srs_DeveloperDefaultStruck + :status: invalid diff --git a/dox_trace/spec/test_input/developer_information/Makefile b/dox_trace/spec/test_input/developer_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/developer_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/developer_information/conf.py b/dox_trace/spec/test_input/developer_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/developer_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/developer_information/index.rst b/dox_trace/spec/test_input/developer_information/index.rst new file mode 100644 index 0000000..8e66e77 --- /dev/null +++ b/dox_trace/spec/test_input/developer_information/index.rst @@ -0,0 +1,9 @@ +Developer Information +===================== + +Not Available +------------- + +.. information:: SRS_Information_Developer + :developer: not_available + :category: software diff --git a/dox_trace/spec/test_input/directives_no_empty_line/Makefile b/dox_trace/spec/test_input/directives_no_empty_line/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_empty_line/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/directives_no_empty_line/conf.py b/dox_trace/spec/test_input/directives_no_empty_line/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_empty_line/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/directives_no_empty_line/index.rst b/dox_trace/spec/test_input/directives_no_empty_line/index.rst new file mode 100644 index 0000000..b7eb0f5 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_empty_line/index.rst @@ -0,0 +1,6 @@ +Directives No Empty Line +======================== + +.. requirement:: Req_ID + :status: valid + Content diff --git a/dox_trace/spec/test_input/directives_no_id/Makefile b/dox_trace/spec/test_input/directives_no_id/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_id/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/directives_no_id/conf.py b/dox_trace/spec/test_input/directives_no_id/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_id/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/directives_no_id/index.rst b/dox_trace/spec/test_input/directives_no_id/index.rst new file mode 100644 index 0000000..f559667 --- /dev/null +++ b/dox_trace/spec/test_input/directives_no_id/index.rst @@ -0,0 +1,5 @@ +Directives No ID +================ + +.. requirement:: + :status: valid diff --git a/dox_trace/spec/test_input/directives_valid/Makefile b/dox_trace/spec/test_input/directives_valid/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/directives_valid/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/directives_valid/conf.py b/dox_trace/spec/test_input/directives_valid/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/directives_valid/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/directives_valid/index.rst b/dox_trace/spec/test_input/directives_valid/index.rst new file mode 100644 index 0000000..a120dd8 --- /dev/null +++ b/dox_trace/spec/test_input/directives_valid/index.rst @@ -0,0 +1,34 @@ +Directives Valid +================ + +Types +----- + +.. requirement:: SRS_Requirement_Type + :category: software + +.. information:: SRS_Information_Type + :category: software + +.. srs:: SRS_Srs_Type + +.. spec:: SWA_Spec_Type + +.. unit:: SMD_Unit_Type + +.. interface:: SWA_Interface_Type + +.. mod:: SWA_Mod_Type + +Attribute +--------- + +.. spec:: SWA_Spec_Attribute + :status: valid + +Content +------- + +.. spec:: SWA_Spec_Content + + Some content. diff --git a/dox_trace/spec/test_input/enclosed/Makefile b/dox_trace/spec/test_input/enclosed/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/enclosed/a.txt b/dox_trace/spec/test_input/enclosed/a.txt new file mode 100644 index 0000000..53a90bf --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/a.txt @@ -0,0 +1 @@ +Empty diff --git a/dox_trace/spec/test_input/enclosed/b/b.txt b/dox_trace/spec/test_input/enclosed/b/b.txt new file mode 100644 index 0000000..53a90bf --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/b/b.txt @@ -0,0 +1 @@ +Empty diff --git a/dox_trace/spec/test_input/enclosed/c.txt b/dox_trace/spec/test_input/enclosed/c.txt new file mode 100644 index 0000000..53a90bf --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/c.txt @@ -0,0 +1 @@ +Empty diff --git a/dox_trace/spec/test_input/enclosed/conf.py b/dox_trace/spec/test_input/enclosed/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/enclosed/index.rst b/dox_trace/spec/test_input/enclosed/index.rst new file mode 100644 index 0000000..21601a3 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed/index.rst @@ -0,0 +1,15 @@ +Enclosed +======== + +Just testing... + +.. enclosed:: + + a.txt + b/b.txt + +.. enclosed:: + +.. enclosed:: + + c.txt diff --git a/dox_trace/spec/test_input/enclosed_invalid/Makefile b/dox_trace/spec/test_input/enclosed_invalid/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed_invalid/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/enclosed_invalid/conf.py b/dox_trace/spec/test_input/enclosed_invalid/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed_invalid/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/enclosed_invalid/index.rst b/dox_trace/spec/test_input/enclosed_invalid/index.rst new file mode 100644 index 0000000..b560722 --- /dev/null +++ b/dox_trace/spec/test_input/enclosed_invalid/index.rst @@ -0,0 +1,8 @@ +Enclosed Invalid +================ + +Just testing... + +.. enclosed:: + + d.txt diff --git a/dox_trace/spec/test_input/export/Makefile b/dox_trace/spec/test_input/export/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/export/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/export/conf.py b/dox_trace/spec/test_input/export/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/export/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/export/index.rst b/dox_trace/spec/test_input/export/index.rst new file mode 100644 index 0000000..ffc12f5 --- /dev/null +++ b/dox_trace/spec/test_input/export/index.rst @@ -0,0 +1,34 @@ +Export +====== + +.. toctree:: + + subfolder/a + subfolder/b + subfolder/b/c + subfolder/b/d + +Types +----- + +.. requirement:: InputRequirement_Type + :category: input + +.. information:: InputInformation_Type + :category: input + +.. requirement:: SRS_Requirement_Type + :category: software + +.. information:: SRS_Information_Type + :category: software + +.. srs:: SRS_Srs_Type + +.. spec:: SWA_Spec_Type + +.. unit:: SMD_Unit_Type + +.. interface:: SWA_Interface_Type + +.. mod:: SWA_Mod_Type diff --git a/dox_trace/spec/test_input/export/subfolder/a.rst b/dox_trace/spec/test_input/export/subfolder/a.rst new file mode 100644 index 0000000..538a260 --- /dev/null +++ b/dox_trace/spec/test_input/export/subfolder/a.rst @@ -0,0 +1,8 @@ +Chapter A +========= + +.. spec:: SMD_ModA_1 + +.. spec:: SWA_ModA_2 + +.. spec:: SWA_ModA_3 diff --git a/dox_trace/spec/test_input/export/subfolder/b.rst b/dox_trace/spec/test_input/export/subfolder/b.rst new file mode 100644 index 0000000..2b8bc58 --- /dev/null +++ b/dox_trace/spec/test_input/export/subfolder/b.rst @@ -0,0 +1,7 @@ +Chapter B +========= + +.. spec:: SWA_ModB_2 + +.. spec:: SMD_ModB_1 + diff --git a/dox_trace/spec/test_input/export/subfolder/b/c.rst b/dox_trace/spec/test_input/export/subfolder/b/c.rst new file mode 100644 index 0000000..f030f82 --- /dev/null +++ b/dox_trace/spec/test_input/export/subfolder/b/c.rst @@ -0,0 +1,7 @@ +Chapter C +========= + +.. spec:: SMD_ModC_1 + +.. spec:: SWA_ModC_2 + diff --git a/dox_trace/spec/test_input/export/subfolder/b/d.rst b/dox_trace/spec/test_input/export/subfolder/b/d.rst new file mode 100644 index 0000000..f079548 --- /dev/null +++ b/dox_trace/spec/test_input/export/subfolder/b/d.rst @@ -0,0 +1,4 @@ +Chapter D +========= + +No specs etc... diff --git a/dox_trace/spec/test_input/export_invalid_config/Makefile b/dox_trace/spec/test_input/export_invalid_config/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/export_invalid_config/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/export_invalid_config/conf.py b/dox_trace/spec/test_input/export_invalid_config/conf.py new file mode 100644 index 0000000..6a7f8e1 --- /dev/null +++ b/dox_trace/spec/test_input/export_invalid_config/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = ":invalid\n\0invalid:" diff --git a/dox_trace/spec/test_input/export_invalid_config/index.rst b/dox_trace/spec/test_input/export_invalid_config/index.rst new file mode 100644 index 0000000..dea617e --- /dev/null +++ b/dox_trace/spec/test_input/export_invalid_config/index.rst @@ -0,0 +1,4 @@ +Export Invalid Config +===================== + +.. spec:: SWA_Test_Config diff --git a/dox_trace/spec/test_input/export_no_config/Makefile b/dox_trace/spec/test_input/export_no_config/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_config/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/export_no_config/conf.py b/dox_trace/spec/test_input/export_no_config/conf.py new file mode 100644 index 0000000..1889564 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_config/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +# no config +# dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/export_no_config/index.rst b/dox_trace/spec/test_input/export_no_config/index.rst new file mode 100644 index 0000000..cc5af54 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_config/index.rst @@ -0,0 +1,4 @@ +Export No Config +================ + +.. spec:: SWA_Test_Config diff --git a/dox_trace/spec/test_input/export_no_srs/Makefile b/dox_trace/spec/test_input/export_no_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/export_no_srs/conf.py b/dox_trace/spec/test_input/export_no_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/export_no_srs/index.rst b/dox_trace/spec/test_input/export_no_srs/index.rst new file mode 100644 index 0000000..fefa616 --- /dev/null +++ b/dox_trace/spec/test_input/export_no_srs/index.rst @@ -0,0 +1,6 @@ +Export +====== + +.. spec:: SWA_Spec_Type + +.. unit:: SMD_Unit_Type diff --git a/dox_trace/spec/test_input/feature/Makefile b/dox_trace/spec/test_input/feature/Makefile new file mode 100644 index 0000000..787c0fd --- /dev/null +++ b/dox_trace/spec/test_input/feature/Makefile @@ -0,0 +1,10 @@ + +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature/conf.py b/dox_trace/spec/test_input/feature/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature/index.rst b/dox_trace/spec/test_input/feature/index.rst new file mode 100644 index 0000000..437e136 --- /dev/null +++ b/dox_trace/spec/test_input/feature/index.rst @@ -0,0 +1,22 @@ +Feature +======= + +Available +--------- + +.. requirement:: SRS_Requirement_FeatureSet + :feature: Bb + :category: software + +.. requirement:: InputRequirement_FeatureSet + :feature: Dd + :category: input + +Default +------- + +.. requirement:: SRS_Requirement_FeatureDefault + :category: software + +.. requirement:: InputRequirement_FeatureDefault + :category: input diff --git a/dox_trace/spec/test_input/feature_information/Makefile b/dox_trace/spec/test_input/feature_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_information/conf.py b/dox_trace/spec/test_input/feature_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_information/index.rst b/dox_trace/spec/test_input/feature_information/index.rst new file mode 100644 index 0000000..5ccdf85 --- /dev/null +++ b/dox_trace/spec/test_input/feature_information/index.rst @@ -0,0 +1,9 @@ +Feature Information +=================== + +Not Available +------------- + +.. information:: SRS_Information_NotAvailable + :feature: not available + :category: software diff --git a/dox_trace/spec/test_input/feature_interface/Makefile b/dox_trace/spec/test_input/feature_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_interface/conf.py b/dox_trace/spec/test_input/feature_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_interface/index.rst b/dox_trace/spec/test_input/feature_interface/index.rst new file mode 100644 index 0000000..cea0550 --- /dev/null +++ b/dox_trace/spec/test_input/feature_interface/index.rst @@ -0,0 +1,8 @@ +Feature Interface +================= + +Not Available +------------- + +.. interface:: SWA_Interface_NotAvailable + :feature: not available diff --git a/dox_trace/spec/test_input/feature_mod/Makefile b/dox_trace/spec/test_input/feature_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_mod/conf.py b/dox_trace/spec/test_input/feature_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_mod/index.rst b/dox_trace/spec/test_input/feature_mod/index.rst new file mode 100644 index 0000000..8b3562d --- /dev/null +++ b/dox_trace/spec/test_input/feature_mod/index.rst @@ -0,0 +1,8 @@ +Feature Mod +=========== + +Not Available +------------- + +.. mod:: SWA_Mod_NotAvailable + :feature: not available diff --git a/dox_trace/spec/test_input/feature_spec/Makefile b/dox_trace/spec/test_input/feature_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_spec/conf.py b/dox_trace/spec/test_input/feature_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_spec/index.rst b/dox_trace/spec/test_input/feature_spec/index.rst new file mode 100644 index 0000000..79c5e2e --- /dev/null +++ b/dox_trace/spec/test_input/feature_spec/index.rst @@ -0,0 +1,8 @@ +Feature Spec +============ + +Not Available +------------- + +.. spec:: SWA_Spec_NotAvailable + :feature: not available diff --git a/dox_trace/spec/test_input/feature_srs/Makefile b/dox_trace/spec/test_input/feature_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_srs/conf.py b/dox_trace/spec/test_input/feature_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_srs/index.rst b/dox_trace/spec/test_input/feature_srs/index.rst new file mode 100644 index 0000000..057a6ec --- /dev/null +++ b/dox_trace/spec/test_input/feature_srs/index.rst @@ -0,0 +1,8 @@ +Feature Srs +=========== + +Not Available +------------- + +.. srs:: SRS_Srs_NotAvailable + :feature: not available diff --git a/dox_trace/spec/test_input/feature_unit/Makefile b/dox_trace/spec/test_input/feature_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/feature_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/feature_unit/conf.py b/dox_trace/spec/test_input/feature_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/feature_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/feature_unit/index.rst b/dox_trace/spec/test_input/feature_unit/index.rst new file mode 100644 index 0000000..cd433b5 --- /dev/null +++ b/dox_trace/spec/test_input/feature_unit/index.rst @@ -0,0 +1,8 @@ +Feature Unit +============ + +Not Available +------------- + +.. unit:: SMD_Unit_NotAvailable + :feature: not available diff --git a/dox_trace/spec/test_input/general/Makefile b/dox_trace/spec/test_input/general/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/general/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/general/conf.py b/dox_trace/spec/test_input/general/conf.py new file mode 100644 index 0000000..e43b1cc --- /dev/null +++ b/dox_trace/spec/test_input/general/conf.py @@ -0,0 +1,13 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_custom_attributes = { + "custom_complex_text": {"directives": ["srs"], "type": "text", "export": "yes"} +} diff --git a/dox_trace/spec/test_input/general/index.rst b/dox_trace/spec/test_input/general/index.rst new file mode 100644 index 0000000..bfa5edc --- /dev/null +++ b/dox_trace/spec/test_input/general/index.rst @@ -0,0 +1,175 @@ +General +======= + +Anchor +------ + +.. requirement:: SRS_Requirement_Anchor + :category: software + +.. information:: SRS_Information_Anchor + :category: software + +.. srs:: SRS_Srs_Anchor + +.. spec:: SWA_Spec_Anchor + +.. unit:: SMD_Unit_Anchor + +.. interface:: SWA_Interface_Anchor + +- :ref:`SRS_Requirement_Anchor` +- :ref:`SRS_Information_Anchor` +- :ref:`SRS_Srs_Anchor` +- :ref:`SWA_Spec_Anchor` +- :ref:`SMD_Unit_Anchor` +- :ref:`SWA_Interface_Anchor` + +Stripped and Empty +------------------ + +.. spec:: SWA_Spec_NotSpecified + +.. spec:: SWA_Spec_NoValue + :status: + +.. spec:: SWA_Spec_DoubleSingle + :status: " '' " + +.. spec:: SWA_Spec_SingleDouble + :status: ' "" ' + +.. spec:: SWA_Spec_Spaces + :status: ' ' + +.. spec:: SWA_Spec_Stripped + :status: ' valid ' + +Multi +----- + +.. unit:: SMD_Unit_MultiStripAndUnique + :tags: obd,, swa, smd, "",'' ,swa + :verification_methods: on_target,, on_target, off_target, "",'' ,manual + :sources: conf.py,, index.rst, conf.py, "",'' ,Makefile + :refs: SRS_Requirement_Anchor,, SRS_Information_Anchor, SRS_Requirement_Anchor, "",'' ,SMD_Unit_Anchor + +.. unit:: SMD_Unit_MultiEmpty + :tags: , + :verification_methods: ,, + :sources: , , , + :refs: "",'' + + SubheadingMulti + +++++++++++++++ + + SubheadingMulti2 + ~~~~~~~~~~~~~~~~ + +Free +---- + +.. unit:: SMD_Unit_Free + :verification_criteria: ,, + :status: ,, + :developer: ,, + :tester: ,, + :asil: ,, + :cal: ,, + :review_status: ,, + + .. _anchor1: + + SubheadingFreeUnit + ++++++++++++++++++ + + Some text. + + SubheadingFreeUnit2 + ~~~~~~~~~~~~~~~~~~~ + + Some text. + + .. _anchor2: + + SubheadingFreeUnit3 + ~~~~~~~~~~~~~~~~~~~ + + .. code-block:: + + Some code. + + SubheadingFreeUnit4 + ~~~~~~~~~~~~~~~~~~~ + + Some text. + +.. requirement:: Requirement_Free + :category: input + :feature: " ,, " + :change_request: ',,' + :comment: ,, + :miscellaneous: ,, + + Some text. + + Subheading + ++++++++++ + + Some text. + + Subheading2 + ~~~~~~~~~~~ + + .. code-block:: c++ + + variable = 123; + +Newlines Content +---------------- + +.. unit:: SMD_Unit_BlockBeforeFirstHeading + + Blah + + .. code-block:: c++ + + variable = 123; + + SubheadingFreeUnit + ++++++++++++++++++ + +Newlines Attribute +------------------ + +.. srs:: SRS_Requirement_NewLine1 + :custom_complex_text: No newline here + +.. srs:: SRS_Requirement_NewLine2 + :custom_complex_text: + No newline here + +.. srs:: SRS_Requirement_NewLine3 + :custom_complex_text: No \ + newline \ + here \ + \ + +.. srs:: SRS_Requirement_NewLine4 + :custom_complex_text: \ + No newline here + +.. srs:: SRS_Requirement_NewLine5 + :custom_complex_text: + No newline \ + here + +.. srs:: SRS_Requirement_NewLine6 + :custom_complex_text: Has + three + lines + +.. srs:: SRS_Requirement_NewLine7 + :custom_complex_text: Has + two \ + lines diff --git a/dox_trace/spec/test_input/html/Makefile b/dox_trace/spec/test_input/html/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/html/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/html/conf.py b/dox_trace/spec/test_input/html/conf.py new file mode 100644 index 0000000..6a94ac3 --- /dev/null +++ b/dox_trace/spec/test_input/html/conf.py @@ -0,0 +1,12 @@ +import os +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +project = os.environ.get("DOXTRACE_PROJECT_NAME", "Project Name") diff --git a/dox_trace/spec/test_input/html/index.rst b/dox_trace/spec/test_input/html/index.rst new file mode 100644 index 0000000..8e71ae8 --- /dev/null +++ b/dox_trace/spec/test_input/html/index.rst @@ -0,0 +1,41 @@ +HTML +==== + +.. toctree:: + + subpage + subpage2 + +Normal +------ + +.. information:: Information_Normal + :category: input + +.. requirement:: Requirement_Normal + :category: input + +.. srs:: SRS_Srs_Normal + +.. spec:: SWA_Spec_Normal + +.. unit:: SMD_Unit_Normal + +.. interface:: SWA_Interface_Normal + +.. mod:: SWA_Mod_Normal + +Struck +------ + +.. requirement:: Requirement_Invalid + :category: input + :status: invalid + +.. requirement:: Requirement_Rejected + :category: input + :review_status: rejected + +.. requirement:: Requirement_NotRelevant + :category: input + :review_status: not_relevant diff --git a/dox_trace/spec/test_input/html/subpage.rst b/dox_trace/spec/test_input/html/subpage.rst new file mode 100644 index 0000000..70dd2c8 --- /dev/null +++ b/dox_trace/spec/test_input/html/subpage.rst @@ -0,0 +1,9 @@ +Subpage +======= + +Normal +------ + +.. requirement:: SRS_Requirement_Subpage + :refs: Requirement_Normal + :category: software diff --git a/dox_trace/spec/test_input/html/subpage2.rst b/dox_trace/spec/test_input/html/subpage2.rst new file mode 100644 index 0000000..f981f45 --- /dev/null +++ b/dox_trace/spec/test_input/html/subpage2.rst @@ -0,0 +1,5 @@ +Subpage2 +======== + +Normal2 +------- diff --git a/dox_trace/spec/test_input/ignore_in_export/Makefile b/dox_trace/spec/test_input/ignore_in_export/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/ignore_in_export/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/ignore_in_export/conf.py b/dox_trace/spec/test_input/ignore_in_export/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/ignore_in_export/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/ignore_in_export/index.rst b/dox_trace/spec/test_input/ignore_in_export/index.rst new file mode 100644 index 0000000..1709629 --- /dev/null +++ b/dox_trace/spec/test_input/ignore_in_export/index.rst @@ -0,0 +1,38 @@ +Ignore in Export +================ + +Set +--- + +.. requirement:: SRS_Requirement_Ignore + :category: software + :ignore_in_export: + +.. information:: SRS_Information_Ignore + :ignore_in_export: + :category: software + +.. requirement:: InputRequirement_Ignore + :ignore_in_export: + :category: input + +.. information:: InputInformation_Ignore + :ignore_in_export: + :category: input + +.. spec:: SWA_Spec_Ignore + :ignore_in_export: + +.. unit:: SMD_Unit_Ignore + :ignore_in_export: + +.. interface:: SWA_Interface_Ignore + :ignore_in_export: + +.. mod:: SWA_Mod_Ignore + :ignore_in_export: + +Not Set +------- + +.. interface:: SWA_Interface_NotIgnore diff --git a/dox_trace/spec/test_input/location/Makefile b/dox_trace/spec/test_input/location/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location/conf.py b/dox_trace/spec/test_input/location/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location/index.rst b/dox_trace/spec/test_input/location/index.rst new file mode 100644 index 0000000..bd23c96 --- /dev/null +++ b/dox_trace/spec/test_input/location/index.rst @@ -0,0 +1,7 @@ +Location +======== + +.. toctree:: + + subfolder/index + modules/driver/doc/index diff --git a/dox_trace/spec/test_input/location/modules/driver/doc/index.rst b/dox_trace/spec/test_input/location/modules/driver/doc/index.rst new file mode 100644 index 0000000..66b47a5 --- /dev/null +++ b/dox_trace/spec/test_input/location/modules/driver/doc/index.rst @@ -0,0 +1,4 @@ +driver +====== + +Documentation of driver. diff --git a/dox_trace/spec/test_input/location/subfolder/index.rst b/dox_trace/spec/test_input/location/subfolder/index.rst new file mode 100644 index 0000000..ac4b68e --- /dev/null +++ b/dox_trace/spec/test_input/location/subfolder/index.rst @@ -0,0 +1,17 @@ +Subfolder +========= + +.. mod:: SWA_Mod_Empty + +.. mod:: SWA_Mod_EmptyStruck + :status: invalid + +.. mod:: SWA_Mod_NotExist + :location: modules/doesNotExist + +.. mod:: SWA_Mod_NotExistStruck + :location: modules/doesNotExist + :status: invalid + +.. mod:: SWA_Mod_Exist + :location: modules/driver diff --git a/dox_trace/spec/test_input/location_information/Makefile b/dox_trace/spec/test_input/location_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_information/conf.py b/dox_trace/spec/test_input/location_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_information/index.rst b/dox_trace/spec/test_input/location_information/index.rst new file mode 100644 index 0000000..8e2aedf --- /dev/null +++ b/dox_trace/spec/test_input/location_information/index.rst @@ -0,0 +1,9 @@ +Location Information +==================== + +Not Available +------------- + +.. information:: SRS_Information_TestSetups + :location: not_available + :category: software diff --git a/dox_trace/spec/test_input/location_interface/Makefile b/dox_trace/spec/test_input/location_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_interface/conf.py b/dox_trace/spec/test_input/location_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_interface/index.rst b/dox_trace/spec/test_input/location_interface/index.rst new file mode 100644 index 0000000..a912c47 --- /dev/null +++ b/dox_trace/spec/test_input/location_interface/index.rst @@ -0,0 +1,8 @@ +Location Interface +================== + +Not Available +------------- + +.. interface:: SWA_Interface_Location + :location: not_available diff --git a/dox_trace/spec/test_input/location_requirement/Makefile b/dox_trace/spec/test_input/location_requirement/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_requirement/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_requirement/conf.py b/dox_trace/spec/test_input/location_requirement/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_requirement/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_requirement/index.rst b/dox_trace/spec/test_input/location_requirement/index.rst new file mode 100644 index 0000000..37f398e --- /dev/null +++ b/dox_trace/spec/test_input/location_requirement/index.rst @@ -0,0 +1,9 @@ +Location Requirement +==================== + +Not Available +------------- + +.. requirement:: SRS_Requirement_Location + :location: not_available + :category: software diff --git a/dox_trace/spec/test_input/location_spec/Makefile b/dox_trace/spec/test_input/location_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_spec/conf.py b/dox_trace/spec/test_input/location_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_spec/index.rst b/dox_trace/spec/test_input/location_spec/index.rst new file mode 100644 index 0000000..dd6ba06 --- /dev/null +++ b/dox_trace/spec/test_input/location_spec/index.rst @@ -0,0 +1,8 @@ +Location Spec +============= + +Not Available +------------- + +.. spec:: SWA_Spec_Location + :location: not_available diff --git a/dox_trace/spec/test_input/location_srs/Makefile b/dox_trace/spec/test_input/location_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_srs/conf.py b/dox_trace/spec/test_input/location_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_srs/index.rst b/dox_trace/spec/test_input/location_srs/index.rst new file mode 100644 index 0000000..47c8079 --- /dev/null +++ b/dox_trace/spec/test_input/location_srs/index.rst @@ -0,0 +1,8 @@ +Location Srs +============ + +Not Available +------------- + +.. srs:: SRS_Srs_Location + :location: not_available diff --git a/dox_trace/spec/test_input/location_unit/Makefile b/dox_trace/spec/test_input/location_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/location_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/location_unit/conf.py b/dox_trace/spec/test_input/location_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/location_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/location_unit/index.rst b/dox_trace/spec/test_input/location_unit/index.rst new file mode 100644 index 0000000..048bbb4 --- /dev/null +++ b/dox_trace/spec/test_input/location_unit/index.rst @@ -0,0 +1,8 @@ +Location Unit +============= + +Not Available +------------- + +.. unit:: SMD_Unit_Location + :location: not_available diff --git a/dox_trace/spec/test_input/miscellaneous/Makefile b/dox_trace/spec/test_input/miscellaneous/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous/conf.py b/dox_trace/spec/test_input/miscellaneous/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous/index.rst b/dox_trace/spec/test_input/miscellaneous/index.rst new file mode 100644 index 0000000..1194e48 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous/index.rst @@ -0,0 +1,36 @@ +Miscellaneous +============= + +Available +--------- + +.. information:: SRS_Information_MiscellaneousSet + :miscellaneous: Aa + :category: software + +.. requirement:: SRS_Requirement_MiscellaneousSet + :miscellaneous: Bb + :category: software + +.. information:: InputInformation_MiscellaneousSet + :miscellaneous: Cc + :category: input + +.. requirement:: InputRequirement_MiscellaneousSet + :miscellaneous: Dd + :category: input + +Default +------- + +.. information:: SRS_Information_MiscellaneousDefault + :category: software + +.. requirement:: SRS_Requirement_MiscellaneousDefault + :category: software + +.. information:: InputInformation_MiscellaneousDefault + :category: input + +.. requirement:: InputRequirement_MiscellaneousDefault + :category: input diff --git a/dox_trace/spec/test_input/miscellaneous_interface/Makefile b/dox_trace/spec/test_input/miscellaneous_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous_interface/conf.py b/dox_trace/spec/test_input/miscellaneous_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous_interface/index.rst b/dox_trace/spec/test_input/miscellaneous_interface/index.rst new file mode 100644 index 0000000..dce956d --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_interface/index.rst @@ -0,0 +1,8 @@ +Miscellaneous Interface +======================= + +Not Available +------------- + +.. interface:: SWA_Interface_NotAvailable + :miscellaneous: not available diff --git a/dox_trace/spec/test_input/miscellaneous_mod/Makefile b/dox_trace/spec/test_input/miscellaneous_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous_mod/conf.py b/dox_trace/spec/test_input/miscellaneous_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous_mod/index.rst b/dox_trace/spec/test_input/miscellaneous_mod/index.rst new file mode 100644 index 0000000..3de6623 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_mod/index.rst @@ -0,0 +1,8 @@ +Miscellaneous Mod +================= + +Not Available +------------- + +.. mod:: SWA_Mod_NotAvailable + :miscellaneous: not available diff --git a/dox_trace/spec/test_input/miscellaneous_spec/Makefile b/dox_trace/spec/test_input/miscellaneous_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous_spec/conf.py b/dox_trace/spec/test_input/miscellaneous_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous_spec/index.rst b/dox_trace/spec/test_input/miscellaneous_spec/index.rst new file mode 100644 index 0000000..06e579b --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_spec/index.rst @@ -0,0 +1,8 @@ +Miscellaneous Spec +================== + +Not Available +------------- + +.. spec:: SWA_Spec_NotAvailable + :miscellaneous: not available diff --git a/dox_trace/spec/test_input/miscellaneous_srs/Makefile b/dox_trace/spec/test_input/miscellaneous_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous_srs/conf.py b/dox_trace/spec/test_input/miscellaneous_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous_srs/index.rst b/dox_trace/spec/test_input/miscellaneous_srs/index.rst new file mode 100644 index 0000000..b76e86c --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_srs/index.rst @@ -0,0 +1,8 @@ +Miscellaneous Srs +================= + +Not Available +------------- + +.. srs:: SRS_Srs_NotAvailable + :miscellaneous: not available diff --git a/dox_trace/spec/test_input/miscellaneous_unit/Makefile b/dox_trace/spec/test_input/miscellaneous_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/miscellaneous_unit/conf.py b/dox_trace/spec/test_input/miscellaneous_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/miscellaneous_unit/index.rst b/dox_trace/spec/test_input/miscellaneous_unit/index.rst new file mode 100644 index 0000000..1c18f05 --- /dev/null +++ b/dox_trace/spec/test_input/miscellaneous_unit/index.rst @@ -0,0 +1,8 @@ +Miscellaneous Unit +================== + +Not Available +------------- + +.. unit:: SMD_Unit_NotAvailable + :miscellaneous: not available diff --git a/dox_trace/spec/test_input/parallel/Makefile b/dox_trace/spec/test_input/parallel/Makefile new file mode 100644 index 0000000..f4cdad0 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -j auto -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/parallel/conf.py b/dox_trace/spec/test_input/parallel/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/parallel/index.rst b/dox_trace/spec/test_input/parallel/index.rst new file mode 100644 index 0000000..3bc2795 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/index.rst @@ -0,0 +1,13 @@ +Parallel +======== + +.. toctree:: + + subpage1 + subpage2 + subpage3 + subpage4 + subpage5 + +.. spec:: SWA_Spec_Main + :refs: SWA_Spec_Subpage1, SWA_Spec_Subpage2 diff --git a/dox_trace/spec/test_input/parallel/subpage1.rst b/dox_trace/spec/test_input/parallel/subpage1.rst new file mode 100644 index 0000000..337f951 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/subpage1.rst @@ -0,0 +1,5 @@ +Subpage1 +======== + +.. spec:: SWA_Spec_Subpage1 + :refs: SWA_Spec_Subpage2 diff --git a/dox_trace/spec/test_input/parallel/subpage2.rst b/dox_trace/spec/test_input/parallel/subpage2.rst new file mode 100644 index 0000000..785c0f2 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/subpage2.rst @@ -0,0 +1,4 @@ +Subpage2 +======== + +.. spec:: SWA_Spec_Subpage2 diff --git a/dox_trace/spec/test_input/parallel/subpage3.rst b/dox_trace/spec/test_input/parallel/subpage3.rst new file mode 100644 index 0000000..0ee7bd7 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/subpage3.rst @@ -0,0 +1,2 @@ +Subpage3 +======== diff --git a/dox_trace/spec/test_input/parallel/subpage4.rst b/dox_trace/spec/test_input/parallel/subpage4.rst new file mode 100644 index 0000000..6641225 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/subpage4.rst @@ -0,0 +1,2 @@ +Subpage4 +======== diff --git a/dox_trace/spec/test_input/parallel/subpage5.rst b/dox_trace/spec/test_input/parallel/subpage5.rst new file mode 100644 index 0000000..456b0d3 --- /dev/null +++ b/dox_trace/spec/test_input/parallel/subpage5.rst @@ -0,0 +1,2 @@ +Subpage5 +======== diff --git a/dox_trace/spec/test_input/properties/Makefile b/dox_trace/spec/test_input/properties/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties/conf.py b/dox_trace/spec/test_input/properties/conf.py new file mode 100644 index 0000000..672df0a --- /dev/null +++ b/dox_trace/spec/test_input/properties/conf.py @@ -0,0 +1,15 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" + +dox_trace_custom_attributes = { + "custom": {"directives": ["unit"], "type": "text"}, +} diff --git a/dox_trace/spec/test_input/properties/index.rst b/dox_trace/spec/test_input/properties/index.rst new file mode 100644 index 0000000..01eedce --- /dev/null +++ b/dox_trace/spec/test_input/properties/index.rst @@ -0,0 +1,52 @@ +Properties +========== + +Default +------- + +.. requirement:: SRS_Requirement1_Full + :category: software + +.. requirement:: SRS_Requirement2_Mod + :category: software + +.. requirement:: SRS_Requirement3_Default + :category: software + +.. requirement:: SRS_Requirement4_Defined + :asil: ASIL_D + :category: software + + Original content. + +.. requirement:: NoModuleNameDefault + :category: input + +.. unit:: SMD_Custom_Prop + +.. unit:: SMD_Custom_Overwritten + :asil: ASIL_C + +.. spec:: SWA_Custom_CategorySet + +.. spec:: SMD_Custom_CategoryNotSet + +Standalone +---------- + +- Role defined: :prop:`SRS_Requirement1_Full:content` +- Directive defined: + + .. prop:: SRS_Requirement2:content + +- Role default :prop:`bla:content` +- Directive default: + + .. prop:: bla:content + +Boolean +------- + +.. spec:: SWA_Custom_True + +.. spec:: SWA_Custom_False diff --git a/dox_trace/spec/test_input/properties/properties.yaml b/dox_trace/spec/test_input/properties/properties.yaml new file mode 100644 index 0000000..f474c3f --- /dev/null +++ b/dox_trace/spec/test_input/properties/properties.yaml @@ -0,0 +1,15 @@ +SRS_Requirement1_Full: { asil: ASIL_A, content: "Single line" } +SRS_Requirement1: { asil: ASIL_B } # ignored + +SRS_Requirement2: { asil: ASIL_C, content: "Multi\n\n- line1\n- **line2**" } + +SRS_Requirement3_Default: {} + +SMD_Custom_Prop: { asil: ASIL_D } + +SWA: { developer: Abc AG } + +SWA_Custom_True: { tags: true } +SWA_Custom_False: { tags: [false] } + +_default_: { asil: QM, content: "Todo" } diff --git a/dox_trace/spec/test_input/properties_no_file/Makefile b/dox_trace/spec/test_input/properties_no_file/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_file/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_no_file/conf.py b/dox_trace/spec/test_input/properties_no_file/conf.py new file mode 100644 index 0000000..1b27a27 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_file/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/properties_no_file/index.rst b/dox_trace/spec/test_input/properties_no_file/index.rst new file mode 100644 index 0000000..35d19bc --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_file/index.rst @@ -0,0 +1,2 @@ +Properties +========== diff --git a/dox_trace/spec/test_input/properties_no_name/Makefile b/dox_trace/spec/test_input/properties_no_name/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_name/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_no_name/conf.py b/dox_trace/spec/test_input/properties_no_name/conf.py new file mode 100644 index 0000000..1b27a27 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_name/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/properties_no_name/index.rst b/dox_trace/spec/test_input/properties_no_name/index.rst new file mode 100644 index 0000000..dba40e1 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_name/index.rst @@ -0,0 +1,4 @@ +Properties +========== + +:prop:`nope:fasel` diff --git a/dox_trace/spec/test_input/properties_no_name/properties.yaml b/dox_trace/spec/test_input/properties_no_name/properties.yaml new file mode 100644 index 0000000..40c4cea --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_name/properties.yaml @@ -0,0 +1 @@ +bla: { fasel: "xy" } diff --git a/dox_trace/spec/test_input/properties_no_value/Makefile b/dox_trace/spec/test_input/properties_no_value/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_value/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_no_value/conf.py b/dox_trace/spec/test_input/properties_no_value/conf.py new file mode 100644 index 0000000..1b27a27 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_value/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/properties_no_value/index.rst b/dox_trace/spec/test_input/properties_no_value/index.rst new file mode 100644 index 0000000..346f358 --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_value/index.rst @@ -0,0 +1,4 @@ +Properties +========== + +:prop:`bla:nope` diff --git a/dox_trace/spec/test_input/properties_no_value/properties.yaml b/dox_trace/spec/test_input/properties_no_value/properties.yaml new file mode 100644 index 0000000..40c4cea --- /dev/null +++ b/dox_trace/spec/test_input/properties_no_value/properties.yaml @@ -0,0 +1 @@ +bla: { fasel: "xy" } diff --git a/dox_trace/spec/test_input/properties_not_available/Makefile b/dox_trace/spec/test_input/properties_not_available/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_not_available/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_not_available/conf.py b/dox_trace/spec/test_input/properties_not_available/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/properties_not_available/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/properties_not_available/index.rst b/dox_trace/spec/test_input/properties_not_available/index.rst new file mode 100644 index 0000000..32c9b83 --- /dev/null +++ b/dox_trace/spec/test_input/properties_not_available/index.rst @@ -0,0 +1,4 @@ +Properties +========== + +:prop:`bla:content` diff --git a/dox_trace/spec/test_input/properties_wrong_file/Makefile b/dox_trace/spec/test_input/properties_wrong_file/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_file/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_wrong_file/conf.py b/dox_trace/spec/test_input/properties_wrong_file/conf.py new file mode 100644 index 0000000..1b27a27 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_file/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/properties_wrong_file/index.rst b/dox_trace/spec/test_input/properties_wrong_file/index.rst new file mode 100644 index 0000000..484a47b --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_file/index.rst @@ -0,0 +1,5 @@ +Properties +========== + +:prop:`bla:fasel` + diff --git a/dox_trace/spec/test_input/properties_wrong_file/properties.yaml b/dox_trace/spec/test_input/properties_wrong_file/properties.yaml new file mode 100644 index 0000000..1c57fc5 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_file/properties.yaml @@ -0,0 +1 @@ +bla: fasel diff --git a/dox_trace/spec/test_input/properties_wrong_syntax/Makefile b/dox_trace/spec/test_input/properties_wrong_syntax/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_syntax/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/properties_wrong_syntax/conf.py b/dox_trace/spec/test_input/properties_wrong_syntax/conf.py new file mode 100644 index 0000000..1b27a27 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_syntax/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/properties_wrong_syntax/index.rst b/dox_trace/spec/test_input/properties_wrong_syntax/index.rst new file mode 100644 index 0000000..6a88583 --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_syntax/index.rst @@ -0,0 +1,4 @@ +Properties +========== + +.. prop:: no_colon diff --git a/dox_trace/spec/test_input/properties_wrong_syntax/properties.yaml b/dox_trace/spec/test_input/properties_wrong_syntax/properties.yaml new file mode 100644 index 0000000..40c4cea --- /dev/null +++ b/dox_trace/spec/test_input/properties_wrong_syntax/properties.yaml @@ -0,0 +1 @@ +bla: { fasel: "xy" } diff --git a/dox_trace/spec/test_input/refs/Makefile b/dox_trace/spec/test_input/refs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/refs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/refs/conf.py b/dox_trace/spec/test_input/refs/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/refs/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/refs/index.rst b/dox_trace/spec/test_input/refs/index.rst new file mode 100644 index 0000000..20a6c28 --- /dev/null +++ b/dox_trace/spec/test_input/refs/index.rst @@ -0,0 +1,87 @@ +Refs +==== + +Available +--------- + +.. requirement:: SRS_Requirement_RefsSet + :refs: SRS_Requirement_RefsDefault, SMD_Unit_RefsSet + :category: software + +.. information:: SRS_Information_RefsSet + :refs: SRS_Information_RefsDefault + :category: software + +.. requirement:: InputRequirement_RefsSet + :refs: InputRequirement_RefsDefault + :category: input + +.. srs:: SRS_Srs_RefsSet + :refs: SRS_Srs_RefsDefault, SMD_Unit_RefsSet + +.. information:: InputInformation_RefsSet + :refs: InputInformation_RefsDefault + :category: input + +.. spec:: SWA_Spec_RefsSet + :refs: SWA_Spec_RefsDefault + +.. unit:: SMD_Unit_RefsSet + :refs: SMD_Unit_RefsDefault + +.. interface:: SWA_Interface_RefsSet + :refs: SWA_Interface_RefsDefault, SMD_Unit_RefsSet + +.. interface:: SMD_Interface_RefsSet + :refs: SMD_Unit_RefsSet + + +Default +------- + +.. requirement:: SRS_Requirement_RefsDefault + :category: software + +.. information:: SRS_Information_RefsDefault + :category: software + +.. requirement:: InputRequirement_RefsDefault + :category: input + +.. information:: InputInformation_RefsDefault + :category: input + +.. srs:: SRS_Srs_RefsDefault + +.. spec:: SWA_Spec_RefsDefault + +.. unit:: SMD_Unit_RefsDefault + +.. interface:: SWA_Interface_RefsDefault + +.. interface:: SMD_Interface_RefsDefault + +Additional +---------- + +.. spec:: SWA_Spec_TagsCovered + :tags: covered + +.. spec:: SWA_Spec_StatusInvalid + :status: invalid + +Round Trip +---------- + +.. spec:: SWA_Spec_RoundTrip + :refs: SMD_Spec_RoundTrip + +.. spec:: SMD_Spec_RoundTrip + :refs: SWA_Spec_RoundTrip + +Appendix +-------- + +.. toctree:: + + undefined_refs diff --git a/dox_trace/spec/test_input/refs/undefined_refs.rst b/dox_trace/spec/test_input/refs/undefined_refs.rst new file mode 100644 index 0000000..6cf633a --- /dev/null +++ b/dox_trace/spec/test_input/refs/undefined_refs.rst @@ -0,0 +1,4 @@ +Undefined Refs +============== + +.. undefined_refs:: diff --git a/dox_trace/spec/test_input/refs_mod/Makefile b/dox_trace/spec/test_input/refs_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/refs_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/refs_mod/conf.py b/dox_trace/spec/test_input/refs_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/refs_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/refs_mod/index.rst b/dox_trace/spec/test_input/refs_mod/index.rst new file mode 100644 index 0000000..fd08b38 --- /dev/null +++ b/dox_trace/spec/test_input/refs_mod/index.rst @@ -0,0 +1,8 @@ +Refs Mod +======== + +Not Available +------------- + +.. mod:: SWA_Mod_Refs + :refs: not_available diff --git a/dox_trace/spec/test_input/refs_undefined_nowarn/Makefile b/dox_trace/spec/test_input/refs_undefined_nowarn/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_nowarn/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/refs_undefined_nowarn/conf.py b/dox_trace/spec/test_input/refs_undefined_nowarn/conf.py new file mode 100644 index 0000000..9095269 --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_nowarn/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_allow_undefined_refs = True diff --git a/dox_trace/spec/test_input/refs_undefined_nowarn/index.rst b/dox_trace/spec/test_input/refs_undefined_nowarn/index.rst new file mode 100644 index 0000000..6b8090c --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_nowarn/index.rst @@ -0,0 +1,15 @@ +Refs +==== + +.. spec:: SWA_Spec_1 + :refs: SWA_Spec_100, BLAH, SWA_Spec_2, FASEL, SWA_Spec_3 + +.. spec:: SWA_Spec_2 + :refs: SWA_Spec_3, BLAH + +.. spec:: SWA_Spec_3 + :refs: FASEL + +.. toctree:: + + undefined_refs diff --git a/dox_trace/spec/test_input/refs_undefined_nowarn/undefined_refs.rst b/dox_trace/spec/test_input/refs_undefined_nowarn/undefined_refs.rst new file mode 100644 index 0000000..b0e2d4f --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_nowarn/undefined_refs.rst @@ -0,0 +1,4 @@ +Undefined_Refs +============== + +.. undefined_refs:: diff --git a/dox_trace/spec/test_input/refs_undefined_warn/Makefile b/dox_trace/spec/test_input/refs_undefined_warn/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_warn/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/refs_undefined_warn/conf.py b/dox_trace/spec/test_input/refs_undefined_warn/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_warn/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/refs_undefined_warn/index.rst b/dox_trace/spec/test_input/refs_undefined_warn/index.rst new file mode 100644 index 0000000..92f3f00 --- /dev/null +++ b/dox_trace/spec/test_input/refs_undefined_warn/index.rst @@ -0,0 +1,5 @@ +Refs +==== + +.. spec:: SWA_Spec_1 + :refs: SWA_Spec_100 diff --git a/dox_trace/spec/test_input/reuse/Makefile b/dox_trace/spec/test_input/reuse/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse/conf.py b/dox_trace/spec/test_input/reuse/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse/index.rst b/dox_trace/spec/test_input/reuse/index.rst new file mode 100644 index 0000000..bd0dde5 --- /dev/null +++ b/dox_trace/spec/test_input/reuse/index.rst @@ -0,0 +1,8 @@ +Reuse +===== + +.. mod:: SWA_Mod_ReuseEmpty + :reuse: + +.. mod:: SWA_Mod_ReuseTrue + :reuse: true diff --git a/dox_trace/spec/test_input/reuse_information/Makefile b/dox_trace/spec/test_input/reuse_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_information/conf.py b/dox_trace/spec/test_input/reuse_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_information/index.rst b/dox_trace/spec/test_input/reuse_information/index.rst new file mode 100644 index 0000000..00e0a6f --- /dev/null +++ b/dox_trace/spec/test_input/reuse_information/index.rst @@ -0,0 +1,9 @@ +Reuse Information +================= + +Not Available +------------- + +.. information:: SRS_Information_Reuse + :reuse: not_available + :category: software diff --git a/dox_trace/spec/test_input/reuse_interface/Makefile b/dox_trace/spec/test_input/reuse_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_interface/conf.py b/dox_trace/spec/test_input/reuse_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_interface/index.rst b/dox_trace/spec/test_input/reuse_interface/index.rst new file mode 100644 index 0000000..0fd6bfa --- /dev/null +++ b/dox_trace/spec/test_input/reuse_interface/index.rst @@ -0,0 +1,8 @@ +Reuse Interface +=============== + +Not Available +------------- + +.. interface:: SWA_Interface_Reuse + :reuse: not_available diff --git a/dox_trace/spec/test_input/reuse_requirement/Makefile b/dox_trace/spec/test_input/reuse_requirement/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_requirement/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_requirement/conf.py b/dox_trace/spec/test_input/reuse_requirement/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_requirement/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_requirement/index.rst b/dox_trace/spec/test_input/reuse_requirement/index.rst new file mode 100644 index 0000000..2f016ae --- /dev/null +++ b/dox_trace/spec/test_input/reuse_requirement/index.rst @@ -0,0 +1,9 @@ +Reuse Requirement +================= + +Not Available +------------- + +.. requirement:: SRS_Requirement_Reuse + :reuse: not_available + :category: software diff --git a/dox_trace/spec/test_input/reuse_spec/Makefile b/dox_trace/spec/test_input/reuse_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_spec/conf.py b/dox_trace/spec/test_input/reuse_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_spec/index.rst b/dox_trace/spec/test_input/reuse_spec/index.rst new file mode 100644 index 0000000..8a9e028 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_spec/index.rst @@ -0,0 +1,8 @@ +Reuse Spec +========== + +Not Available +------------- + +.. spec:: SWA_Spec_Reuse + :reuse: not_available diff --git a/dox_trace/spec/test_input/reuse_srs/Makefile b/dox_trace/spec/test_input/reuse_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_srs/conf.py b/dox_trace/spec/test_input/reuse_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_srs/index.rst b/dox_trace/spec/test_input/reuse_srs/index.rst new file mode 100644 index 0000000..e16a30c --- /dev/null +++ b/dox_trace/spec/test_input/reuse_srs/index.rst @@ -0,0 +1,8 @@ +Reuse Srs +========= + +Not Available +------------- + +.. srs:: SRS_Srs_Reuse + :reuse: not_available diff --git a/dox_trace/spec/test_input/reuse_unit/Makefile b/dox_trace/spec/test_input/reuse_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/reuse_unit/conf.py b/dox_trace/spec/test_input/reuse_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/reuse_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/reuse_unit/index.rst b/dox_trace/spec/test_input/reuse_unit/index.rst new file mode 100644 index 0000000..e75cbfe --- /dev/null +++ b/dox_trace/spec/test_input/reuse_unit/index.rst @@ -0,0 +1,8 @@ +Reuse Unit +========== + +Not Available +------------- + +.. unit:: SMD_Unit_Reuse + :reuse: not_available diff --git a/dox_trace/spec/test_input/review_status/Makefile b/dox_trace/spec/test_input/review_status/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/review_status/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/review_status/conf.py b/dox_trace/spec/test_input/review_status/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/review_status/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/review_status/index.rst b/dox_trace/spec/test_input/review_status/index.rst new file mode 100644 index 0000000..d68eb48 --- /dev/null +++ b/dox_trace/spec/test_input/review_status/index.rst @@ -0,0 +1,80 @@ +Review Status +============= + +Available +--------- + +.. information:: SRS_Information_ReviewStatusNotReviewed + :review_status: not_reviewed + :category: software + +.. requirement:: SRS_Requirement_ReviewStatusNotReviewed + :review_status: not_reviewed + :category: software + +.. information:: InputInformation_ReviewStatusNotReviewed + :review_status: not_reviewed + :category: input + +.. requirement:: InputRequirement_ReviewStatusNotReviewed + :review_status: not_reviewed + :category: input + +.. srs:: SRS_Srs_ReviewStatusNotReviewed + :review_status: not_reviewed + +.. spec:: SWA_Spec_ReviewStatusNotReviewed + :review_status: not_reviewed + +.. unit:: SMD_Unit_ReviewStatusRejected + :review_status: rejected + +.. interface:: SWA_Interface_ReviewStatusNotReviewed + :review_status: not_reviewed + +.. mod:: SWA_Mod_ReviewStatusNotReviewed + :review_status: not_reviewed + +Default +------- + +.. information:: SRS_Information_ReviewStatusDefault + :category: software + +.. requirement:: SRS_Requirement_ReviewStatusDefault + :category: software + +.. information:: InputInformation_ReviewStatusDefault + :category: input + +.. requirement:: InputRequirement_ReviewStatusDefault + :category: input + +.. srs:: SRS_Srs_ReviewStatusDefault + +.. spec:: SWA_Spec_ReviewStatusDefault + +.. unit:: SMD_Unit_ReviewStatusDefault + +.. interface:: SWA_Interface_ReviewStatusDefault + +.. mod:: SWA_Mod_ReviewStatusDefault + +Additional +---------- + +.. requirement:: InputRequirement_ReviewStatusAccepted + :review_status: accepted + :category: input + +.. requirement:: InputRequirement_ReviewStatusRejected + :review_status: rejected + :category: input + +.. requirement:: InputRequirement_StatusInvalid + :status: invalid + :category: input + +.. information:: InputInformation_StatusInvalid + :status: invalid + :category: input diff --git a/dox_trace/spec/test_input/security/Makefile b/dox_trace/spec/test_input/security/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/security/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/security/attributes.dim b/dox_trace/spec/test_input/security/attributes.dim new file mode 100644 index 0000000..0745788 --- /dev/null +++ b/dox_trace/spec/test_input/security/attributes.dim @@ -0,0 +1,7 @@ +security: + type: single + default: 'not_set' + allowed: + - yes + - no + - not_set diff --git a/dox_trace/spec/test_input/security/conf.py b/dox_trace/spec/test_input/security/conf.py new file mode 100644 index 0000000..0ac6918 --- /dev/null +++ b/dox_trace/spec/test_input/security/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/security/index.rst b/dox_trace/spec/test_input/security/index.rst new file mode 100644 index 0000000..5419e5d --- /dev/null +++ b/dox_trace/spec/test_input/security/index.rst @@ -0,0 +1,92 @@ +Security +======== + +Available +--------- + +.. information:: SRS_Information_SecurityYes + :security: yes + :category: software + +.. requirement:: SRS_Requirement_SecurityYes + :security: yes + :category: software + +.. information:: InputInformation_SecurityYes + :security: yes + :category: input + +.. requirement:: InputRequirement_SecurityYes + :security: yes + :category: input + +.. srs:: SRS_Srs_SecurityYes + :security: yes + +.. spec:: SWA_Spec_SecurityYes + :security: yes + +.. unit:: SMD_Unit_SecurityYes + :security: yes + +.. interface:: SWA_Interface_SecurityYes + :security: yes + +.. mod:: SWA_Mod_SecurityYes + :security: yes + +Default +------- + +.. information:: SRS_Information_SecurityDefault + :category: software + +.. requirement:: SRS_Requirement_SecurityDefault + :category: software + +.. information:: InputInformation_SecurityDefault + :category: input + +.. requirement:: InputRequirement_SecurityDefault + :category: input + +.. srs:: SRS_Srs_SecurityDefault + +.. spec:: SWA_Spec_SecurityDefault + +.. unit:: SMD_Unit_SecurityDefault + +.. interface:: SWA_Interface_SecurityDefault + +.. mod:: SWA_Mod_SecurityDefault + +Additional +---------- + +.. spec:: SWA_Spec_ReviewStatusRejected + :review_status: rejected + +Cal +--- + +.. spec:: SWA_Spec_CalNotSet + :cal: not_set + +.. spec:: SWA_Spec_CalQm + :cal: QM + +.. spec:: SWA_Spec_Cal1 + :cal: CAL_1 + +.. spec:: SWA_Spec_Cal2 + :cal: CAL_2 + +.. spec:: SWA_Spec_Cal3 + :cal: CAL_3 + +.. spec:: SWA_Spec_Cal4 + :cal: CAL_4 + +.. spec:: SWA_Spec_Cal1yes + :security: yes + :cal: CAL_1 diff --git a/dox_trace/spec/test_input/sources/Makefile b/dox_trace/spec/test_input/sources/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/sources/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/sources/conf.py b/dox_trace/spec/test_input/sources/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/sources/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/sources/doc/subpage.rst b/dox_trace/spec/test_input/sources/doc/subpage.rst new file mode 100644 index 0000000..a82534e --- /dev/null +++ b/dox_trace/spec/test_input/sources/doc/subpage.rst @@ -0,0 +1,5 @@ +Subpage +======= + +.. unit:: SMD_Unit_ModuleDoc + :sources: doc/subpage.rst diff --git a/dox_trace/spec/test_input/sources/index.rst b/dox_trace/spec/test_input/sources/index.rst new file mode 100644 index 0000000..485ae4f --- /dev/null +++ b/dox_trace/spec/test_input/sources/index.rst @@ -0,0 +1,75 @@ +Sources +======= + +.. toctree:: + + doc/subpage + +Available +--------- + +.. requirement:: SRS_Requirement_SourcesSet + :sources: Makefile + :category: software + +.. requirement:: InputRequirement_SourcesSet + :sources: Makefile, index.rst + :category: input + +.. spec:: SWA_Spec_SourcesSet + :sources: src/test.abc + +.. srs:: SRS_Srs_SourcesSet + :sources: Makefile + +.. unit:: SMD_Unit_SourcesSet + :sources: src/test.abc, Makefile + +.. interface:: SWA_Interface_SourcesSet + :sources: Makefile, src/test.abc + +.. interface:: SMD_Interface_SourcesSet + :sources: Makefile, src/test.abc + +Default +------- + +.. requirement:: SRS_Requirement_SourcesDefault + :category: software + +.. requirement:: InputRequirement_SourcesDefault + :category: input + +.. srs:: SRS_Srs_SourcesDefault + +.. spec:: SWA_Spec_SourcesDefault + +.. unit:: SMD_Unit_SourcesDefault + +.. interface:: SWA_Interface_SourcesDefault + +.. interface:: SMD_Interface_SourcesDefault + +Additional +---------- + +.. spec:: SWA_Spec_TagsCovered + :tags: covered + +.. unit:: SMD_Unit_TagsCovered + :tags: covered + +.. interface:: SMD_Interface_TagsCovered + :tags: covered + +.. spec:: SWA_Spec_StatusInvalid + :status: invalid + +.. unit:: SMD_Unit_StatusInvalid + :status: invalid + +.. interface:: SWA_Interface_StatusInvalid + :status: invalid + +.. interface:: SMD_Interface_StatusInvalid + :status: invalid diff --git a/dox_trace/spec/test_input/sources/src/test.abc b/dox_trace/spec/test_input/sources/src/test.abc new file mode 100644 index 0000000..346e384 --- /dev/null +++ b/dox_trace/spec/test_input/sources/src/test.abc @@ -0,0 +1 @@ +// test file diff --git a/dox_trace/spec/test_input/sources_information/Makefile b/dox_trace/spec/test_input/sources_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/sources_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/sources_information/conf.py b/dox_trace/spec/test_input/sources_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/sources_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/sources_information/index.rst b/dox_trace/spec/test_input/sources_information/index.rst new file mode 100644 index 0000000..fb1a4b0 --- /dev/null +++ b/dox_trace/spec/test_input/sources_information/index.rst @@ -0,0 +1,9 @@ +Sources Information +=================== + +Not Available +------------- + +.. information:: SRS_Information_Sources + :sources: not_available + :category: software diff --git a/dox_trace/spec/test_input/sources_mod/Makefile b/dox_trace/spec/test_input/sources_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/sources_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/sources_mod/conf.py b/dox_trace/spec/test_input/sources_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/sources_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/sources_mod/index.rst b/dox_trace/spec/test_input/sources_mod/index.rst new file mode 100644 index 0000000..a631a2f --- /dev/null +++ b/dox_trace/spec/test_input/sources_mod/index.rst @@ -0,0 +1,8 @@ +Sources Mod +=========== + +Not Available +------------- + +.. mod:: SWA_Mod_Sources + :sources: not_available diff --git a/dox_trace/spec/test_input/status/Makefile b/dox_trace/spec/test_input/status/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/status/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/status/conf.py b/dox_trace/spec/test_input/status/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/status/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/status/index.rst b/dox_trace/spec/test_input/status/index.rst new file mode 100644 index 0000000..4db60d7 --- /dev/null +++ b/dox_trace/spec/test_input/status/index.rst @@ -0,0 +1,67 @@ +Status +====== + +Available +--------- + +.. information:: SRS_Information_StatusValid + :status: valid + :category: software + +.. requirement:: SRS_Requirement_StatusValid + :status: valid + :category: software + +.. information:: InputInformation_StatusValid + :status: valid + :category: input + +.. requirement:: InputRequirement_StatusValid + :status: valid + :category: input + +.. srs:: SRS_Srs_StatusValid + :status: valid + +.. spec:: SWA_Spec_StatusValid + :status: valid + +.. unit:: SMD_Unit_StatusValid + :status: valid + +.. interface:: SWA_Interface_StatusValid + :status: valid + +.. mod:: SWA_Mod_StatusValid + :status: valid + +Default +------- + +.. information:: SRS_Information_StatusDefault + :category: software + +.. requirement:: SRS_Requirement_StatusDefault + :category: software + +.. information:: InputInformation_StatusDefault + :category: input + +.. requirement:: InputRequirement_StatusDefault + :category: input + +.. srs:: SRS_Srs_StatusDefault + +.. spec:: SWA_Spec_StatusDefault + +.. unit:: SMD_Unit_StatusDefault + +.. interface:: SWA_Interface_StatusDefault + +.. mod:: SWA_Mod_StatusDefault + +Additional +---------- + +.. spec:: SWA_Spec_ReviewStatusRejected + :review_status: rejected diff --git a/dox_trace/spec/test_input/tags/Makefile b/dox_trace/spec/test_input/tags/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tags/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tags/conf.py b/dox_trace/spec/test_input/tags/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tags/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tags/index.rst b/dox_trace/spec/test_input/tags/index.rst new file mode 100644 index 0000000..cf352dc --- /dev/null +++ b/dox_trace/spec/test_input/tags/index.rst @@ -0,0 +1,79 @@ +Tags +==== + +.. toctree:: + + modules/driver/doc/index + +Available +--------- + +.. information:: SRS_Information_TagsSet + :tags: srs + :category: software + +.. requirement:: SRS_Requirement_TagsSet + :tags: swa + :category: software + +.. information:: InputInformation_TagsSet + :tags: memory + :category: input + +.. requirement:: InputRequirement_TagsSet + :tags: memory, performance + :category: input + +.. srs:: SRS_Srs_TagsSet + :tags: swa + +.. spec:: SWA_Spec_TagsSet + :tags: performance + +.. unit:: SMD_Unit_TagsSet + :tags: obd, performance + +.. interface:: SWA_Interface_TagsSet + :tags: sys, tool + +Default +------- + +.. information:: SRS_Information_TagsDefault + :category: software + :tags: + +.. requirement:: SRS_Requirement_TagsDefault + :category: software + +.. information:: InputInformation_TagsDefault + :category: input + +.. requirement:: InputRequirement_TagsDefault + :category: input + +.. srs:: SRS_Srs_TagsDefault + +.. spec:: SWA_Spec_TagsDefault + :tags: + +.. unit:: SMD_Unit_TagsDefault + +.. interface:: SWA_Interface_TagsDefault + +Export +------ + +.. unit:: SMD_Unit_TagsUnitSet + :tags: obd, unit, performance + +.. interface:: SWA_Interface_TagsInterfaceSet + :tags: sys, interface, tool + +.. mod:: SWA_Mod_Empty + +.. mod:: SWA_Mod_NotExist + :location: modules/doesNotExist + +.. mod:: SWA_Mod_Exist + :location: modules/driver diff --git a/dox_trace/spec/test_input/tags/modules/driver/doc/index.rst b/dox_trace/spec/test_input/tags/modules/driver/doc/index.rst new file mode 100644 index 0000000..66b47a5 --- /dev/null +++ b/dox_trace/spec/test_input/tags/modules/driver/doc/index.rst @@ -0,0 +1,4 @@ +driver +====== + +Documentation of driver. diff --git a/dox_trace/spec/test_input/tags_mod/Makefile b/dox_trace/spec/test_input/tags_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tags_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tags_mod/conf.py b/dox_trace/spec/test_input/tags_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tags_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tags_mod/index.rst b/dox_trace/spec/test_input/tags_mod/index.rst new file mode 100644 index 0000000..8940cc7 --- /dev/null +++ b/dox_trace/spec/test_input/tags_mod/index.rst @@ -0,0 +1,8 @@ +Tags Mod +======== + +Not Available +------------- + +.. mod:: SWA_Mod_Tags + :tags: not_available diff --git a/dox_trace/spec/test_input/test_setups/Makefile b/dox_trace/spec/test_input/test_setups/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/test_setups/conf.py b/dox_trace/spec/test_input/test_setups/conf.py new file mode 100644 index 0000000..9e3cd25 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True +dox_trace_test_setups_backward = True diff --git a/dox_trace/spec/test_input/test_setups/index.rst b/dox_trace/spec/test_input/test_setups/index.rst new file mode 100644 index 0000000..9e06004 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups/index.rst @@ -0,0 +1,61 @@ +Test Setups +=========== + +Available +--------- + +.. requirement:: SRS_Requirement_TestSetupsSet + :test_setups: on_target, off_target + :category: software + +.. requirement:: InputRequirement_TestSetupsSet + :test_setups: manual + :category: input + +.. srs:: SRS_Srs_TestSetupsSet + :test_setups: on_target, off_target + +.. spec:: SWA_Spec_TestSetupsSet + :test_setups: off_target, on_target + +.. unit:: SMD_Unit_TestSetupsSet + :test_setups: none + +.. interface:: SWA_Interface_TestSetupsSet + :test_setups: off_target + +.. interface:: SMD_Interface_TestSetupsSet + :test_setups: off_target + +Default +------- + +.. requirement:: SRS_Requirement_TestSetupsDefault + :category: software + +.. requirement:: InputRequirement_TestSetupsDefault + :category: input + +.. srs:: SRS_Srs_TestSetupsDefault + +.. spec:: SWA_Spec_TestSetupsDefault + +.. spec:: SMD_Spec_TestSetupsDefault + +.. unit:: SMD_Unit_TestSetupsDefault + +.. mod:: SWA_Mod_TestSetupsDefault + +.. interface:: SWA_Interface_TestSetupsDefault + +.. interface:: SMD_Interface_TestSetupsDefault + +Backward +-------- + +.. spec:: SWA_Spec_TestSetupsBackward + :verification_methods: off_target, on_target + +.. spec:: SWA_Spec_TestSetupsBackwardBoth + :verification_methods: off_target, on_target + :test_setups: manual \ No newline at end of file diff --git a/dox_trace/spec/test_input/test_setups_information/Makefile b/dox_trace/spec/test_input/test_setups_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/test_setups_information/conf.py b/dox_trace/spec/test_input/test_setups_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/test_setups_information/index.rst b/dox_trace/spec/test_input/test_setups_information/index.rst new file mode 100644 index 0000000..6a41ef4 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_information/index.rst @@ -0,0 +1,9 @@ +Test Setups Information +======================= + +Not Available +------------- + +.. information:: SRS_Information_TestSetups + :test_setups: not_available + :category: software diff --git a/dox_trace/spec/test_input/test_setups_mod/Makefile b/dox_trace/spec/test_input/test_setups_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/test_setups_mod/conf.py b/dox_trace/spec/test_input/test_setups_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/test_setups_mod/index.rst b/dox_trace/spec/test_input/test_setups_mod/index.rst new file mode 100644 index 0000000..81cf675 --- /dev/null +++ b/dox_trace/spec/test_input/test_setups_mod/index.rst @@ -0,0 +1,8 @@ +Test Setups Mod +=============== + +Not Available +------------- + +.. mod:: SWA_Mod_TestSetups + :test_setups: not_available diff --git a/dox_trace/spec/test_input/tester/Makefile b/dox_trace/spec/test_input/tester/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tester/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tester/conf.py b/dox_trace/spec/test_input/tester/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tester/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tester/index.rst b/dox_trace/spec/test_input/tester/index.rst new file mode 100644 index 0000000..27dc675 --- /dev/null +++ b/dox_trace/spec/test_input/tester/index.rst @@ -0,0 +1,73 @@ +Tester +====== + +Available +--------- + +.. requirement:: SRS_Requirement_TesterXY + :tester: XY + :category: software + +.. requirement:: InputRequirement_TesterXY + :tester: XY + :category: input + +.. srs:: SRS_Srs_TesterXY + :tester: XY + +.. spec:: SWA_Spec_TesterXY + :tester: XY + +.. unit:: SMD_Unit_TesterXY + :tester: XY + +.. interface:: SWA_Interface_TesterXY + :tester: XY + +.. interface:: SMD_Interface_TesterXY + :tester: XY + +Default +------- + +.. requirement:: SRS_Requirement_TesterDefault + :category: software + +.. requirement:: InputRequirement_TesterDefault + :category: input + +.. srs:: SRS_Srs_TesterDefault + +.. spec:: SWA_Spec_TesterDefault + +.. unit:: SMD_Unit_TesterDefault + +.. interface:: SWA_Interface_TesterDefault + +.. interface:: SMD_Interface_TesterDefault + +Additional +---------- + +.. requirement:: SRS_Requirement_TesterDefaultStruck + :category: software + :status: invalid + +.. requirement:: InputRequirement_TesterDefaultStruck + :category: input + :status: invalid + +.. srs:: SRS_Srs_TesterDefaultStruck + :status: invalid + +.. requirement:: SRS_Requirement_TesterDefaultTestSetupsNone + :category: software + :verification_methods: none + +.. requirement:: InputRequirement_TesterDefaultTestSetupsNone + :category: input + :verification_methods: none + + +.. srs:: SRS_Srs_TesterDefaultTestSetupsNone + :verification_methods: none diff --git a/dox_trace/spec/test_input/tester_information/Makefile b/dox_trace/spec/test_input/tester_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tester_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tester_information/conf.py b/dox_trace/spec/test_input/tester_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tester_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tester_information/index.rst b/dox_trace/spec/test_input/tester_information/index.rst new file mode 100644 index 0000000..db2e3bc --- /dev/null +++ b/dox_trace/spec/test_input/tester_information/index.rst @@ -0,0 +1,9 @@ +Tester Information +================== + +Not Available +------------- + +.. information:: SRS_Information_Tester + :tester: not_available + :category: software diff --git a/dox_trace/spec/test_input/tester_mod/Makefile b/dox_trace/spec/test_input/tester_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tester_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tester_mod/conf.py b/dox_trace/spec/test_input/tester_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tester_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tester_mod/index.rst b/dox_trace/spec/test_input/tester_mod/index.rst new file mode 100644 index 0000000..89be48d --- /dev/null +++ b/dox_trace/spec/test_input/tester_mod/index.rst @@ -0,0 +1,8 @@ +Tester Mod +========== + +Not Available +------------- + +.. mod:: SWA_Mod_Tester + :tester: not_available diff --git a/dox_trace/spec/test_input/tr_architecture_cal_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_cal_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_cal_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_cal_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_cal_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_cal_empty/index.rst new file mode 100644 index 0000000..bdaee66 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. spec:: SWA_Req_notset2 + :developer: Abc AG + :status: invalid + +.. interface:: SWA_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_cal_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_cal_empty/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_cal_none/Makefile b/dox_trace/spec/test_input/tr_architecture_cal_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_cal_none/conf.py b/dox_trace/spec/test_input/tr_architecture_cal_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_cal_none/index.rst b/dox_trace/spec/test_input/tr_architecture_cal_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_cal_none/report.rst b/dox_trace/spec/test_input/tr_architecture_cal_none/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/Makefile b/dox_trace/spec/test_input/tr_architecture_cal_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/conf.py b/dox_trace/spec/test_input/tr_architecture_cal_table/conf.py new file mode 100644 index 0000000..0a58d44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/index.rst b/dox_trace/spec/test_input/tr_architecture_cal_table/index.rst new file mode 100644 index 0000000..e7d7b4b --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SWA_Req_cal1 + :developer: Abc AG + :status: valid + :cal: CAL_1 + +.. spec:: SWA_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + +.. interface:: SWA_Req_qm1 + :developer: Abc AG + :status: valid + :CAL: QM + +.. spec:: SWA_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/properties.yaml b/dox_trace/spec/test_input/tr_architecture_cal_table/properties.yaml new file mode 100644 index 0000000..6b88094 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/properties.yaml @@ -0,0 +1 @@ +SWA_Second: { cal: "QM" } diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/report.rst b/dox_trace/spec/test_input/tr_architecture_cal_table/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/second.rst b/dox_trace/spec/test_input/tr_architecture_cal_table/second.rst new file mode 100644 index 0000000..bdba26a --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. spec:: SWA_Second_qm2 + :developer: Abc AG + :status: valid + diff --git a/dox_trace/spec/test_input/tr_architecture_cal_table/third.rst b/dox_trace/spec/test_input/tr_architecture_cal_table/third.rst new file mode 100644 index 0000000..6dc2114 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_cal_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SWA_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_architecture_list_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_list_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_list_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_list_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_list_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_list_empty/index.rst new file mode 100644 index 0000000..1043e2b --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_empty/index.rst @@ -0,0 +1,17 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. interface:: SWA_Req_notset2 + :developer: Abc AG + :status: invalid + +.. mod:: SWA_Req_notset3 + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_list_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_list_empty/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_list_none/Makefile b/dox_trace/spec/test_input/tr_architecture_list_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_list_none/conf.py b/dox_trace/spec/test_input/tr_architecture_list_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_list_none/index.rst b/dox_trace/spec/test_input/tr_architecture_list_none/index.rst new file mode 100644 index 0000000..bd721a3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_none/index.rst @@ -0,0 +1,11 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_list_none/report.rst b/dox_trace/spec/test_input/tr_architecture_list_none/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/Makefile b/dox_trace/spec/test_input/tr_architecture_list_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/abc/doc/index.rst b/dox_trace/spec/test_input/tr_architecture_list_table/abc/doc/index.rst new file mode 100644 index 0000000..068db74 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/abc/doc/index.rst @@ -0,0 +1,2 @@ +abc +=== diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/conf.py b/dox_trace/spec/test_input/tr_architecture_list_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/index.rst b/dox_trace/spec/test_input/tr_architecture_list_table/index.rst new file mode 100644 index 0000000..04b1420 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/index.rst @@ -0,0 +1,49 @@ +Heading +======= + +.. spec:: SWA_Req_deref1 + :developer: Abc AG + :status: valid + :refs: SWA_Req_refderef1, SWA_Req_refderef2, SWA_Second_ref1 + +.. interface:: SWA_Req_refderef1 + :developer: Abc AG + :status: valid + :refs: SWA_Req_refderef2 + +.. spec:: SWA_Req_refderef2 + :developer: Abc AG + :status: valid + :refs: SWA_Req_notset2 + +.. mod:: SWA_Req_no1 + :developer: Abc AG + :status: valid + +.. spec:: SWA_Req_deref2 + :developer: Abc AG + :status: valid + :sources: index.rst, second.rst + :refs: SWA_Req_notset2 + +.. spec:: SWA_Req_deref3 + :developer: Abc AG + :status: valid + :sources: index.rst + +.. mod:: SWA_Req_deref4 + :developer: Abc AG + :status: valid + :location: abc + +.. mod:: SWA_Req_deref5 + :developer: Abc AG + :status: valid + :location: efg + +.. toctree:: + + second + third + report + abc/doc/index diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/report.rst b/dox_trace/spec/test_input/tr_architecture_list_table/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/second.rst b/dox_trace/spec/test_input/tr_architecture_list_table/second.rst new file mode 100644 index 0000000..a269255 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. spec:: SWA_Second_ref1 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_architecture_list_table/third.rst b/dox_trace/spec/test_input/tr_architecture_list_table/third.rst new file mode 100644 index 0000000..8aa58cd --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_list_table/third.rst @@ -0,0 +1,14 @@ +Third Document +============== + +.. spec:: SWA_Req_notset2 + :developer: Other + +.. spec:: SWA_Req_notset3 + :developer: Other + :refs: SWA_Req_refderef1 + +.. information:: SRS_Req_info1 + :refs: SWA_Req_refderef1 + +:ref:`SWA_Req_refderef1` diff --git a/dox_trace/spec/test_input/tr_architecture_ref_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_ref_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_ref_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_ref_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_ref_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_ref_empty/index.rst new file mode 100644 index 0000000..1043e2b --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_empty/index.rst @@ -0,0 +1,17 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. interface:: SWA_Req_notset2 + :developer: Abc AG + :status: invalid + +.. mod:: SWA_Req_notset3 + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_ref_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_ref_empty/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_ref_none/Makefile b/dox_trace/spec/test_input/tr_architecture_ref_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_ref_none/conf.py b/dox_trace/spec/test_input/tr_architecture_ref_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_ref_none/index.rst b/dox_trace/spec/test_input/tr_architecture_ref_none/index.rst new file mode 100644 index 0000000..bd721a3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_none/index.rst @@ -0,0 +1,11 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_ref_none/report.rst b/dox_trace/spec/test_input/tr_architecture_ref_none/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/Makefile b/dox_trace/spec/test_input/tr_architecture_ref_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/abc/doc/index.rst b/dox_trace/spec/test_input/tr_architecture_ref_table/abc/doc/index.rst new file mode 100644 index 0000000..068db74 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/abc/doc/index.rst @@ -0,0 +1,2 @@ +abc +=== diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/conf.py b/dox_trace/spec/test_input/tr_architecture_ref_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/index.rst b/dox_trace/spec/test_input/tr_architecture_ref_table/index.rst new file mode 100644 index 0000000..d3b1805 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/index.rst @@ -0,0 +1,99 @@ +Heading +======= + +.. spec:: SWA_Req_deref1 + :developer: Abc AG + :status: valid + :refs: SWA_Req_refderef1, SWA_Req_refderef2, SWA_Second_ref1 + +.. interface:: SWA_Req_refderef1 + :developer: Abc AG + :status: valid + :refs: SWA_Req_refderef2 + +.. spec:: SWA_Req_refderef2 + :developer: Abc AG + :status: valid + :refs: SWA_Req_notset2 + +.. mod:: SWA_Req_no1 + :developer: Abc AG + :status: valid + +.. spec:: SWA_Req_deref2 + :developer: Abc AG + :status: valid + :sources: index.rst, second.rst + :refs: SWA_Req_notset2 + +.. spec:: SWA_Req_deref3 + :developer: Abc AG + :status: valid + :sources: index.rst + +.. mod:: SWA_Req_deref4 + :developer: Abc AG + :status: valid + :location: abc + +.. mod:: SWA_Req_deref5 + :developer: Abc AG + :status: valid + :location: efg + +Upper Level +----------- + +.. spec:: SWA_Level_none + :developer: Abc AG + :status: valid + +.. spec:: SWA_Level_swa + :developer: Abc AG + :status: valid + +.. spec:: SWA_Level_srs + :developer: Abc AG + :status: valid + +.. spec:: SWA_Level_software + :developer: Abc AG + :status: valid + +.. spec:: SWA_Level_input + :developer: Abc AG + :status: valid + +.. spec:: SWA_Level_all + :developer: Abc AG + :status: valid + +.. spec:: SWA_Parent_swa + :developer: Abc AG + :status: valid + :refs: SWA_Level_swa, SWA_Level_all + +.. srs:: SRS_Parent_srs + :developer: Abc AG + :status: valid + :refs: SWA_Level_srs, SWA_Level_all + +.. requirement:: SRS_Parent_software + :category: software + :developer: Abc AG + :status: valid + :refs: SWA_Level_software, SWA_Level_all + +.. requirement:: Input_Parent_input + :category: input + :review_status: accepted + :status: valid + :refs: SWA_Level_input, SWA_Level_all + + +.. toctree:: + + second + third + report + abc/doc/index diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/report.rst b/dox_trace/spec/test_input/tr_architecture_ref_table/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/second.rst b/dox_trace/spec/test_input/tr_architecture_ref_table/second.rst new file mode 100644 index 0000000..a269255 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. spec:: SWA_Second_ref1 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_architecture_ref_table/third.rst b/dox_trace/spec/test_input/tr_architecture_ref_table/third.rst new file mode 100644 index 0000000..8aa58cd --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_ref_table/third.rst @@ -0,0 +1,14 @@ +Third Document +============== + +.. spec:: SWA_Req_notset2 + :developer: Other + +.. spec:: SWA_Req_notset3 + :developer: Other + :refs: SWA_Req_refderef1 + +.. information:: SRS_Req_info1 + :refs: SWA_Req_refderef1 + +:ref:`SWA_Req_refderef1` diff --git a/dox_trace/spec/test_input/tr_architecture_safety_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_safety_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_safety_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_safety_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_safety_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_safety_empty/index.rst new file mode 100644 index 0000000..bdaee66 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. spec:: SWA_Req_notset2 + :developer: Abc AG + :status: invalid + +.. interface:: SWA_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_safety_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_safety_empty/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_safety_none/Makefile b/dox_trace/spec/test_input/tr_architecture_safety_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_safety_none/conf.py b/dox_trace/spec/test_input/tr_architecture_safety_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_safety_none/index.rst b/dox_trace/spec/test_input/tr_architecture_safety_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_safety_none/report.rst b/dox_trace/spec/test_input/tr_architecture_safety_none/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/Makefile b/dox_trace/spec/test_input/tr_architecture_safety_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/conf.py b/dox_trace/spec/test_input/tr_architecture_safety_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/index.rst b/dox_trace/spec/test_input/tr_architecture_safety_table/index.rst new file mode 100644 index 0000000..c87f0af --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SWA_Req_A1 + :developer: Abc AG + :status: valid + :asil: ASIL_A + +.. spec:: SWA_Req_A2 + :developer: Abc AG + :status: valid + :asil: ASIL_A + +.. interface:: SWA_Req_B(C)1 + :developer: Abc AG + :status: valid + :asil: ASIL_B(C) + +.. spec:: SWA_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/report.rst b/dox_trace/spec/test_input/tr_architecture_safety_table/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/second.rst b/dox_trace/spec/test_input/tr_architecture_safety_table/second.rst new file mode 100644 index 0000000..65338e4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. spec:: SWA_Second_QM + :developer: Abc AG + :status: valid + :asil: QM diff --git a/dox_trace/spec/test_input/tr_architecture_safety_table/third.rst b/dox_trace/spec/test_input/tr_architecture_safety_table/third.rst new file mode 100644 index 0000000..6dc2114 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_safety_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SWA_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_architecture_security_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_security_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_security_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_security_empty/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_empty/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_architecture_security_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_security_empty/index.rst new file mode 100644 index 0000000..bdaee66 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. spec:: SWA_Req_notset2 + :developer: Abc AG + :status: invalid + +.. interface:: SWA_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_security_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_security_empty/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_security_none/Makefile b/dox_trace/spec/test_input/tr_architecture_security_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_security_none/conf.py b/dox_trace/spec/test_input/tr_architecture_security_none/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_none/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_architecture_security_none/index.rst b/dox_trace/spec/test_input/tr_architecture_security_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_security_none/report.rst b/dox_trace/spec/test_input/tr_architecture_security_none/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/Makefile b/dox_trace/spec/test_input/tr_architecture_security_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/conf.py b/dox_trace/spec/test_input/tr_architecture_security_table/conf.py new file mode 100644 index 0000000..dca84fc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/conf.py @@ -0,0 +1,12 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/index.rst b/dox_trace/spec/test_input/tr_architecture_security_table/index.rst new file mode 100644 index 0000000..e39c354 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SWA_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + +.. spec:: SWA_Req_yes2 + :developer: Abc AG + :status: valid + :security: yes + +.. interface:: SWA_Req_no1 + :developer: Abc AG + :status: valid + :security: no + +.. spec:: SWA_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/properties.yaml b/dox_trace/spec/test_input/tr_architecture_security_table/properties.yaml new file mode 100644 index 0000000..adb73ae --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/properties.yaml @@ -0,0 +1 @@ +SWA_Second: { security: "no" } diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/report.rst b/dox_trace/spec/test_input/tr_architecture_security_table/report.rst new file mode 100644 index 0000000..fc39cc3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Architecture +------------ + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/second.rst b/dox_trace/spec/test_input/tr_architecture_security_table/second.rst new file mode 100644 index 0000000..7421093 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. spec:: SWA_Second_no2 + :developer: Abc AG + :status: valid + diff --git a/dox_trace/spec/test_input/tr_architecture_security_table/third.rst b/dox_trace/spec/test_input/tr_architecture_security_table/third.rst new file mode 100644 index 0000000..6dc2114 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_security_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SWA_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_architecture_status_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_status_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_status_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_status_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_status_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_status_empty/index.rst new file mode 100644 index 0000000..35dc0b1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_empty/index.rst @@ -0,0 +1,16 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. interface:: SWA_Req_notset2 + :developer: Other + +.. mod:: SWA_Req_notset3 + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_status_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_status_empty/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_status_none/Makefile b/dox_trace/spec/test_input/tr_architecture_status_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_status_none/conf.py b/dox_trace/spec/test_input/tr_architecture_status_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_status_none/index.rst b/dox_trace/spec/test_input/tr_architecture_status_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_status_none/report.rst b/dox_trace/spec/test_input/tr_architecture_status_none/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/Makefile b/dox_trace/spec/test_input/tr_architecture_status_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/conf.py b/dox_trace/spec/test_input/tr_architecture_status_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/index.rst b/dox_trace/spec/test_input/tr_architecture_status_table/index.rst new file mode 100644 index 0000000..8fece6a --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SWA_Req_valid1 + :developer: Abc AG + :status: valid + +.. spec:: SWA_Req_valid2 + :developer: Abc AG + :status: valid + +.. mod:: SWA_Req_draft1 + :developer: Abc AG + +.. spec:: SWA_Req_draft2 + :developer: Abc AG + :status: draft + +.. interface:: SWA_Req_invalid1 + :developer: Abc AG + :status: invalid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/report.rst b/dox_trace/spec/test_input/tr_architecture_status_table/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/second.rst b/dox_trace/spec/test_input/tr_architecture_status_table/second.rst new file mode 100644 index 0000000..bef7014 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. interface:: SWA_Second_valid3 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_architecture_status_table/third.rst b/dox_trace/spec/test_input/tr_architecture_status_table/third.rst new file mode 100644 index 0000000..acc9cee --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_status_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. spec:: SWA_Req_notset2 + :developer: Other diff --git a/dox_trace/spec/test_input/tr_architecture_type_empty/Makefile b/dox_trace/spec/test_input/tr_architecture_type_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_type_empty/conf.py b/dox_trace/spec/test_input/tr_architecture_type_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_type_empty/index.rst b/dox_trace/spec/test_input/tr_architecture_type_empty/index.rst new file mode 100644 index 0000000..b0ae8f6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_empty/index.rst @@ -0,0 +1,20 @@ +Heading +======= + +.. spec:: SWA_Req_notset1 + :developer: Other + +.. interface:: SWA_Req_notset2 + :developer: Other + +.. mod:: SWA_Req_notset3 + :developer: Other + +.. spec:: SWA_Req_notset4 + :developer: Abc AG + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_type_empty/report.rst b/dox_trace/spec/test_input/tr_architecture_type_empty/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_type_none/Makefile b/dox_trace/spec/test_input/tr_architecture_type_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_type_none/conf.py b/dox_trace/spec/test_input/tr_architecture_type_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_type_none/index.rst b/dox_trace/spec/test_input/tr_architecture_type_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_architecture_type_none/report.rst b/dox_trace/spec/test_input/tr_architecture_type_none/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/Makefile b/dox_trace/spec/test_input/tr_architecture_type_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/conf.py b/dox_trace/spec/test_input/tr_architecture_type_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/index.rst b/dox_trace/spec/test_input/tr_architecture_type_table/index.rst new file mode 100644 index 0000000..a7a727f --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/index.rst @@ -0,0 +1,28 @@ +Heading +======= + +.. spec:: SWA_Req_spec1 + :developer: Abc AG + :status: valid + +.. spec:: SWA_Req_spec2 + :developer: Abc AG + :status: valid + +.. mod:: SWA_Req_mod1 + :developer: Abc AG + :status: valid + +.. spec:: SWA_Req_spec3 + :developer: Abc AG + :status: valid + +.. interface:: SWA_Req_interface1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/report.rst b/dox_trace/spec/test_input/tr_architecture_type_table/report.rst new file mode 100644 index 0000000..e0564dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Architecture +--------------------- + +.. traceability_report:: architecture + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/second.rst b/dox_trace/spec/test_input/tr_architecture_type_table/second.rst new file mode 100644 index 0000000..b1ee6e6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. interface:: SWA_Second_interface2 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_architecture_type_table/third.rst b/dox_trace/spec/test_input/tr_architecture_type_table/third.rst new file mode 100644 index 0000000..acc9cee --- /dev/null +++ b/dox_trace/spec/test_input/tr_architecture_type_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. spec:: SWA_Req_notset2 + :developer: Other diff --git a/dox_trace/spec/test_input/tr_general_developerregex/Makefile b/dox_trace/spec/test_input/tr_general_developerregex/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_developerregex/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_general_developerregex/conf.py b/dox_trace/spec/test_input/tr_general_developerregex/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_developerregex/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_general_developerregex/index.rst b/dox_trace/spec/test_input/tr_general_developerregex/index.rst new file mode 100644 index 0000000..3f9933a --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_developerregex/index.rst @@ -0,0 +1,37 @@ +Heading +======= + +.. srs:: SRS_Req_ok1 + :developer: Abc AG + +.. srs:: SRS_Req_ok2 + :developer: ABCAg + +.. srs:: SRS_Req_ok3 + :developer: abc AG + +.. srs:: SRS_Req_ok4 + :developer: Abc_AG + +.. srs:: SRS_Req_ok5 + :developer: abc_ag + +.. srs:: SRS_Req_ok6 + :developer: Other, abc_aG + +.. srs:: SRS_Req_ok7 + :developer: Abc AG, Abc ag + +.. srs:: SRS_Req_nok1 + :developer: ABC Ag2 + +.. srs:: SRS_Req_nok2 + :developer: Abc + +.. srs:: SRS_Req_nok3 + :developer: Abc*Ag + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_general_developerregex/report.rst b/dox_trace/spec/test_input/tr_general_developerregex/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_developerregex/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_general_ignore/Makefile b/dox_trace/spec/test_input/tr_general_ignore/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_ignore/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_general_ignore/conf.py b/dox_trace/spec/test_input/tr_general_ignore/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_ignore/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_general_ignore/index.rst b/dox_trace/spec/test_input/tr_general_ignore/index.rst new file mode 100644 index 0000000..6a7055f --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_ignore/index.rst @@ -0,0 +1,11 @@ +.. spec:: SMD_Req_1 + :ignore_in_export: + :developer: Abc AG + +.. spec:: SMD_Req_2 + :developer: Abc AG + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_general_ignore/report.rst b/dox_trace/spec/test_input/tr_general_ignore/report.rst new file mode 100644 index 0000000..7560256 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_ignore/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Module +------ + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_general_invalidcategory/Makefile b/dox_trace/spec/test_input/tr_general_invalidcategory/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_invalidcategory/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_general_invalidcategory/conf.py b/dox_trace/spec/test_input/tr_general_invalidcategory/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_invalidcategory/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_general_invalidcategory/index.rst b/dox_trace/spec/test_input/tr_general_invalidcategory/index.rst new file mode 100644 index 0000000..3d1242f --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_invalidcategory/index.rst @@ -0,0 +1,9 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_general_invalidcategory/report.rst b/dox_trace/spec/test_input/tr_general_invalidcategory/report.rst new file mode 100644 index 0000000..cd80b0e --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_invalidcategory/report.rst @@ -0,0 +1,7 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: nope diff --git a/dox_trace/spec/test_input/tr_general_missingdeveloper/Makefile b/dox_trace/spec/test_input/tr_general_missingdeveloper/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_missingdeveloper/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_general_missingdeveloper/conf.py b/dox_trace/spec/test_input/tr_general_missingdeveloper/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_missingdeveloper/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_general_missingdeveloper/index.rst b/dox_trace/spec/test_input/tr_general_missingdeveloper/index.rst new file mode 100644 index 0000000..3d1242f --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_missingdeveloper/index.rst @@ -0,0 +1,9 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_general_missingdeveloper/report.rst b/dox_trace/spec/test_input/tr_general_missingdeveloper/report.rst new file mode 100644 index 0000000..c8aaf0d --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_missingdeveloper/report.rst @@ -0,0 +1,7 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: software diff --git a/dox_trace/spec/test_input/tr_general_notitle/Makefile b/dox_trace/spec/test_input/tr_general_notitle/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_notitle/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_general_notitle/conf.py b/dox_trace/spec/test_input/tr_general_notitle/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_notitle/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_general_notitle/index.rst b/dox_trace/spec/test_input/tr_general_notitle/index.rst new file mode 100644 index 0000000..d5b58a1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_notitle/index.rst @@ -0,0 +1,6 @@ +.. requirement:: CRS_Req_notset1 + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_general_notitle/report.rst b/dox_trace/spec/test_input/tr_general_notitle/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_general_notitle/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_cal_empty/Makefile b/dox_trace/spec/test_input/tr_input_cal_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_cal_empty/conf.py b/dox_trace/spec/test_input/tr_input_cal_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_cal_empty/index.rst b/dox_trace/spec/test_input/tr_input_cal_empty/index.rst new file mode 100644 index 0000000..5be5fc4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :developer: Other + :category: input + +.. requirement:: CRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: input + +.. requirement:: CRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_cal_empty/report.rst b/dox_trace/spec/test_input/tr_input_cal_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_cal_none/Makefile b/dox_trace/spec/test_input/tr_input_cal_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_cal_none/conf.py b/dox_trace/spec/test_input/tr_input_cal_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_cal_none/index.rst b/dox_trace/spec/test_input/tr_input_cal_none/index.rst new file mode 100644 index 0000000..b1e6d76 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_cal_none/report.rst b/dox_trace/spec/test_input/tr_input_cal_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_cal_table/Makefile b/dox_trace/spec/test_input/tr_input_cal_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_cal_table/conf.py b/dox_trace/spec/test_input/tr_input_cal_table/conf.py new file mode 100644 index 0000000..0a58d44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/tr_input_cal_table/index.rst b/dox_trace/spec/test_input/tr_input_cal_table/index.rst new file mode 100644 index 0000000..8a3cffc --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/index.rst @@ -0,0 +1,35 @@ +Heading +======= + +.. requirement:: CRS_Req_cal1 + :developer: Abc AG + :status: valid + :cal: CAL_1 + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_qm1 + :developer: Abc AG + :status: valid + :cal: QM + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_notset1 + :developer: Abc AG + :status: valid + :category: input + :review_status: accepted + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_cal_table/properties.yaml b/dox_trace/spec/test_input/tr_input_cal_table/properties.yaml new file mode 100644 index 0000000..9ed6742 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/properties.yaml @@ -0,0 +1 @@ +CRS_Second: { cal: "QM" } diff --git a/dox_trace/spec/test_input/tr_input_cal_table/report.rst b/dox_trace/spec/test_input/tr_input_cal_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_cal_table/second.rst b/dox_trace/spec/test_input/tr_input_cal_table/second.rst new file mode 100644 index 0000000..419dfd2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/second.rst @@ -0,0 +1,9 @@ +Second Document +=============== + +.. requirement:: CRS_Second_qm2 + :developer: Abc AG + :status: valid + :category: input + :review_status: accepted + diff --git a/dox_trace/spec/test_input/tr_input_cal_table/third.rst b/dox_trace/spec/test_input/tr_input_cal_table/third.rst new file mode 100644 index 0000000..1a19a97 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_cal_table/third.rst @@ -0,0 +1,8 @@ +Third Document +============== + +.. requirement:: CRS_Req_ignored + :developer: Abc AG + :status: invalid + :category: input + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_input_dev_none/Makefile b/dox_trace/spec/test_input/tr_input_dev_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_dev_none/conf.py b/dox_trace/spec/test_input/tr_input_dev_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_dev_none/index.rst b/dox_trace/spec/test_input/tr_input_dev_none/index.rst new file mode 100644 index 0000000..07df2e2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_dev_none/report.rst b/dox_trace/spec/test_input/tr_input_dev_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_dev_table/Makefile b/dox_trace/spec/test_input/tr_input_dev_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_dev_table/conf.py b/dox_trace/spec/test_input/tr_input_dev_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_dev_table/index.rst b/dox_trace/spec/test_input/tr_input_dev_table/index.rst new file mode 100644 index 0000000..fbaf4f2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_table/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. requirement:: CRS_Req_notset1 + :category: input + +.. requirement:: CRS_Req_notset2 + :category: input + +.. requirement:: CRS_Req_notset3 + :category: input + +.. toctree:: + + second + report \ No newline at end of file diff --git a/dox_trace/spec/test_input/tr_input_dev_table/report.rst b/dox_trace/spec/test_input/tr_input_dev_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_dev_table/second.rst b/dox_trace/spec/test_input/tr_input_dev_table/second.rst new file mode 100644 index 0000000..26788ea --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_dev_table/second.rst @@ -0,0 +1,18 @@ +Second Document +=============== + +.. requirement:: CRS_Req_abc1 + :category: input + :developer: Abc AG + +.. requirement:: CRS_Req_abc2 + :category: input + :developer: Abc AG + +.. requirement:: CRS_Req_other1 + :category: input + :developer: Someone else + +.. requirement:: CRS_Req_abcother1 + :category: input + :developer: Someone else, Abc AG diff --git a/dox_trace/spec/test_input/tr_input_list_empty/Makefile b/dox_trace/spec/test_input/tr_input_list_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_list_empty/conf.py b/dox_trace/spec/test_input/tr_input_list_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_list_empty/index.rst b/dox_trace/spec/test_input/tr_input_list_empty/index.rst new file mode 100644 index 0000000..113e37a --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_empty/index.rst @@ -0,0 +1,21 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. requirement:: CRS_Req_notset2 + :category: input + :developer: Abc AG + :status: draft + +.. requirement:: CRS_Req_notset3 + :category: input + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_list_empty/report.rst b/dox_trace/spec/test_input/tr_input_list_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_list_none/Makefile b/dox_trace/spec/test_input/tr_input_list_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_list_none/conf.py b/dox_trace/spec/test_input/tr_input_list_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_list_none/index.rst b/dox_trace/spec/test_input/tr_input_list_none/index.rst new file mode 100644 index 0000000..07df2e2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_list_none/report.rst b/dox_trace/spec/test_input/tr_input_list_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_list_table/Makefile b/dox_trace/spec/test_input/tr_input_list_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_list_table/conf.py b/dox_trace/spec/test_input/tr_input_list_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_list_table/index.rst b/dox_trace/spec/test_input/tr_input_list_table/index.rst new file mode 100644 index 0000000..45ddc77 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/index.rst @@ -0,0 +1,44 @@ +Heading +======= + +.. requirement:: CRS_Req_deref1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_refderef1, CRS_Req_refderef2, CRS_Req_ref1 + +.. requirement:: CRS_Req_refderef1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_refderef2 + +.. requirement:: CRS_Req_refderef2 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_notset2 + +.. requirement:: CRS_Req_deref2 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :tags: covered + +.. requirement:: CRS_Req_deref3 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :sources: index.rst, second.rst + :refs: CRS_Req_notset2 + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_list_table/report.rst b/dox_trace/spec/test_input/tr_input_list_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_list_table/second.rst b/dox_trace/spec/test_input/tr_input_list_table/second.rst new file mode 100644 index 0000000..2580ab0 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: CRS_Req_ref1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_input_list_table/third.rst b/dox_trace/spec/test_input/tr_input_list_table/third.rst new file mode 100644 index 0000000..6c807fe --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_list_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: CRS_Req_notset2 + :category: input diff --git a/dox_trace/spec/test_input/tr_input_ref_empty/Makefile b/dox_trace/spec/test_input/tr_input_ref_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_ref_empty/conf.py b/dox_trace/spec/test_input/tr_input_ref_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_ref_empty/index.rst b/dox_trace/spec/test_input/tr_input_ref_empty/index.rst new file mode 100644 index 0000000..113e37a --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_empty/index.rst @@ -0,0 +1,21 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. requirement:: CRS_Req_notset2 + :category: input + :developer: Abc AG + :status: draft + +.. requirement:: CRS_Req_notset3 + :category: input + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_ref_empty/report.rst b/dox_trace/spec/test_input/tr_input_ref_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_ref_none/Makefile b/dox_trace/spec/test_input/tr_input_ref_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_ref_none/conf.py b/dox_trace/spec/test_input/tr_input_ref_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_ref_none/index.rst b/dox_trace/spec/test_input/tr_input_ref_none/index.rst new file mode 100644 index 0000000..07df2e2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_ref_none/report.rst b/dox_trace/spec/test_input/tr_input_ref_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_ref_table/Makefile b/dox_trace/spec/test_input/tr_input_ref_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_ref_table/conf.py b/dox_trace/spec/test_input/tr_input_ref_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_ref_table/index.rst b/dox_trace/spec/test_input/tr_input_ref_table/index.rst new file mode 100644 index 0000000..45ddc77 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/index.rst @@ -0,0 +1,44 @@ +Heading +======= + +.. requirement:: CRS_Req_deref1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_refderef1, CRS_Req_refderef2, CRS_Req_ref1 + +.. requirement:: CRS_Req_refderef1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_refderef2 + +.. requirement:: CRS_Req_refderef2 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: CRS_Req_notset2 + +.. requirement:: CRS_Req_deref2 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :tags: covered + +.. requirement:: CRS_Req_deref3 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + :sources: index.rst, second.rst + :refs: CRS_Req_notset2 + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_ref_table/report.rst b/dox_trace/spec/test_input/tr_input_ref_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_ref_table/second.rst b/dox_trace/spec/test_input/tr_input_ref_table/second.rst new file mode 100644 index 0000000..2580ab0 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: CRS_Req_ref1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_input_ref_table/third.rst b/dox_trace/spec/test_input/tr_input_ref_table/third.rst new file mode 100644 index 0000000..6c807fe --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_ref_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: CRS_Req_notset2 + :category: input diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_empty/Makefile b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_empty/conf.py b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_empty/index.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/index.rst new file mode 100644 index 0000000..669c709 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/index.rst @@ -0,0 +1,20 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. requirement:: CRS_Req_notset2 + :category: input + :developer: Abc AG + :status: draft + +.. requirement:: CRS_Req_notset3 + :category: input + :developer: Other, Company + :status: valid + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_empty/report.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_none/Makefile b/dox_trace/spec/test_input/tr_input_reviewstatus_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_none/conf.py b/dox_trace/spec/test_input/tr_input_reviewstatus_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_none/index.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_none/index.rst new file mode 100644 index 0000000..07df2e2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_none/report.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/Makefile b/dox_trace/spec/test_input/tr_input_reviewstatus_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/conf.py b/dox_trace/spec/test_input/tr_input_reviewstatus_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/index.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_table/index.rst new file mode 100644 index 0000000..2d0a974 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/index.rst @@ -0,0 +1,50 @@ +Heading +======= + +.. requirement:: CRS_Req_accepted1 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + +.. requirement:: CRS_Req_accepted2 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + +.. requirement:: CRS_Req_unclear1 + :category: input + :developer: Abc AG + :status: valid + :review_status: unclear + +.. requirement:: CRS_Req_unclear2 + :category: input + :developer: Abc AG + :status: valid + :review_status: unclear + +.. requirement:: CRS_Req_rejected1 + :category: input + :developer: Abc AG + :status: valid + :review_status: rejected + +.. requirement:: CRS_Req_notrelevant1 + :category: input + :developer: Abc AG + :status: valid + :review_status: not_relevant + +.. requirement:: CRS_Req_notreviewed1 + :category: input + :developer: Abc AG + :status: valid + :review_status: not_reviewed + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/report.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/second.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_table/second.rst new file mode 100644 index 0000000..8ff88b4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/second.rst @@ -0,0 +1,19 @@ +Second Document +=============== + +.. requirement:: CRS_Req_accepted3 + :category: input + :developer: Abc AG + :status: valid + :review_status: accepted + +.. requirement:: CRS_Req_notreviewed2 + :category: input + :developer: Abc AG + :status: valid + +.. requirement:: CRS_Req_invalid1 + :category: input + :developer: Abc AG + :status: valid + :review_status: invalid diff --git a/dox_trace/spec/test_input/tr_input_reviewstatus_table/third.rst b/dox_trace/spec/test_input/tr_input_reviewstatus_table/third.rst new file mode 100644 index 0000000..417a050 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_reviewstatus_table/third.rst @@ -0,0 +1,11 @@ +Third Document +============== + +.. requirement:: CRS_Req_notset2 + :category: input + +.. requirement:: CRS_Req_notset3 + :category: input + :status: valid + :developer: Other + diff --git a/dox_trace/spec/test_input/tr_input_safety_empty/Makefile b/dox_trace/spec/test_input/tr_input_safety_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_safety_empty/conf.py b/dox_trace/spec/test_input/tr_input_safety_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_safety_empty/index.rst b/dox_trace/spec/test_input/tr_input_safety_empty/index.rst new file mode 100644 index 0000000..5be5fc4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :developer: Other + :category: input + +.. requirement:: CRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: input + +.. requirement:: CRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_safety_empty/report.rst b/dox_trace/spec/test_input/tr_input_safety_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_safety_none/Makefile b/dox_trace/spec/test_input/tr_input_safety_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_safety_none/conf.py b/dox_trace/spec/test_input/tr_input_safety_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_safety_none/index.rst b/dox_trace/spec/test_input/tr_input_safety_none/index.rst new file mode 100644 index 0000000..b1e6d76 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_safety_none/report.rst b/dox_trace/spec/test_input/tr_input_safety_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_safety_table/Makefile b/dox_trace/spec/test_input/tr_input_safety_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_safety_table/conf.py b/dox_trace/spec/test_input/tr_input_safety_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_safety_table/index.rst b/dox_trace/spec/test_input/tr_input_safety_table/index.rst new file mode 100644 index 0000000..4c28d74 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/index.rst @@ -0,0 +1,29 @@ +Heading +======= + +.. requirement:: CRS_Req_A1 + :developer: Abc AG + :status: valid + :asil: ASIL_A + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_A2 + :developer: Abc AG + :status: valid + :asil: ASIL_A + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_B(C)1 + :developer: Abc AG + :status: valid + :asil: ASIL_B(C) + :category: input + :review_status: accepted + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_safety_table/report.rst b/dox_trace/spec/test_input/tr_input_safety_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_safety_table/second.rst b/dox_trace/spec/test_input/tr_input_safety_table/second.rst new file mode 100644 index 0000000..1d0c27c --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/second.rst @@ -0,0 +1,10 @@ +Second Document +=============== + +.. requirement:: CRS_Second_QM + :developer: Abc AG + :status: valid + :category: input + :review_status: accepted + :asil: QM + diff --git a/dox_trace/spec/test_input/tr_input_safety_table/third.rst b/dox_trace/spec/test_input/tr_input_safety_table/third.rst new file mode 100644 index 0000000..1a19a97 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_safety_table/third.rst @@ -0,0 +1,8 @@ +Third Document +============== + +.. requirement:: CRS_Req_ignored + :developer: Abc AG + :status: invalid + :category: input + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_input_security_empty/Makefile b/dox_trace/spec/test_input/tr_input_security_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_security_empty/conf.py b/dox_trace/spec/test_input/tr_input_security_empty/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_empty/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_input_security_empty/index.rst b/dox_trace/spec/test_input/tr_input_security_empty/index.rst new file mode 100644 index 0000000..5be5fc4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :developer: Other + :category: input + +.. requirement:: CRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: input + +.. requirement:: CRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_security_empty/report.rst b/dox_trace/spec/test_input/tr_input_security_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_security_none/Makefile b/dox_trace/spec/test_input/tr_input_security_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_security_none/conf.py b/dox_trace/spec/test_input/tr_input_security_none/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_none/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_input_security_none/index.rst b/dox_trace/spec/test_input/tr_input_security_none/index.rst new file mode 100644 index 0000000..b1e6d76 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_security_none/report.rst b/dox_trace/spec/test_input/tr_input_security_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_security_table/Makefile b/dox_trace/spec/test_input/tr_input_security_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_security_table/conf.py b/dox_trace/spec/test_input/tr_input_security_table/conf.py new file mode 100644 index 0000000..dca84fc --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/conf.py @@ -0,0 +1,12 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_input_security_table/index.rst b/dox_trace/spec/test_input/tr_input_security_table/index.rst new file mode 100644 index 0000000..24b0a70 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/index.rst @@ -0,0 +1,35 @@ +Heading +======= + +.. requirement:: CRS_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_yes2 + :developer: Abc AG + :status: valid + :security: yes + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_no1 + :developer: Abc AG + :status: valid + :security: no + :category: input + :review_status: accepted + +.. requirement:: CRS_Req_notset1 + :developer: Abc AG + :status: valid + :category: input + :review_status: accepted + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_security_table/properties.yaml b/dox_trace/spec/test_input/tr_input_security_table/properties.yaml new file mode 100644 index 0000000..e17b6e0 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/properties.yaml @@ -0,0 +1 @@ +CRS_Second: { security: "no" } diff --git a/dox_trace/spec/test_input/tr_input_security_table/report.rst b/dox_trace/spec/test_input/tr_input_security_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_security_table/second.rst b/dox_trace/spec/test_input/tr_input_security_table/second.rst new file mode 100644 index 0000000..7aba015 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/second.rst @@ -0,0 +1,9 @@ +Second Document +=============== + +.. requirement:: CRS_Second_no2 + :developer: Abc AG + :status: valid + :category: input + :review_status: accepted + diff --git a/dox_trace/spec/test_input/tr_input_security_table/third.rst b/dox_trace/spec/test_input/tr_input_security_table/third.rst new file mode 100644 index 0000000..1a19a97 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_security_table/third.rst @@ -0,0 +1,8 @@ +Third Document +============== + +.. requirement:: CRS_Req_ignored + :developer: Abc AG + :status: invalid + :category: input + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_input_status_empty/Makefile b/dox_trace/spec/test_input/tr_input_status_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_status_empty/conf.py b/dox_trace/spec/test_input/tr_input_status_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_status_empty/index.rst b/dox_trace/spec/test_input/tr_input_status_empty/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_empty/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_status_empty/report.rst b/dox_trace/spec/test_input/tr_input_status_empty/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_status_none/Makefile b/dox_trace/spec/test_input/tr_input_status_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_status_none/conf.py b/dox_trace/spec/test_input/tr_input_status_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_status_none/index.rst b/dox_trace/spec/test_input/tr_input_status_none/index.rst new file mode 100644 index 0000000..07df2e2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. information:: CRS_Information_1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_input_status_none/report.rst b/dox_trace/spec/test_input/tr_input_status_none/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_status_table/Makefile b/dox_trace/spec/test_input/tr_input_status_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_input_status_table/conf.py b/dox_trace/spec/test_input/tr_input_status_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_input_status_table/index.rst b/dox_trace/spec/test_input/tr_input_status_table/index.rst new file mode 100644 index 0000000..dc64c0f --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/index.rst @@ -0,0 +1,32 @@ +Heading +======= + +.. requirement:: CRS_Req_valid1 + :category: input + :developer: Abc AG + :status: valid + +.. requirement:: CRS_Req_valid2 + :category: input + :developer: Abc AG + :status: valid + +.. requirement:: CRS_Req_draft1 + :category: input + :developer: Abc AG + +.. requirement:: CRS_Req_draft2 + :category: input + :developer: Abc AG + :status: draft + +.. requirement:: CRS_Req_invalid1 + :category: input + :developer: Abc AG + :status: invalid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_input_status_table/report.rst b/dox_trace/spec/test_input/tr_input_status_table/report.rst new file mode 100644 index 0000000..49559c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Input Requirements +------------------ + +.. traceability_report:: input + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_input_status_table/second.rst b/dox_trace/spec/test_input/tr_input_status_table/second.rst new file mode 100644 index 0000000..9687576 --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/second.rst @@ -0,0 +1,12 @@ +Second Document +=============== + +.. requirement:: CRS_Req_valid3 + :category: input + :developer: Abc AG + :status: valid + +.. requirement:: CRS_Req_invalidStatus + :category: input + :developer: Abc AG + :status: nope diff --git a/dox_trace/spec/test_input/tr_input_status_table/third.rst b/dox_trace/spec/test_input/tr_input_status_table/third.rst new file mode 100644 index 0000000..6c807fe --- /dev/null +++ b/dox_trace/spec/test_input/tr_input_status_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: CRS_Req_notset2 + :category: input diff --git a/dox_trace/spec/test_input/tr_module_cal_empty/Makefile b/dox_trace/spec/test_input/tr_module_cal_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_cal_empty/conf.py b/dox_trace/spec/test_input/tr_module_cal_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_cal_empty/index.rst b/dox_trace/spec/test_input/tr_module_cal_empty/index.rst new file mode 100644 index 0000000..9241fd6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. spec:: SMD_Req_notset2 + :developer: Abc AG + :status: invalid + +.. unit:: SMD_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_cal_empty/report.rst b/dox_trace/spec/test_input/tr_module_cal_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_cal_none/Makefile b/dox_trace/spec/test_input/tr_module_cal_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_cal_none/conf.py b/dox_trace/spec/test_input/tr_module_cal_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_cal_none/index.rst b/dox_trace/spec/test_input/tr_module_cal_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_cal_none/report.rst b/dox_trace/spec/test_input/tr_module_cal_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_cal_table/Makefile b/dox_trace/spec/test_input/tr_module_cal_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_cal_table/conf.py b/dox_trace/spec/test_input/tr_module_cal_table/conf.py new file mode 100644 index 0000000..0a58d44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/tr_module_cal_table/index.rst b/dox_trace/spec/test_input/tr_module_cal_table/index.rst new file mode 100644 index 0000000..414fade --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SMD_Req_cal1 + :developer: Abc AG + :status: valid + :cal: CAL_1 + +.. spec:: SMD_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + +.. unit:: SMD_Req_qm1 + :developer: Abc AG + :status: valid + :cal: QM + +.. spec:: SMD_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_cal_table/properties.yaml b/dox_trace/spec/test_input/tr_module_cal_table/properties.yaml new file mode 100644 index 0000000..e746e6b --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/properties.yaml @@ -0,0 +1 @@ +SMD_Second: { cal: "QM" } diff --git a/dox_trace/spec/test_input/tr_module_cal_table/report.rst b/dox_trace/spec/test_input/tr_module_cal_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_cal_table/second.rst b/dox_trace/spec/test_input/tr_module_cal_table/second.rst new file mode 100644 index 0000000..f367aa6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. spec:: SMD_Second_qm2 + :developer: Abc AG + :status: valid + diff --git a/dox_trace/spec/test_input/tr_module_cal_table/third.rst b/dox_trace/spec/test_input/tr_module_cal_table/third.rst new file mode 100644 index 0000000..2e2ecf5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_cal_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SMD_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_module_list_empty/Makefile b/dox_trace/spec/test_input/tr_module_list_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_list_empty/conf.py b/dox_trace/spec/test_input/tr_module_list_empty/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_empty/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_list_empty/index.rst b/dox_trace/spec/test_input/tr_module_list_empty/index.rst new file mode 100644 index 0000000..0496742 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_empty/index.rst @@ -0,0 +1,17 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. interface:: SMD_Req_notset2 + :developer: Abc AG + :status: invalid + +.. unit:: SMD_Req_notset3 + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_list_empty/report.rst b/dox_trace/spec/test_input/tr_module_list_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_list_none/Makefile b/dox_trace/spec/test_input/tr_module_list_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_list_none/conf.py b/dox_trace/spec/test_input/tr_module_list_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_list_none/index.rst b/dox_trace/spec/test_input/tr_module_list_none/index.rst new file mode 100644 index 0000000..bd721a3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_none/index.rst @@ -0,0 +1,11 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_list_none/report.rst b/dox_trace/spec/test_input/tr_module_list_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_list_table/AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt b/dox_trace/spec/test_input/tr_module_list_table/AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt new file mode 100644 index 0000000..53a90bf --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt @@ -0,0 +1 @@ +Empty diff --git a/dox_trace/spec/test_input/tr_module_list_table/Makefile b/dox_trace/spec/test_input/tr_module_list_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_list_table/conf.py b/dox_trace/spec/test_input/tr_module_list_table/conf.py new file mode 100644 index 0000000..abea30e --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True +dox_trace_allow_undefined_refs = True diff --git a/dox_trace/spec/test_input/tr_module_list_table/index.rst b/dox_trace/spec/test_input/tr_module_list_table/index.rst new file mode 100644 index 0000000..aa89c9e --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/index.rst @@ -0,0 +1,53 @@ +Heading +======= + +.. spec:: SMD_Req_deref1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef1, SMD_Req_refderef2, SMD_Second_ref1 + +.. interface:: SMD_Req_refderef1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef2 + +.. spec:: SMD_Req_refderef2 + :developer: Abc AG + :status: valid + :refs: SMD_Req_notset2 + +.. unit:: SMD_Req_no1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_deref2 + :developer: Abc AG + :status: valid + :sources: index.rst, second.rst + :refs: SMD_Req_notset2 + +.. spec:: SMD_Req_deref3 + :developer: Abc AG + :status: valid + :sources: index.rst + +.. spec:: SMD_Req_deref4 + :developer: Abc AG + :status: valid + :refs: invalid_ref + +.. spec:: SMD_Req_AbcccccccccccccccccccccccccccccccccccxAbcccc123xA-1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_AbcccccccccccxAbcccc123xA-2 + :sources: AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt + +.. spec:: SMD_Req_AbcccccccccccxAbcccc123xA-2 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_list_table/report.rst b/dox_trace/spec/test_input/tr_module_list_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_list_table/second.rst b/dox_trace/spec/test_input/tr_module_list_table/second.rst new file mode 100644 index 0000000..79e305a --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. spec:: SMD_Second_ref1 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_module_list_table/third.rst b/dox_trace/spec/test_input/tr_module_list_table/third.rst new file mode 100644 index 0000000..27d47c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_list_table/third.rst @@ -0,0 +1,14 @@ +Third Document +============== + +.. spec:: SMD_Req_notset2 + :developer: Other + +.. spec:: SMD_Req_notset3 + :developer: Other + :refs: SMD_Req_refderef1 + +.. information:: SRS_Req_info1 + :refs: SMD_Req_refderef1 + +:ref:`SMD_Req_refderef1` diff --git a/dox_trace/spec/test_input/tr_module_ref_empty/Makefile b/dox_trace/spec/test_input/tr_module_ref_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_ref_empty/conf.py b/dox_trace/spec/test_input/tr_module_ref_empty/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_empty/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_ref_empty/index.rst b/dox_trace/spec/test_input/tr_module_ref_empty/index.rst new file mode 100644 index 0000000..0496742 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_empty/index.rst @@ -0,0 +1,17 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. interface:: SMD_Req_notset2 + :developer: Abc AG + :status: invalid + +.. unit:: SMD_Req_notset3 + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_ref_empty/report.rst b/dox_trace/spec/test_input/tr_module_ref_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_ref_none/Makefile b/dox_trace/spec/test_input/tr_module_ref_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_ref_none/conf.py b/dox_trace/spec/test_input/tr_module_ref_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_ref_none/index.rst b/dox_trace/spec/test_input/tr_module_ref_none/index.rst new file mode 100644 index 0000000..bd721a3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_none/index.rst @@ -0,0 +1,11 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_ref_none/report.rst b/dox_trace/spec/test_input/tr_module_ref_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_ref_table/Makefile b/dox_trace/spec/test_input/tr_module_ref_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_ref_table/conf.py b/dox_trace/spec/test_input/tr_module_ref_table/conf.py new file mode 100644 index 0000000..abea30e --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True +dox_trace_allow_undefined_refs = True diff --git a/dox_trace/spec/test_input/tr_module_ref_table/index.rst b/dox_trace/spec/test_input/tr_module_ref_table/index.rst new file mode 100644 index 0000000..1ad28a4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/index.rst @@ -0,0 +1,102 @@ +Heading +======= + +.. spec:: SMD_Req_deref1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef1, SMD_Req_refderef2, SMD_Second_ref1 + +.. interface:: SMD_Req_refderef1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef2 + +.. spec:: SMD_Req_refderef2 + :developer: Abc AG + :status: valid + :refs: SMD_Req_notset2 + +.. unit:: SMD_Req_no1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_deref2 + :developer: Abc AG + :status: valid + :sources: index.rst, second.rst + :refs: SMD_Req_notset2 + +.. spec:: SMD_Req_deref3 + :developer: Abc AG + :status: valid + :sources: index.rst + +.. spec:: SMD_Req_deref4 + :developer: Abc AG + :status: valid + :refs: invalid_ref + +Upper Level +----------- + +.. spec:: SMD_Level_none + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_smd + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_swa + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_srs + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_software + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_input + :developer: Abc AG + :status: valid + +.. spec:: SMD_Level_all + :developer: Abc AG + :status: valid + +.. spec:: SMD_Parent_smd + :developer: Abc AG + :status: valid + :refs: SMD_Level_smd, SMD_Level_all + +.. spec:: SWA_Parent_swa + :developer: Abc AG + :status: valid + :refs: SMD_Level_swa, SMD_Level_all + +.. srs:: SRS_Parent_srs + :developer: Abc AG + :status: valid + :refs: SMD_Level_srs, SMD_Level_all + +.. requirement:: SRS_Parent_software + :category: software + :developer: Abc AG + :status: valid + :refs: SMD_Level_software, SMD_Level_all + +.. requirement:: Input_Parent_input + :category: input + :review_status: accepted + :status: valid + :refs: SMD_Level_input, SMD_Level_all + + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_ref_table/report.rst b/dox_trace/spec/test_input/tr_module_ref_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_ref_table/second.rst b/dox_trace/spec/test_input/tr_module_ref_table/second.rst new file mode 100644 index 0000000..79e305a --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. spec:: SMD_Second_ref1 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_module_ref_table/third.rst b/dox_trace/spec/test_input/tr_module_ref_table/third.rst new file mode 100644 index 0000000..27d47c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_ref_table/third.rst @@ -0,0 +1,14 @@ +Third Document +============== + +.. spec:: SMD_Req_notset2 + :developer: Other + +.. spec:: SMD_Req_notset3 + :developer: Other + :refs: SMD_Req_refderef1 + +.. information:: SRS_Req_info1 + :refs: SMD_Req_refderef1 + +:ref:`SMD_Req_refderef1` diff --git a/dox_trace/spec/test_input/tr_module_safety_empty/Makefile b/dox_trace/spec/test_input/tr_module_safety_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_safety_empty/conf.py b/dox_trace/spec/test_input/tr_module_safety_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_safety_empty/index.rst b/dox_trace/spec/test_input/tr_module_safety_empty/index.rst new file mode 100644 index 0000000..9241fd6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. spec:: SMD_Req_notset2 + :developer: Abc AG + :status: invalid + +.. unit:: SMD_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_safety_empty/report.rst b/dox_trace/spec/test_input/tr_module_safety_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_safety_none/Makefile b/dox_trace/spec/test_input/tr_module_safety_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_safety_none/conf.py b/dox_trace/spec/test_input/tr_module_safety_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_safety_none/index.rst b/dox_trace/spec/test_input/tr_module_safety_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_safety_none/report.rst b/dox_trace/spec/test_input/tr_module_safety_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_safety_table/Makefile b/dox_trace/spec/test_input/tr_module_safety_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_safety_table/conf.py b/dox_trace/spec/test_input/tr_module_safety_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_safety_table/index.rst b/dox_trace/spec/test_input/tr_module_safety_table/index.rst new file mode 100644 index 0000000..bcaddf8 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SMD_Req_A1 + :developer: Abc AG + :status: valid + :asil: ASIL_A + +.. spec:: SMD_Req_A2 + :developer: Abc AG + :status: valid + :asil: ASIL_A + +.. unit:: SMD_Req_B(C)1 + :developer: Abc AG + :status: valid + :asil: ASIL_B(C) + +.. spec:: SMD_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_safety_table/report.rst b/dox_trace/spec/test_input/tr_module_safety_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_safety_table/second.rst b/dox_trace/spec/test_input/tr_module_safety_table/second.rst new file mode 100644 index 0000000..d335020 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. spec:: SMD_Second_QM + :developer: Abc AG + :status: valid + :asil: QM + diff --git a/dox_trace/spec/test_input/tr_module_safety_table/third.rst b/dox_trace/spec/test_input/tr_module_safety_table/third.rst new file mode 100644 index 0000000..2e2ecf5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_safety_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SMD_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_module_security_empty/Makefile b/dox_trace/spec/test_input/tr_module_security_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_security_empty/conf.py b/dox_trace/spec/test_input/tr_module_security_empty/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_empty/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_module_security_empty/index.rst b/dox_trace/spec/test_input/tr_module_security_empty/index.rst new file mode 100644 index 0000000..9241fd6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. spec:: SMD_Req_notset2 + :developer: Abc AG + :status: invalid + +.. unit:: SMD_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_security_empty/report.rst b/dox_trace/spec/test_input/tr_module_security_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_security_none/Makefile b/dox_trace/spec/test_input/tr_module_security_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_security_none/conf.py b/dox_trace/spec/test_input/tr_module_security_none/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_none/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_module_security_none/index.rst b/dox_trace/spec/test_input/tr_module_security_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_security_none/report.rst b/dox_trace/spec/test_input/tr_module_security_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_security_table/Makefile b/dox_trace/spec/test_input/tr_module_security_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_security_table/conf.py b/dox_trace/spec/test_input/tr_module_security_table/conf.py new file mode 100644 index 0000000..dca84fc --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/conf.py @@ -0,0 +1,12 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_module_security_table/index.rst b/dox_trace/spec/test_input/tr_module_security_table/index.rst new file mode 100644 index 0000000..82c21da --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SMD_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + +.. spec:: SMD_Req_yes2 + :developer: Abc AG + :status: valid + :security: yes + +.. unit:: SMD_Req_no1 + :developer: Abc AG + :status: valid + :security: no + +.. spec:: SMD_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_security_table/properties.yaml b/dox_trace/spec/test_input/tr_module_security_table/properties.yaml new file mode 100644 index 0000000..298f0b2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/properties.yaml @@ -0,0 +1 @@ +SMD_Second: { security: "no" } diff --git a/dox_trace/spec/test_input/tr_module_security_table/report.rst b/dox_trace/spec/test_input/tr_module_security_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_security_table/second.rst b/dox_trace/spec/test_input/tr_module_security_table/second.rst new file mode 100644 index 0000000..b0525c1 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. spec:: SMD_Second_no2 + :developer: Abc AG + :status: valid + diff --git a/dox_trace/spec/test_input/tr_module_security_table/third.rst b/dox_trace/spec/test_input/tr_module_security_table/third.rst new file mode 100644 index 0000000..2e2ecf5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_security_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SMD_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_module_status_empty/Makefile b/dox_trace/spec/test_input/tr_module_status_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_status_empty/conf.py b/dox_trace/spec/test_input/tr_module_status_empty/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_empty/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_status_empty/index.rst b/dox_trace/spec/test_input/tr_module_status_empty/index.rst new file mode 100644 index 0000000..56f5f15 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_empty/index.rst @@ -0,0 +1,16 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + +.. interface:: SMD_Req_notset2 + :developer: Other + +.. unit:: SMD_Req_notset3 + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_status_empty/report.rst b/dox_trace/spec/test_input/tr_module_status_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_status_none/Makefile b/dox_trace/spec/test_input/tr_module_status_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_status_none/conf.py b/dox_trace/spec/test_input/tr_module_status_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_status_none/index.rst b/dox_trace/spec/test_input/tr_module_status_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_status_none/report.rst b/dox_trace/spec/test_input/tr_module_status_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_status_table/Makefile b/dox_trace/spec/test_input/tr_module_status_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_status_table/conf.py b/dox_trace/spec/test_input/tr_module_status_table/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_status_table/index.rst b/dox_trace/spec/test_input/tr_module_status_table/index.rst new file mode 100644 index 0000000..b5edbb2 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/index.rst @@ -0,0 +1,27 @@ +Heading +======= + +.. spec:: SMD_Req_valid1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_valid2 + :developer: Abc AG + :status: valid + +.. unit:: SMD_Req_draft1 + :developer: Abc AG + +.. spec:: SMD_Req_draft2 + :developer: Abc AG + :status: draft + +.. interface:: SMD_Req_invalid1 + :developer: Abc AG + :status: invalid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_status_table/report.rst b/dox_trace/spec/test_input/tr_module_status_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_status_table/second.rst b/dox_trace/spec/test_input/tr_module_status_table/second.rst new file mode 100644 index 0000000..65d1d9c --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. interface:: SMD_Second_valid3 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_module_status_table/third.rst b/dox_trace/spec/test_input/tr_module_status_table/third.rst new file mode 100644 index 0000000..eb116df --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_status_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. spec:: SMD_Req_notset2 + :developer: Other diff --git a/dox_trace/spec/test_input/tr_module_type_empty/Makefile b/dox_trace/spec/test_input/tr_module_type_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_type_empty/conf.py b/dox_trace/spec/test_input/tr_module_type_empty/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_empty/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_type_empty/index.rst b/dox_trace/spec/test_input/tr_module_type_empty/index.rst new file mode 100644 index 0000000..81c210e --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_empty/index.rst @@ -0,0 +1,20 @@ +Heading +======= + +.. spec:: SMD_Req_notset1 + :developer: Other + :status: valid + +.. interface:: SMD_Req_notset2 + :developer: Abc AG + :status: draft + +.. unit:: SMD_Req_notset3 + :developer: Abc AG + :review_status: not_reviewed + :status: valid + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_type_empty/report.rst b/dox_trace/spec/test_input/tr_module_type_empty/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_type_none/Makefile b/dox_trace/spec/test_input/tr_module_type_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_type_none/conf.py b/dox_trace/spec/test_input/tr_module_type_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_type_none/index.rst b/dox_trace/spec/test_input/tr_module_type_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_module_type_none/report.rst b/dox_trace/spec/test_input/tr_module_type_none/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_type_table/Makefile b/dox_trace/spec/test_input/tr_module_type_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_type_table/conf.py b/dox_trace/spec/test_input/tr_module_type_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_module_type_table/index.rst b/dox_trace/spec/test_input/tr_module_type_table/index.rst new file mode 100644 index 0000000..3347d12 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/index.rst @@ -0,0 +1,24 @@ +Heading +======= + +.. spec:: SMD_Req_spec1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_spec2 + :developer: Abc AG + :status: valid + +.. unit:: SMD_Req_unit1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_spec3 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_type_table/report.rst b/dox_trace/spec/test_input/tr_module_type_table/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_type_table/second.rst b/dox_trace/spec/test_input/tr_module_type_table/second.rst new file mode 100644 index 0000000..76b165b --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. unit:: SMD_Second_unit2 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_module_type_table/third.rst b/dox_trace/spec/test_input/tr_module_type_table/third.rst new file mode 100644 index 0000000..333cf44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SMD_Req_notset1 + :developer: Abc AG + :status: draft \ No newline at end of file diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/Makefile b/dox_trace/spec/test_input/tr_module_type_table_deprecated/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/conf.py b/dox_trace/spec/test_input/tr_module_type_table_deprecated/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/index.rst b/dox_trace/spec/test_input/tr_module_type_table_deprecated/index.rst new file mode 100644 index 0000000..515a4f8 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/index.rst @@ -0,0 +1,28 @@ +Heading +======= + +.. spec:: SMD_Req_spec1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_spec2 + :developer: Abc AG + :status: valid + +.. unit:: SMD_Req_unit1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_spec3 + :developer: Abc AG + :status: valid + +.. interface:: SMD_Req_interface1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/report.rst b/dox_trace/spec/test_input/tr_module_type_table_deprecated/report.rst new file mode 100644 index 0000000..2ec68ff --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Module Design +---------------------- + +.. traceability_report:: module + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/second.rst b/dox_trace/spec/test_input/tr_module_type_table_deprecated/second.rst new file mode 100644 index 0000000..76b165b --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. unit:: SMD_Second_unit2 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_module_type_table_deprecated/third.rst b/dox_trace/spec/test_input/tr_module_type_table_deprecated/third.rst new file mode 100644 index 0000000..333cf44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_module_type_table_deprecated/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. spec:: SMD_Req_notset1 + :developer: Abc AG + :status: draft \ No newline at end of file diff --git a/dox_trace/spec/test_input/tr_software_cal_empty/Makefile b/dox_trace/spec/test_input/tr_software_cal_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_cal_empty/conf.py b/dox_trace/spec/test_input/tr_software_cal_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_cal_empty/index.rst b/dox_trace/spec/test_input/tr_software_cal_empty/index.rst new file mode 100644 index 0000000..811fa83 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :developer: Other + :category: software + +.. requirement:: SRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: software + +.. requirement:: SRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_cal_empty/report.rst b/dox_trace/spec/test_input/tr_software_cal_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_cal_none/Makefile b/dox_trace/spec/test_input/tr_software_cal_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_cal_none/conf.py b/dox_trace/spec/test_input/tr_software_cal_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_cal_none/index.rst b/dox_trace/spec/test_input/tr_software_cal_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_cal_none/report.rst b/dox_trace/spec/test_input/tr_software_cal_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_cal_table/Makefile b/dox_trace/spec/test_input/tr_software_cal_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_cal_table/conf.py b/dox_trace/spec/test_input/tr_software_cal_table/conf.py new file mode 100644 index 0000000..0a58d44 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" diff --git a/dox_trace/spec/test_input/tr_software_cal_table/index.rst b/dox_trace/spec/test_input/tr_software_cal_table/index.rst new file mode 100644 index 0000000..760d308 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/index.rst @@ -0,0 +1,29 @@ +Heading +======= + +.. requirement:: SRS_Req_cal1 + :developer: Abc AG + :status: valid + :cal: CAL_1 + :category: software + +.. requirement:: SRS_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + :category: software + +.. srs:: SRS_Req_qm1 + :developer: Abc AG + :status: valid + :cal: QM + +.. srs:: SRS_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_cal_table/properties.yaml b/dox_trace/spec/test_input/tr_software_cal_table/properties.yaml new file mode 100644 index 0000000..59b245a --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/properties.yaml @@ -0,0 +1 @@ +SRS_Second: { cal: "QM" } diff --git a/dox_trace/spec/test_input/tr_software_cal_table/report.rst b/dox_trace/spec/test_input/tr_software_cal_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_cal_table/second.rst b/dox_trace/spec/test_input/tr_software_cal_table/second.rst new file mode 100644 index 0000000..7e50f30 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: SRS_Second_qm2 + :developer: Abc AG + :status: valid + :category: software + diff --git a/dox_trace/spec/test_input/tr_software_cal_table/third.rst b/dox_trace/spec/test_input/tr_software_cal_table/third.rst new file mode 100644 index 0000000..5db9aec --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_cal_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. srs:: SRS_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_software_list_empty/Makefile b/dox_trace/spec/test_input/tr_software_list_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_list_empty/conf.py b/dox_trace/spec/test_input/tr_software_list_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_list_empty/index.rst b/dox_trace/spec/test_input/tr_software_list_empty/index.rst new file mode 100644 index 0000000..20de434 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. srs:: SRS_Req_notset2 + :developer: Other + +.. requirement:: SRS_Req_notset3 + :category: software + :developer: Abc AG + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_list_empty/report.rst b/dox_trace/spec/test_input/tr_software_list_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_list_none/Makefile b/dox_trace/spec/test_input/tr_software_list_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_list_none/conf.py b/dox_trace/spec/test_input/tr_software_list_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_list_none/index.rst b/dox_trace/spec/test_input/tr_software_list_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_list_none/report.rst b/dox_trace/spec/test_input/tr_software_list_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_list_table/Makefile b/dox_trace/spec/test_input/tr_software_list_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_list_table/conf.py b/dox_trace/spec/test_input/tr_software_list_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_list_table/index.rst b/dox_trace/spec/test_input/tr_software_list_table/index.rst new file mode 100644 index 0000000..2f145dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/index.rst @@ -0,0 +1,41 @@ +Heading +======= + +.. requirement:: SRS_Req_deref1 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_refderef1, SRS_Req_refderef2, SRS_Req_ref1 + +.. srs:: SRS_Req_refderef1 + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_refderef2 + +.. requirement:: SRS_Req_refderef2 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_notset2 + +.. srs:: SRS_Req_deref2 + :developer: Abc AG + :status: valid + :review_status: accepted + :tags: covered + +.. srs:: SRS_Req_deref3 + :developer: Abc AG + :status: valid + :review_status: accepted + :sources: index.rst, second.rst + :refs: SRS_Req_notset2 + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_list_table/report.rst b/dox_trace/spec/test_input/tr_software_list_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_list_table/second.rst b/dox_trace/spec/test_input/tr_software_list_table/second.rst new file mode 100644 index 0000000..5322008 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: SRS_Req_ref1 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_software_list_table/third.rst b/dox_trace/spec/test_input/tr_software_list_table/third.rst new file mode 100644 index 0000000..b9db25f --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_list_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: SRS_Req_notset2 + :category: software diff --git a/dox_trace/spec/test_input/tr_software_ref_empty/Makefile b/dox_trace/spec/test_input/tr_software_ref_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_ref_empty/conf.py b/dox_trace/spec/test_input/tr_software_ref_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_ref_empty/index.rst b/dox_trace/spec/test_input/tr_software_ref_empty/index.rst new file mode 100644 index 0000000..20de434 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_empty/index.rst @@ -0,0 +1,19 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. srs:: SRS_Req_notset2 + :developer: Other + +.. requirement:: SRS_Req_notset3 + :category: software + :developer: Abc AG + :status: draft + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_ref_empty/report.rst b/dox_trace/spec/test_input/tr_software_ref_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_ref_none/Makefile b/dox_trace/spec/test_input/tr_software_ref_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_ref_none/conf.py b/dox_trace/spec/test_input/tr_software_ref_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_ref_none/index.rst b/dox_trace/spec/test_input/tr_software_ref_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_ref_none/report.rst b/dox_trace/spec/test_input/tr_software_ref_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_ref_table/Makefile b/dox_trace/spec/test_input/tr_software_ref_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_ref_table/conf.py b/dox_trace/spec/test_input/tr_software_ref_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_ref_table/index.rst b/dox_trace/spec/test_input/tr_software_ref_table/index.rst new file mode 100644 index 0000000..2f145dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/index.rst @@ -0,0 +1,41 @@ +Heading +======= + +.. requirement:: SRS_Req_deref1 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_refderef1, SRS_Req_refderef2, SRS_Req_ref1 + +.. srs:: SRS_Req_refderef1 + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_refderef2 + +.. requirement:: SRS_Req_refderef2 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted + :refs: SRS_Req_notset2 + +.. srs:: SRS_Req_deref2 + :developer: Abc AG + :status: valid + :review_status: accepted + :tags: covered + +.. srs:: SRS_Req_deref3 + :developer: Abc AG + :status: valid + :review_status: accepted + :sources: index.rst, second.rst + :refs: SRS_Req_notset2 + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_ref_table/report.rst b/dox_trace/spec/test_input/tr_software_ref_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_ref_table/second.rst b/dox_trace/spec/test_input/tr_software_ref_table/second.rst new file mode 100644 index 0000000..5322008 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: SRS_Req_ref1 + :category: software + :developer: Abc AG + :status: valid + :review_status: accepted diff --git a/dox_trace/spec/test_input/tr_software_ref_table/third.rst b/dox_trace/spec/test_input/tr_software_ref_table/third.rst new file mode 100644 index 0000000..b9db25f --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_ref_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: SRS_Req_notset2 + :category: software diff --git a/dox_trace/spec/test_input/tr_software_safety_empty/Makefile b/dox_trace/spec/test_input/tr_software_safety_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_safety_empty/conf.py b/dox_trace/spec/test_input/tr_software_safety_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_safety_empty/index.rst b/dox_trace/spec/test_input/tr_software_safety_empty/index.rst new file mode 100644 index 0000000..811fa83 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :developer: Other + :category: software + +.. requirement:: SRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: software + +.. requirement:: SRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_safety_empty/report.rst b/dox_trace/spec/test_input/tr_software_safety_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_safety_none/Makefile b/dox_trace/spec/test_input/tr_software_safety_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_safety_none/conf.py b/dox_trace/spec/test_input/tr_software_safety_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_safety_none/index.rst b/dox_trace/spec/test_input/tr_software_safety_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_safety_none/report.rst b/dox_trace/spec/test_input/tr_software_safety_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_safety_table/Makefile b/dox_trace/spec/test_input/tr_software_safety_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_safety_table/conf.py b/dox_trace/spec/test_input/tr_software_safety_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_safety_table/index.rst b/dox_trace/spec/test_input/tr_software_safety_table/index.rst new file mode 100644 index 0000000..a7e2054 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/index.rst @@ -0,0 +1,29 @@ +Heading +======= + +.. requirement:: SRS_Req_A1 + :developer: Abc AG + :status: valid + :asil: ASIL_A + :category: software + +.. requirement:: SRS_Req_A2 + :developer: Abc AG + :status: valid + :asil: ASIL_A + :category: software + +.. srs:: SRS_Req_B(C)1 + :developer: Abc AG + :status: valid + :asil: ASIL_B(C) + +.. srs:: SRS_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_safety_table/report.rst b/dox_trace/spec/test_input/tr_software_safety_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_safety_table/second.rst b/dox_trace/spec/test_input/tr_software_safety_table/second.rst new file mode 100644 index 0000000..61d73c6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: SRS_Second_QM + :developer: Abc AG + :status: valid + :category: software + :asil: QM diff --git a/dox_trace/spec/test_input/tr_software_safety_table/third.rst b/dox_trace/spec/test_input/tr_software_safety_table/third.rst new file mode 100644 index 0000000..5db9aec --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_safety_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. srs:: SRS_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_software_security_empty/Makefile b/dox_trace/spec/test_input/tr_software_security_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_security_empty/conf.py b/dox_trace/spec/test_input/tr_software_security_empty/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_empty/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_software_security_empty/index.rst b/dox_trace/spec/test_input/tr_software_security_empty/index.rst new file mode 100644 index 0000000..811fa83 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_empty/index.rst @@ -0,0 +1,22 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :developer: Other + :category: software + +.. requirement:: SRS_Req_notset2 + :developer: Abc AG + :status: invalid + :category: software + +.. requirement:: SRS_Req_notset3 + :developer: Abc AG + :status: valid + :review_status: unclear + :category: software + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_security_empty/report.rst b/dox_trace/spec/test_input/tr_software_security_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_security_none/Makefile b/dox_trace/spec/test_input/tr_software_security_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_security_none/conf.py b/dox_trace/spec/test_input/tr_software_security_none/conf.py new file mode 100644 index 0000000..e136531 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_none/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_software_security_none/index.rst b/dox_trace/spec/test_input/tr_software_security_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_security_none/report.rst b/dox_trace/spec/test_input/tr_software_security_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_security_table/Makefile b/dox_trace/spec/test_input/tr_software_security_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_security_table/conf.py b/dox_trace/spec/test_input/tr_software_security_table/conf.py new file mode 100644 index 0000000..dca84fc --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/conf.py @@ -0,0 +1,12 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_properties_file = "properties.yaml" + +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/tr_software_security_table/index.rst b/dox_trace/spec/test_input/tr_software_security_table/index.rst new file mode 100644 index 0000000..56c0d9a --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/index.rst @@ -0,0 +1,29 @@ +Heading +======= + +.. requirement:: SRS_Req_yes1 + :developer: Abc AG + :status: valid + :security: yes + :category: software + +.. requirement:: SRS_Req_yes2 + :developer: Abc AG + :status: valid + :security: yes + :category: software + +.. srs:: SRS_Req_no1 + :developer: Abc AG + :status: valid + :security: no + +.. srs:: SRS_Req_notset1 + :developer: Abc AG + :status: valid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_security_table/properties.yaml b/dox_trace/spec/test_input/tr_software_security_table/properties.yaml new file mode 100644 index 0000000..0cb71dc --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/properties.yaml @@ -0,0 +1 @@ +SRS_Second: { security: "no" } diff --git a/dox_trace/spec/test_input/tr_software_security_table/report.rst b/dox_trace/spec/test_input/tr_software_security_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_security_table/second.rst b/dox_trace/spec/test_input/tr_software_security_table/second.rst new file mode 100644 index 0000000..96e3b2d --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/second.rst @@ -0,0 +1,8 @@ +Second Document +=============== + +.. requirement:: SRS_Second_no2 + :developer: Abc AG + :status: valid + :category: software + diff --git a/dox_trace/spec/test_input/tr_software_security_table/third.rst b/dox_trace/spec/test_input/tr_software_security_table/third.rst new file mode 100644 index 0000000..5db9aec --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_security_table/third.rst @@ -0,0 +1,6 @@ +Third Document +============== + +.. srs:: SRS_Req_ignored + :developer: Abc AG + :status: invalid diff --git a/dox_trace/spec/test_input/tr_software_status_empty/Makefile b/dox_trace/spec/test_input/tr_software_status_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_status_empty/conf.py b/dox_trace/spec/test_input/tr_software_status_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_status_empty/index.rst b/dox_trace/spec/test_input/tr_software_status_empty/index.rst new file mode 100644 index 0000000..ab6b430 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_empty/index.rst @@ -0,0 +1,14 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. srs:: SRS_Req_notset2 + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_status_empty/report.rst b/dox_trace/spec/test_input/tr_software_status_empty/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_empty/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_status_none/Makefile b/dox_trace/spec/test_input/tr_software_status_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_status_none/conf.py b/dox_trace/spec/test_input/tr_software_status_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_status_none/index.rst b/dox_trace/spec/test_input/tr_software_status_none/index.rst new file mode 100644 index 0000000..6a330b6 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_none/index.rst @@ -0,0 +1,10 @@ +Heading +======= + +.. requirement:: CRS_Req_notset1 + :category: input + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_software_status_none/report.rst b/dox_trace/spec/test_input/tr_software_status_none/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_none/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_status_table/Makefile b/dox_trace/spec/test_input/tr_software_status_table/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_software_status_table/conf.py b/dox_trace/spec/test_input/tr_software_status_table/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_software_status_table/index.rst b/dox_trace/spec/test_input/tr_software_status_table/index.rst new file mode 100644 index 0000000..fb2bc7d --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/index.rst @@ -0,0 +1,30 @@ +Heading +======= + +.. requirement:: SRS_Req_valid1 + :category: software + :developer: Abc AG + :status: valid + +.. requirement:: SRS_Req_valid2 + :category: software + :developer: Abc AG + :status: valid + +.. srs:: SRS_Req_draft1 + :developer: Abc AG + +.. requirement:: SRS_Req_draft2 + :category: software + :developer: Abc AG + :status: draft + +.. srs:: SRS_Req_invalid1 + :developer: Abc AG + :status: invalid + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_software_status_table/report.rst b/dox_trace/spec/test_input/tr_software_status_table/report.rst new file mode 100644 index 0000000..32908c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/report.rst @@ -0,0 +1,8 @@ +Traceability Report +=================== + +Software Requirements +--------------------- + +.. traceability_report:: software + :developer: Abc AG diff --git a/dox_trace/spec/test_input/tr_software_status_table/second.rst b/dox_trace/spec/test_input/tr_software_status_table/second.rst new file mode 100644 index 0000000..21d1f2d --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/second.rst @@ -0,0 +1,7 @@ +Second Document +=============== + +.. requirement:: SRS_Req_valid3 + :category: software + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_software_status_table/third.rst b/dox_trace/spec/test_input/tr_software_status_table/third.rst new file mode 100644 index 0000000..b9db25f --- /dev/null +++ b/dox_trace/spec/test_input/tr_software_status_table/third.rst @@ -0,0 +1,5 @@ +Third Document +============== + +.. requirement:: SRS_Req_notset2 + :category: software diff --git a/dox_trace/spec/test_input/tr_source_list/Makefile b/dox_trace/spec/test_input/tr_source_list/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_source_list/conf.py b/dox_trace/spec/test_input/tr_source_list/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/tr_source_list/index.rst b/dox_trace/spec/test_input/tr_source_list/index.rst new file mode 100644 index 0000000..9b1d5f4 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/index.rst @@ -0,0 +1,38 @@ +Heading +======= + +.. spec:: SMD_Req_deref1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef1, SMD_Req_refderef2, SMD_Second_ref1 + +.. interface:: SMD_Req_refderef1 + :developer: Abc AG + :status: valid + :refs: SMD_Req_refderef2 + +.. spec:: SMD_Req_refderef2 + :developer: Abc AG + :status: valid + :refs: SMD_Req_notset2 + +.. unit:: SMD_Req_no1 + :developer: Abc AG + :status: valid + +.. spec:: SMD_Req_deref2 + :developer: Abc AG + :status: valid + :sources: index.rst, second.rst + :refs: SMD_Req_notset2 + +.. spec:: SMD_Req_deref3 + :developer: Abc AG + :status: valid + :sources: index.rst + +.. toctree:: + + second + third + report diff --git a/dox_trace/spec/test_input/tr_source_list/report.rst b/dox_trace/spec/test_input/tr_source_list/report.rst new file mode 100644 index 0000000..2d83907 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/report.rst @@ -0,0 +1,7 @@ +Traceability Report +=================== + +Sources +------- + +.. traceability_report:: source diff --git a/dox_trace/spec/test_input/tr_source_list/second.rst b/dox_trace/spec/test_input/tr_source_list/second.rst new file mode 100644 index 0000000..79e305a --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/second.rst @@ -0,0 +1,6 @@ +Second Document +=============== + +.. spec:: SMD_Second_ref1 + :developer: Abc AG + :status: valid diff --git a/dox_trace/spec/test_input/tr_source_list/third.rst b/dox_trace/spec/test_input/tr_source_list/third.rst new file mode 100644 index 0000000..27d47c5 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_list/third.rst @@ -0,0 +1,14 @@ +Third Document +============== + +.. spec:: SMD_Req_notset2 + :developer: Other + +.. spec:: SMD_Req_notset3 + :developer: Other + :refs: SMD_Req_refderef1 + +.. information:: SRS_Req_info1 + :refs: SMD_Req_refderef1 + +:ref:`SMD_Req_refderef1` diff --git a/dox_trace/spec/test_input/tr_source_none/Makefile b/dox_trace/spec/test_input/tr_source_none/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_none/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/tr_source_none/conf.py b/dox_trace/spec/test_input/tr_source_none/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_none/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/tr_source_none/index.rst b/dox_trace/spec/test_input/tr_source_none/index.rst new file mode 100644 index 0000000..bd721a3 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_none/index.rst @@ -0,0 +1,11 @@ +Heading +======= + +.. requirement:: SRS_Req_notset1 + :category: software + :developer: Other + +.. toctree:: + :caption: Pages + + report diff --git a/dox_trace/spec/test_input/tr_source_none/report.rst b/dox_trace/spec/test_input/tr_source_none/report.rst new file mode 100644 index 0000000..2d83907 --- /dev/null +++ b/dox_trace/spec/test_input/tr_source_none/report.rst @@ -0,0 +1,7 @@ +Traceability Report +=================== + +Sources +------- + +.. traceability_report:: source diff --git a/dox_trace/spec/test_input/undefined_refs_empty/Makefile b/dox_trace/spec/test_input/undefined_refs_empty/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_empty/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/undefined_refs_empty/conf.py b/dox_trace/spec/test_input/undefined_refs_empty/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_empty/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/undefined_refs_empty/index.rst b/dox_trace/spec/test_input/undefined_refs_empty/index.rst new file mode 100644 index 0000000..2f73856 --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_empty/index.rst @@ -0,0 +1,14 @@ +Refs +==== + +.. spec:: SWA_Spec_1 + :refs: SWA_Spec_2, SWA_Spec_3 + +.. spec:: SWA_Spec_2 + :refs: SWA_Spec_3 + +.. spec:: SWA_Spec_3 + +.. toctree:: + + undefined_refs diff --git a/dox_trace/spec/test_input/undefined_refs_empty/undefined_refs.rst b/dox_trace/spec/test_input/undefined_refs_empty/undefined_refs.rst new file mode 100644 index 0000000..6cf633a --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_empty/undefined_refs.rst @@ -0,0 +1,4 @@ +Undefined Refs +============== + +.. undefined_refs:: diff --git a/dox_trace/spec/test_input/undefined_refs_list/Makefile b/dox_trace/spec/test_input/undefined_refs_list/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_list/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/undefined_refs_list/conf.py b/dox_trace/spec/test_input/undefined_refs_list/conf.py new file mode 100644 index 0000000..9095269 --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_list/conf.py @@ -0,0 +1,11 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" + +dox_trace_allow_undefined_refs = True diff --git a/dox_trace/spec/test_input/undefined_refs_list/index.rst b/dox_trace/spec/test_input/undefined_refs_list/index.rst new file mode 100644 index 0000000..6b8090c --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_list/index.rst @@ -0,0 +1,15 @@ +Refs +==== + +.. spec:: SWA_Spec_1 + :refs: SWA_Spec_100, BLAH, SWA_Spec_2, FASEL, SWA_Spec_3 + +.. spec:: SWA_Spec_2 + :refs: SWA_Spec_3, BLAH + +.. spec:: SWA_Spec_3 + :refs: FASEL + +.. toctree:: + + undefined_refs diff --git a/dox_trace/spec/test_input/undefined_refs_list/undefined_refs.rst b/dox_trace/spec/test_input/undefined_refs_list/undefined_refs.rst new file mode 100644 index 0000000..b0e2d4f --- /dev/null +++ b/dox_trace/spec/test_input/undefined_refs_list/undefined_refs.rst @@ -0,0 +1,4 @@ +Undefined_Refs +============== + +.. undefined_refs:: diff --git a/dox_trace/spec/test_input/upstream_asil/Makefile b/dox_trace/spec/test_input/upstream_asil/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_asil/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/upstream_asil/conf.py b/dox_trace/spec/test_input/upstream_asil/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_asil/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/upstream_asil/index.rst b/dox_trace/spec/test_input/upstream_asil/index.rst new file mode 100644 index 0000000..9379e70 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_asil/index.rst @@ -0,0 +1,88 @@ +Parent Asil +=========== + +Shown +----- + +.. requirement:: SRS_Requirement_A + :category: software + :refs: SMD_Spec_ignoreBackRefs, SWA_Spec_unique + :asil: ASIL_A + +.. information:: SRS_Information_B + :category: software + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_B + +.. srs:: SRS_Srs_A + :refs: SMD_Spec_ignoreBackRefs, SWA_Spec_unique + :asil: ASIL_A + +.. spec:: SWA_Spec_C + :refs: SWA_Spec_unique + :asil: ASIL_C + +.. unit:: SMD_Unit_D + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_D + +.. interface:: SWA_Interface_AA + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_A(A) + +.. mod:: SWA_Mod_A + :asil: ASIL_A + +Not Shown +--------- + +.. requirement:: InputRequirement_AB + :category: input + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_A(B) + +.. information:: InputInformation_AC + :category: input + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_A(C) + +Parent and Grandparents +----------------------- + +.. spec:: SWA_Spec_AD + :refs: SWA_Spec_BC + :asil: ASIL_A(D) + +.. spec:: SWA_Spec_BB + :refs: SWA_Spec_BD + :asil: ASIL_B(B) + +.. spec:: SWA_Spec_BC + :refs: SWA_Spec_child + :asil: ASIL_B(C) + +.. spec:: SWA_Spec_BD + :refs: SWA_Spec_child + :asil: ASIL_B(D) + +.. spec:: SWA_Spec_child + +Dismiss +------- + +.. spec:: SWA_Spec_strike + :refs: SMD_Spec_ignoreBackRefs + :asil: ASIL_C(D) + :status: invalid + +.. unit:: SMD_Spec_ignoreBackRefs + :refs: SWA_Spec_C + +Unique +------ + +.. spec:: SWA_Spec_A2 + :refs: SWA_Spec_unique + :asil: ASIL_A + +.. spec:: SWA_Spec_unique diff --git a/dox_trace/spec/test_input/upstream_cal/Makefile b/dox_trace/spec/test_input/upstream_cal/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_cal/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/upstream_cal/conf.py b/dox_trace/spec/test_input/upstream_cal/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_cal/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/upstream_cal/index.rst b/dox_trace/spec/test_input/upstream_cal/index.rst new file mode 100644 index 0000000..47f6e33 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_cal/index.rst @@ -0,0 +1,110 @@ +Parent Security +=============== + +Shown +----- + +.. requirement:: SRS_Requirement_Cal1 + :category: software + :refs: SMD_Spec_ignoreBackRefs1, SWA_Spec_unique + :cal: CAL_1 + +.. information:: SRS_Information_Qm + :category: software + :refs: SMD_Spec_ignoreBackRefs1 + :cal: QM + +.. srs:: SRS_Srs_Cal2 + :refs: SWA_Spec_unique + :cal: CAL_2 + +.. spec:: SWA_Spec_notSet + :refs: SMD_Spec_ignoreBackRefs1, SWA_Spec_unique + :cal: not_set + +.. unit:: SMD_Unit_Cal3 + :refs: SMD_Spec_ignoreBackRefs2 + :cal: CAL_3 + +.. interface:: SWA_Interface_Qm + :refs: SMD_Spec_ignoreBackRefs2 + :cal: QM + +.. mod:: SWA_Mod_Cal2 + :cal: CAL_2 + +Not Shown +--------- + +.. requirement:: InputRequirement_notSet + :category: input + :refs: SMD_Spec_ignoreBackRefs2 + :cal: not_set + +.. information:: InputInformation_Cal1 + :category: input + :refs: SMD_Spec_ignoreBackRefs3 + :cal: CAL_1 + +Parent and Grandparents +----------------------- + +.. spec:: SWA_Spec_Cal1P1 + :refs: SWA_Spec_QmP + :cal: CAL_1 + +.. spec:: SWA_Spec_Cal1P2 + :refs: SWA_Spec_notSetP + :cal: CAL_1 + +.. spec:: SWA_Spec_QmP + :refs: SWA_Spec_child + :cal: QM + +.. spec:: SWA_Spec_notSetP + :refs: SWA_Spec_child + :cal: not_set + +.. spec:: SWA_Spec_child + +Dismiss +------- + +.. spec:: SWA_Spec_strike + :refs: SMD_Spec_ignoreBackRefs3 + :security: no + :status: invalid + +.. unit:: SMD_Spec_ignoreBackRefs1 + :refs: SRS_Srs_Cal2 + +.. unit:: SMD_Spec_ignoreBackRefs2 + +.. unit:: SMD_Spec_ignoreBackRefs3 + +Unique +------ + +.. spec:: SWA_Spec_yesU + :refs: SWA_Spec_unique + :cal: CAL_1 + +.. spec:: SWA_Spec_unique + +Security +-------- + +.. spec:: SWA_Spec_SecYes + :refs: SWA_Spec_Cal + :security: yes + +.. spec:: SWA_Spec_SecNo + :refs: SWA_Spec_Cal + :security: no + +.. spec:: SWA_Spec_SecNotSet + :refs: SWA_Spec_Cal + :cal: QM + :security: not_set + +.. spec:: SWA_Spec_Cal diff --git a/dox_trace/spec/test_input/upstream_references/Makefile b/dox_trace/spec/test_input/upstream_references/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_references/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/upstream_references/conf.py b/dox_trace/spec/test_input/upstream_references/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/upstream_references/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/upstream_references/index.rst b/dox_trace/spec/test_input/upstream_references/index.rst new file mode 100644 index 0000000..116e946 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_references/index.rst @@ -0,0 +1,125 @@ +Backward References +=================== + +1 to N +------ + +.. requirement:: InputRequirement_Parent + :category: input + :refs: SRS_Requirement_BackwardRefsShown, + SRS_Information_BackwardRefsShown, + InputRequirement_BackwardRefsShown, + InputInformation_BackwardRefsShown, + SRS_Srs_BackwardRefsShown, + SWA_Spec_BackwardRefsShown, + SMD_Unit_BackwardRefsShown, + SWA_Interface_BackwardRefsShown + +.. requirement:: SRS_Requirement_BackwardRefsShown + :category: software + +.. information:: SRS_Information_BackwardRefsShown + :category: software + +.. requirement:: InputRequirement_BackwardRefsShown + :category: input + +.. information:: InputInformation_BackwardRefsShown + :category: input + +.. srs:: SRS_Srs_BackwardRefsShown + +.. spec:: SWA_Spec_BackwardRefsShown + +.. unit:: SMD_Unit_BackwardRefsShown + +.. interface:: SWA_Interface_BackwardRefsShown + +N to 1 +------ + +.. requirement:: SRS_Requirement_Ref + :category: software + :refs: SMD_Unit_All + +.. information:: SRS_Information_Ref + :category: software + :refs: SMD_Unit_All + +.. requirement:: InputRequirement_Ref + :category: input + :refs: SMD_Unit_All + +.. information:: InputInformation_Ref + :category: input + :refs: SMD_Unit_All + +.. srs:: SRS_Srs_Ref + +.. spec:: SWA_Spec_Ref + +.. unit:: SMD_Unit_Ref + :refs: SMD_Unit_All + +.. interface:: SWA_Interface_Ref + :refs: SMD_Unit_All + +.. unit:: SMD_Unit_All + :refs: SRS_Srs_Ref, SWA_Spec_Ref + +Default +------- + +.. requirement:: SRS_Requirement_RefsDefault + :category: software + +.. information:: SRS_Information_RefsDefault + :category: software + +.. requirement:: InputRequirement_RefsDefault + :category: input + +.. information:: InputInformation_RefsDefault + :category: input + +.. srs:: SRS_Srs_RefsDefault + +.. mod:: SWA_Mod_RefsDefault + +.. spec:: SWA_Spec_RefsDefault + +.. unit:: SMD_Unit_RefsDefault + +.. interface:: SWA_Interface_RefsDefault + +.. interface:: SMD_Interface_RefsDefault + + +Unique +------ + +.. interface:: SWA_Interface_UniqueParent + :refs: SWA_Spec_Unique, SWA_Spec_Unique + +.. spec:: SWA_Spec_UniqueParent + :refs: SWA_Spec_Unique, SWA_Spec_Unique + +.. spec:: SWA_Spec_Unique + +Round Trip +---------- + +.. spec:: SWA_Spec_RoundTrip + :refs: SMD_Spec_RoundTrip + +.. spec:: SMD_Spec_RoundTrip + :refs: SWA_Spec_RoundTrip + +Special +------- + +.. srs:: SRS_Srs_Tool + :tags: tool + +.. srs:: SRS_srs_Invalid + :status: invalid diff --git a/dox_trace/spec/test_input/upstream_security/Makefile b/dox_trace/spec/test_input/upstream_security/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_security/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/upstream_security/conf.py b/dox_trace/spec/test_input/upstream_security/conf.py new file mode 100644 index 0000000..0ac6918 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_security/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_security_backward = True diff --git a/dox_trace/spec/test_input/upstream_security/index.rst b/dox_trace/spec/test_input/upstream_security/index.rst new file mode 100644 index 0000000..bfe25d4 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_security/index.rst @@ -0,0 +1,109 @@ +Parent Security +=============== + +Shown +----- + +.. requirement:: SRS_Requirement_yes + :category: software + :refs: SMD_Spec_ignoreBackRefs1, SWA_Spec_unique + :security: yes + +.. information:: SRS_Information_no + :category: software + :refs: SMD_Spec_ignoreBackRefs1 + :security: no + +.. srs:: SRS_Srs_yes + :refs: SMD_Spec_ignoreBackRefs1, SWA_Spec_unique + :security: yes + +.. spec:: SWA_Spec_notSet + :refs: SMD_Spec_ignoreBackRefs1, SWA_Spec_unique + :security: not_set + +.. unit:: SMD_Unit_yes + :refs: SMD_Spec_ignoreBackRefs2 + :security: yes + +.. interface:: SWA_Interface_no + :refs: SMD_Spec_ignoreBackRefs2 + :security: no + +.. mod:: SWA_Mod_yes + :security: yes + +Not Shown +--------- + +.. requirement:: InputRequirement_notSet + :category: input + :refs: SMD_Spec_ignoreBackRefs2 + :security: not_set + +.. information:: InputInformation_yes + :category: input + :refs: SMD_Spec_ignoreBackRefs3 + :security: yes + +Parent and Grandparents +----------------------- + +.. spec:: SWA_Spec_yesP1 + :refs: SWA_Spec_noP + :security: yes + +.. spec:: SWA_Spec_yesP2 + :refs: SWA_Spec_notSetP + :security: yes + +.. spec:: SWA_Spec_noP + :refs: SWA_Spec_child + :security: no + +.. spec:: SWA_Spec_notSetP + :refs: SWA_Spec_child + :security: not_set + +.. spec:: SWA_Spec_child + +Dismiss +------- + +.. spec:: SWA_Spec_strike + :refs: SMD_Spec_ignoreBackRefs3 + :security: no + :status: invalid + +.. unit:: SMD_Spec_ignoreBackRefs1 + +.. unit:: SMD_Spec_ignoreBackRefs2 + +.. unit:: SMD_Spec_ignoreBackRefs3 + +Unique +------ + +.. spec:: SWA_Spec_yesU + :refs: SWA_Spec_unique + :security: yes + +.. spec:: SWA_Spec_unique + +Cal +--- + +.. spec:: SWA_Spec_Cal1 + :refs: SWA_Spec_Cal + :cal: CAL_1 + +.. spec:: SWA_Spec_Qm + :refs: SWA_Spec_Cal + :cal: QM + +.. spec:: SWA_Spec_no + :refs: SWA_Spec_Cal + :security: no + :cal: not_set + +.. spec:: SWA_Spec_Cal diff --git a/dox_trace/spec/test_input/upstream_tags/Makefile b/dox_trace/spec/test_input/upstream_tags/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_tags/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/upstream_tags/conf.py b/dox_trace/spec/test_input/upstream_tags/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_tags/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/upstream_tags/index.rst b/dox_trace/spec/test_input/upstream_tags/index.rst new file mode 100644 index 0000000..5955e81 --- /dev/null +++ b/dox_trace/spec/test_input/upstream_tags/index.rst @@ -0,0 +1,77 @@ +Parent Tags +=========== + +Shown +----- + +.. requirement:: SRS_Requirement_sys + :category: software + :refs: SMD_Spec_ignoreBackRefs + :tags: sys + +.. information:: SRS_Information_srs + :category: software + :refs: SMD_Spec_ignoreBackRefs + :tags: srs + +.. srs:: SRS_Srs_sys + :refs: SMD_Spec_ignoreBackRefs + :tags: sys + +.. spec:: SWA_Spec_swa + :refs: SMD_Spec_ignoreBackRefs + :tags: swa + +.. unit:: SMD_Unit_smd + :refs: SMD_Spec_ignoreBackRefs + :tags: smd + +.. interface:: SWA_Interface_process + :tags: process + +Not Shown +--------- + +.. requirement:: InputRequirement_tested + :category: input + :refs: SMD_Spec_ignoreBackRefs + :tags: covered + +.. information:: InputInformation_covered + :category: input + :refs: SMD_Spec_ignoreBackRefs + :tags: tested + +.. mod:: SWA_Mod_none + +Parent and Grandparents +----------------------- + +.. spec:: SWA_Spec_smd + :tags: smd, obd + :refs: SWA_Spec_swa2 + +.. spec:: SWA_Spec_swa1 + :tags: obd, swa + :refs: SWA_Spec_tool + +.. spec:: SWA_Spec_swa2 + :tags: memory, swa + :refs: SWA_Spec_child + +.. spec:: SWA_Spec_tool + :tags: tool + :refs: SWA_Spec_child + +.. spec:: SWA_Spec_child + +Dismiss +------- + +.. spec:: SWA_Spec_strike + :refs: SMD_Spec_ignoreBackRefs + :tags: performance + :status: invalid + +.. unit:: SMD_Spec_ignoreBackRefs + :refs: SWA_Interface_process diff --git a/dox_trace/spec/test_input/usage/Makefile b/dox_trace/spec/test_input/usage/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage/conf.py b/dox_trace/spec/test_input/usage/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage/index.rst b/dox_trace/spec/test_input/usage/index.rst new file mode 100644 index 0000000..01449a2 --- /dev/null +++ b/dox_trace/spec/test_input/usage/index.rst @@ -0,0 +1,8 @@ +Usage +===== + +.. mod:: SWA_Mod_UsageEmpty + :usage: + +.. mod:: SWA_Mod_UsageDev + :usage: Dev diff --git a/dox_trace/spec/test_input/usage_information/Makefile b/dox_trace/spec/test_input/usage_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_information/conf.py b/dox_trace/spec/test_input/usage_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_information/index.rst b/dox_trace/spec/test_input/usage_information/index.rst new file mode 100644 index 0000000..a2a3ddc --- /dev/null +++ b/dox_trace/spec/test_input/usage_information/index.rst @@ -0,0 +1,9 @@ +Usage Information +================= + +Not Available +------------- + +.. information:: SRS_Information_Usage + :usage: not_available + :category: software diff --git a/dox_trace/spec/test_input/usage_interface/Makefile b/dox_trace/spec/test_input/usage_interface/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_interface/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_interface/conf.py b/dox_trace/spec/test_input/usage_interface/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_interface/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_interface/index.rst b/dox_trace/spec/test_input/usage_interface/index.rst new file mode 100644 index 0000000..476f636 --- /dev/null +++ b/dox_trace/spec/test_input/usage_interface/index.rst @@ -0,0 +1,8 @@ +Usage Interface +=============== + +Not Available +------------- + +.. interface:: SWA_Interface_Usage + :usage: not_available diff --git a/dox_trace/spec/test_input/usage_requirement/Makefile b/dox_trace/spec/test_input/usage_requirement/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_requirement/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_requirement/conf.py b/dox_trace/spec/test_input/usage_requirement/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_requirement/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_requirement/index.rst b/dox_trace/spec/test_input/usage_requirement/index.rst new file mode 100644 index 0000000..51641cb --- /dev/null +++ b/dox_trace/spec/test_input/usage_requirement/index.rst @@ -0,0 +1,9 @@ +Usage Requirement +================= + +Not Available +------------- + +.. requirement:: SRS_Requirement_Usage + :usage: not_available + :category: software diff --git a/dox_trace/spec/test_input/usage_spec/Makefile b/dox_trace/spec/test_input/usage_spec/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_spec/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_spec/conf.py b/dox_trace/spec/test_input/usage_spec/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_spec/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_spec/index.rst b/dox_trace/spec/test_input/usage_spec/index.rst new file mode 100644 index 0000000..b5747bb --- /dev/null +++ b/dox_trace/spec/test_input/usage_spec/index.rst @@ -0,0 +1,8 @@ +Usage Spec +========== + +Not Available +------------- + +.. spec:: SWA_Spec_Usage + :usage: not_available diff --git a/dox_trace/spec/test_input/usage_srs/Makefile b/dox_trace/spec/test_input/usage_srs/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_srs/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_srs/conf.py b/dox_trace/spec/test_input/usage_srs/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_srs/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_srs/index.rst b/dox_trace/spec/test_input/usage_srs/index.rst new file mode 100644 index 0000000..c98668e --- /dev/null +++ b/dox_trace/spec/test_input/usage_srs/index.rst @@ -0,0 +1,8 @@ +Usage Srs +========= + +Not Available +------------- + +.. srs:: SRS_Srs_Usage + :usage: not_available diff --git a/dox_trace/spec/test_input/usage_unit/Makefile b/dox_trace/spec/test_input/usage_unit/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/usage_unit/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/usage_unit/conf.py b/dox_trace/spec/test_input/usage_unit/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/usage_unit/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/usage_unit/index.rst b/dox_trace/spec/test_input/usage_unit/index.rst new file mode 100644 index 0000000..1933d7f --- /dev/null +++ b/dox_trace/spec/test_input/usage_unit/index.rst @@ -0,0 +1,8 @@ +Usage Unit +========== + +Not Available +------------- + +.. unit:: SMD_Unit_Usage + :usage: not_available diff --git a/dox_trace/spec/test_input/verification_criteria/Makefile b/dox_trace/spec/test_input/verification_criteria/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_criteria/conf.py b/dox_trace/spec/test_input/verification_criteria/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/verification_criteria/index.rst b/dox_trace/spec/test_input/verification_criteria/index.rst new file mode 100644 index 0000000..b61b5ea --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria/index.rst @@ -0,0 +1,76 @@ +Verification Criteria +===================== + +.. _available: + +Available +--------- + +.. requirement:: SRS_Requirement_VcSet + :verification_criteria: Aa: :ref:`available`! + :category: software + +.. requirement:: InputRequirement_VcSet + :verification_criteria: Bb + :category: input + +.. srs:: SRS_Srs_VcSet + :verification_criteria: Aa: :ref:`available`! + +.. spec:: SWA_Spec_VcSet + :verification_criteria: Cc + +.. unit:: SMD_Unit_VcSet + :verification_criteria: :raw-html:`Hello
    world!` + +.. interface:: SWA_Interface_VcSet + :verification_criteria: Dd + +.. interface:: SMD_Interface_VcSet + :verification_criteria: Ee + +Empty +----- + +.. srs:: SRS_Srs_VcEmpty + :verification_criteria: + +.. requirement:: SRS_Requirement_VcEmptyRaw + :verification_criteria: :raw-html:`` + :category: software + +Default +------- + +.. requirement:: SRS_Requirement_VcDefault + :category: software + +.. requirement:: InputRequirement_VcDefault + :category: input + +.. srs:: SRS_Srs_VcDefault + +.. spec:: SWA_Spec_VcDefault + +.. unit:: SMD_Unit_VcDefault + +.. interface:: SWA_Interface_VcDefault + +.. interface:: SMD_Interface_VcDefault + +Additional +---------- + +.. requirement:: SRS_Requirement_VcDefaultTool + :category: software + :tags: tool + +.. requirement:: SRS_Requirement_VcDefaultStruck + :category: software + :status: invalid + +.. srs:: SRS_Srs_VcDefaultTool + :tags: tool + +.. srs:: SRS_Srs_VcDefaultStruck + :status: invalid diff --git a/dox_trace/spec/test_input/verification_criteria_information/Makefile b/dox_trace/spec/test_input/verification_criteria_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_criteria_information/conf.py b/dox_trace/spec/test_input/verification_criteria_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/verification_criteria_information/index.rst b/dox_trace/spec/test_input/verification_criteria_information/index.rst new file mode 100644 index 0000000..ea69b40 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_information/index.rst @@ -0,0 +1,9 @@ +Verification Criteria Information +================================= + +Not Available +------------- + +.. information:: SRS_Information_VerificationCriteria + :verification_criteria: not_available + :category: software diff --git a/dox_trace/spec/test_input/verification_criteria_mod/Makefile b/dox_trace/spec/test_input/verification_criteria_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_criteria_mod/conf.py b/dox_trace/spec/test_input/verification_criteria_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/verification_criteria_mod/index.rst b/dox_trace/spec/test_input/verification_criteria_mod/index.rst new file mode 100644 index 0000000..cda7454 --- /dev/null +++ b/dox_trace/spec/test_input/verification_criteria_mod/index.rst @@ -0,0 +1,8 @@ +Verification Criteria Mod +========================= + +Not Available +------------- + +.. mod:: SWA_Mod_VerificationCriteria + :verification_criteria: not_available diff --git a/dox_trace/spec/test_input/verification_methods/Makefile b/dox_trace/spec/test_input/verification_methods/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_methods/conf.py b/dox_trace/spec/test_input/verification_methods/conf.py new file mode 100644 index 0000000..072acfa --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods/conf.py @@ -0,0 +1,10 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" +dox_trace_allow_deprecated = True diff --git a/dox_trace/spec/test_input/verification_methods/index.rst b/dox_trace/spec/test_input/verification_methods/index.rst new file mode 100644 index 0000000..d185b5c --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods/index.rst @@ -0,0 +1,61 @@ +Verification Methods +==================== + +Available +--------- + +.. requirement:: SRS_Requirement_VerificationMethodsSet + :verification_methods: on_target, off_target + :category: software + +.. requirement:: InputRequirement_VerificationMethodsSet + :verification_methods: manual + :category: input + +.. srs:: SRS_Srs_VerificationMethodsSet + :verification_methods: on_target, off_target + +.. spec:: SWA_Spec_VerificationMethodsSet + :verification_methods: off_target, on_target + +.. unit:: SMD_Unit_VerificationMethodsSet + :verification_methods: none + +.. interface:: SWA_Interface_VerificationMethodsSet + :verification_methods: off_target + +.. interface:: SMD_Interface_VerificationMethodsSet + :verification_methods: off_target + +Default +------- + +.. requirement:: SRS_Requirement_VerificationMethodsDefault + :category: software + +.. requirement:: InputRequirement_VerificationMethodsDefault + :category: input + +.. srs:: SRS_Srs_VerificationMethodsDefault + +.. spec:: SWA_Spec_VerificationMethodsDefault + +.. spec:: SMD_Spec_VerificationMethodsDefault + +.. unit:: SMD_Unit_VerificationMethodsDefault + +.. mod:: SWA_Mod_VerificationMethodsDefault + +.. interface:: SWA_Interface_VerificationMethodsDefault + +.. interface:: SMD_Interface_VerificationMethodsDefault + +Backward +-------- + +.. spec:: SWA_Spec_VerificationMethodsBackward + :test_setups: off_target, on_target + +.. spec:: SWA_Spec_VerificationMethodsBackwardBoth + :test_setups: off_target, on_target + :verification_methods: manual diff --git a/dox_trace/spec/test_input/verification_methods_information/Makefile b/dox_trace/spec/test_input/verification_methods_information/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_information/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_methods_information/conf.py b/dox_trace/spec/test_input/verification_methods_information/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_information/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/verification_methods_information/index.rst b/dox_trace/spec/test_input/verification_methods_information/index.rst new file mode 100644 index 0000000..c6ad72f --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_information/index.rst @@ -0,0 +1,9 @@ +Verification Methods Information +================================ + +Not Available +------------- + +.. information:: SRS_Information_VerificationMethods + :verification_methods: not_available + :category: software diff --git a/dox_trace/spec/test_input/verification_methods_mod/Makefile b/dox_trace/spec/test_input/verification_methods_mod/Makefile new file mode 100644 index 0000000..249b780 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_mod/Makefile @@ -0,0 +1,10 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = build +CONFIGDIR = . + +.PHONY: Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -c "$(CONFIGDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_trace/spec/test_input/verification_methods_mod/conf.py b/dox_trace/spec/test_input/verification_methods_mod/conf.py new file mode 100644 index 0000000..a743438 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_mod/conf.py @@ -0,0 +1,9 @@ +import sys +from pathlib import Path + +EXTENSION_ROOT = Path("../../../../") +sys.path.extend([str(path.resolve()) for path in EXTENSION_ROOT.glob("*")]) + +extensions = ["dox_style", "dox_trace", "sphinxcontrib.jquery"] + +dox_trace_dim_root = "export_root" diff --git a/dox_trace/spec/test_input/verification_methods_mod/index.rst b/dox_trace/spec/test_input/verification_methods_mod/index.rst new file mode 100644 index 0000000..8b1d680 --- /dev/null +++ b/dox_trace/spec/test_input/verification_methods_mod/index.rst @@ -0,0 +1,8 @@ +Verification Methods Mod +======================== + +Not Available +------------- + +.. mod:: SWA_Mod_VerificationMethods + :verification_methods: not_available diff --git a/dox_trace/spec/test_setups_spec.rb b/dox_trace/spec/test_setups_spec.rb new file mode 100644 index 0000000..6f47186 --- /dev/null +++ b/dox_trace/spec/test_setups_spec.rb @@ -0,0 +1,97 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute test_setups" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("test_setups") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_TestSetups', 'DoxTrace_HTML_TestSetups'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("test_setups", "index.html") + + expect(data.value("SRS_Requirement_TestSetupsSet", "test_setups")).to eq 'on_target, off_target' + expect(data.value("InputRequirement_TestSetupsSet", "test_setups")).to eq 'manual' + expect(data.value("SRS_Srs_TestSetupsSet", "test_setups")).to eq 'on_target, off_target' + expect(data.value("SWA_Spec_TestSetupsSet", "test_setups")).to eq 'off_target, on_target' + expect(data.value("SMD_Unit_TestSetupsSet", "test_setups")).to eq 'none' + expect(data.value("SWA_Interface_TestSetupsSet", "test_setups")).to eq 'off_target' + expect(data.exist?("SMD_Interface_TestSetupsSet", "test_setups")).to be false + + expect(data.value("SRS_Requirement_TestSetupsDefault", "test_setups")).to eq '-' + expect(data.value("InputRequirement_TestSetupsDefault", "test_setups")).to eq '-' + expect(data.value("SRS_Srs_TestSetupsDefault", "test_setups")).to eq 'on_target' + expect(data.value("SWA_Spec_TestSetupsDefault", "test_setups")).to eq 'on_target' + expect(data.value("SMD_Spec_TestSetupsDefault", "test_setups")).to eq 'off_target' + expect(data.value("SMD_Unit_TestSetupsDefault", "test_setups")).to eq 'off_target' + expect(data.value("SWA_Interface_TestSetupsDefault", "test_setups")).to eq 'on_target' + + expect(data.exist?("SMD_Interface_TestSetupsDefault", "test_setups")).to be false + expect(data.exist?("SWA_Mod_TestSetupsDefault", "test_setups")).to be false + end + + it 'shall get the value from verification_methods if test_setups is not defined', doc_refs: ['DoxTrace_Syntax_VerificationMethodsToTestSetups', 'DoxTrace_HTML_TestSetups', 'DoxTrace_HTML_VerificationMethods'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("test_setups", "index.html") + + expect(data.value("SWA_Spec_TestSetupsBackward", "test_setups")).to eq 'off_target, on_target' + expect(data.exist?("SWA_Spec_TestSetupsBackward", "verification_methods")).to be false + expect(data.value("SWA_Spec_TestSetupsBackwardBoth", "test_setups")).to eq 'manual' + expect(data.exist?("SWA_Spec_TestSetupsBackwardBoth", "verification_methods")).to be false + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_TestSetups', 'DoxTrace_Export_Attributes', 'DoxTrace_Export_VerificationMethods', 'DoxTrace_Export_TestSetups'] do + srs = @test.dim_original_data["spec/test_input/test_setups/export_root/srs/index.dim"] + expect(srs["SRS_Srs_TestSetupsSet"]["test_setups"]).to eq 'on_target, off_target' + expect(srs["SRS_Srs_TestSetupsDefault"]["test_setups"]).to eq 'on_target' + + swa = @test.dim_original_data["spec/test_input/test_setups/export_root/swa/index.dim"] + expect(swa["SWA_Spec_TestSetupsSet"]["test_setups"]).to eq 'off_target, on_target' + expect(swa["SWA_Interface_TestSetupsSet"]["test_setups"]).to eq 'off_target' + expect(swa["SWA_Spec_TestSetupsDefault"]["test_setups"]).to eq 'on_target' + expect(swa["SWA_Interface_TestSetupsDefault"]["test_setups"]).to eq 'on_target' + + expect(swa["SWA_Spec_TestSetupsBackward"]["test_setups"]).to eq 'off_target, on_target' + expect(swa["SWA_Spec_TestSetupsBackwardBoth"]["test_setups"]).to eq 'manual' + content = File.read("spec/test_input/test_setups/export_root/swa/index.dim") + expect(content).not_to include "verification_methods" + + smd = @test.dim_original_data["spec/test_input/test_setups/export_root/smd/index.dim"] + expect(smd["SMD_Interface_TestSetupsSet"]["test_setups"]).to eq 'none' + expect(smd["SMD_Unit_TestSetupsSet"]["test_setups"]).to eq 'none' + expect(smd["SMD_Spec_TestSetupsDefault"]["test_setups"]).to eq 'off_target' + expect(smd["SMD_Unit_TestSetupsDefault"]["test_setups"]).to eq 'off_target' + expect(smd["SMD_Interface_TestSetupsDefault"]["test_setups"]).to eq 'none' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("test_setups_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_TestSetups'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "test_setups"' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("test_setups_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_TestSetups'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "test_setups"' + end + end + + end +end diff --git a/dox_trace/spec/tester_spec.rb b/dox_trace/spec/tester_spec.rb new file mode 100644 index 0000000..fef1c05 --- /dev/null +++ b/dox_trace/spec/tester_spec.rb @@ -0,0 +1,88 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute tester" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("tester") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Tester', 'DoxTrace_HTML_Tester'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tester", "index.html") + + expect(data.value("SRS_Requirement_TesterXY", "tester")).to eq 'XY' + expect(data.value("InputRequirement_TesterXY", "tester")).to eq 'XY' + expect(data.value("SRS_Srs_TesterXY", "tester")).to eq 'XY' + expect(data.value("SWA_Spec_TesterXY", "tester")).to eq 'XY' + expect(data.value("SMD_Unit_TesterXY", "tester")).to eq 'XY' + expect(data.value("SWA_Interface_TesterXY", "tester")).to eq 'XY' + expect(data.exist?("SMD_Interface_TesterXY", "tester")).to be false + + expect(data.value("SRS_Requirement_TesterDefault", "tester")).to eq '[missing]' + expect(data.value("InputRequirement_TesterDefault", "tester")).to eq '[missing]' + expect(data.value("SRS_Srs_TesterDefault", "tester")).to eq '[missing]' + expect(data.value("SWA_Spec_TesterDefault", "tester")).to eq '[missing]' + expect(data.value("SMD_Unit_TesterDefault", "tester")).to eq '[missing]' + expect(data.value("SWA_Interface_TesterDefault", "tester")).to eq '[missing]' + expect(data.exist?("SMD_Interface_TesterDefault", "tester")).to be false + + expect(data.value("SRS_Requirement_TesterDefaultStruck", "tester")).to eq '-' + expect(data.value("SRS_Srs_TesterDefaultStruck", "tester")).to eq '-' + expect(data.value("InputRequirement_TesterDefaultStruck", "tester")).to eq '-' + expect(data.value("InputRequirement_TesterDefaultStruck", "tester")).to eq '-' + expect(data.value("SRS_Requirement_TesterDefaultTestSetupsNone", "tester")).to eq '-' + expect(data.value("SRS_Srs_TesterDefaultTestSetupsNone", "tester")).to eq '-' + expect(data.value("InputRequirement_TesterDefaultTestSetupsNone", "tester")).to eq '-' + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_Tester', 'DoxTrace_Export_Attributes', 'DoxTrace_Export_Tester'] do + srs = @test.dim_original_data["spec/test_input/tester/export_root/srs/index.dim"] + expect(srs["SRS_Srs_TesterXY"]["tester"]).to eq 'XY' + expect(srs["SRS_Srs_TesterDefault"]["tester"]).to eq '' + expect(srs["SRS_Srs_TesterDefaultStruck"]["tester"]).to eq '' + expect(srs["SRS_Srs_TesterDefaultTestSetupsNone"]["tester"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/tester/export_root/swa/index.dim"] + expect(swa["SWA_Spec_TesterXY"]["tester"]).to eq 'XY' + expect(swa["SWA_Interface_TesterXY"]["tester"]).to eq 'XY' + expect(swa["SWA_Spec_TesterDefault"]["tester"]).to eq '' + expect(swa["SWA_Interface_TesterDefault"]["tester"]).to eq '' + + smd = @test.dim_original_data["spec/test_input/tester/export_root/smd/index.dim"] + expect(smd["SMD_Unit_TesterXY"]["tester"]).to eq 'XY' + expect(smd["SMD_Interface_TesterXY"]["tester"]).to eq '' + expect(smd["SMD_Unit_TesterDefault"]["tester"]).to eq '' + expect(smd["SMD_Interface_TesterDefault"]["tester"]).to eq '' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("tester_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Tester'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "tester"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("tester_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Tester'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "tester"' + end + end + + end +end diff --git a/dox_trace/spec/tr_architecture_spec.rb b/dox_trace/spec/tr_architecture_spec.rb new file mode 100644 index 0000000..67f7103 --- /dev/null +++ b/dox_trace/spec/tr_architecture_spec.rb @@ -0,0 +1,435 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report for architecture" do + + context 'status table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_status_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_status_none", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_status_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_status_empty", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_status_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_status_table", "report.html") + expect(data.tr_nodata?("Status")).to be false + expect(data.tr_desc("Status")).to include table_desc + + v = data.tr_values("Status") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_draft1", "SWA_Req_draft2", "SWA_Req_invalid1", "SWA_Req_valid1", "SWA_Req_valid2", "SWA_Second_valid3"] + expect(v["TOTAL"]["valid"]).to match_array ["SWA_Req_valid1", "SWA_Req_valid2", "SWA_Second_valid3"] + expect(v["TOTAL"]["draft"]).to match_array ["SWA_Req_draft1", "SWA_Req_draft2"] + expect(v["TOTAL"]["invalid"]).to match_array ["SWA_Req_invalid1"] + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_draft1", "SWA_Req_draft2", "SWA_Req_invalid1", "SWA_Req_valid1", "SWA_Req_valid2"] + expect(v["SWA_Req"]["valid"]).to match_array ["SWA_Req_valid1", "SWA_Req_valid2"] + expect(v["SWA_Req"]["draft"]).to match_array ["SWA_Req_draft1", "SWA_Req_draft2"] + expect(v["SWA_Req"]["invalid"]).to match_array ["SWA_Req_invalid1"] + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_valid3"] + expect(v["SWA_Second"]["valid"]).to match_array ["SWA_Second_valid3"] + expect(v["SWA_Second"]["draft"]).to match_array [] + expect(v["SWA_Second"]["invalid"]).to match_array [] + end + end + end + + context 'type table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_type_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_type_none", "report.html") + expect(data.tr_nodata?("Type")).to be true + expect(data.tr_desc("Type")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_type_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_type_empty", "report.html") + expect(data.tr_nodata?("Type")).to be true + expect(data.tr_desc("Type")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_type_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_type_table", "report.html") + expect(data.tr_nodata?("Type")).to be false + expect(data.tr_desc("Type")).to include table_desc + + v = data.tr_values("Type") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_interface1", "SWA_Req_mod1", "SWA_Req_spec1", "SWA_Req_spec2", "SWA_Req_spec3", "SWA_Second_interface2"] + expect(v["TOTAL"]["spec"]).to match_array ["SWA_Req_spec1", "SWA_Req_spec2", "SWA_Req_spec3"] + expect(v["TOTAL"]["interface"]).to match_array ["SWA_Req_interface1", "SWA_Second_interface2"] + expect(v["TOTAL"]["mod"]).to match_array ["SWA_Req_mod1"] + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_interface1", "SWA_Req_mod1", "SWA_Req_spec1", "SWA_Req_spec2", "SWA_Req_spec3"] + expect(v["SWA_Req"]["spec"]).to match_array ["SWA_Req_spec1", "SWA_Req_spec2", "SWA_Req_spec3"] + expect(v["SWA_Req"]["interface"]).to match_array ["SWA_Req_interface1"] + expect(v["SWA_Req"]["mod"]).to match_array ["SWA_Req_mod1"] + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_interface2"] + expect(v["SWA_Second"]["spec"]).to match_array [] + expect(v["SWA_Second"]["interface"]).to match_array ["SWA_Second_interface2"] + expect(v["SWA_Second"]["mod"]).to match_array [] + end + end + end + + context 'safety table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_safety_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_safety_none", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_safety_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_safety_empty", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_safety_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_safety_table", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be false + expect(data.tr_desc("Functional Safety")).to include table_desc + + v = data.tr_values("Functional Safety") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_A1", "SWA_Req_A2", "SWA_Req_B(C)1", "SWA_Req_notset1", "SWA_Second_QM"] + expect(v["TOTAL"]["ASIL_A"]).to match_array ["SWA_Req_A1", "SWA_Req_A2"] + expect(v["TOTAL"]["ASIL_B(C)"]).to match_array ["SWA_Req_B(C)1"] + expect(v["TOTAL"]["QM"]).to match_array ["SWA_Second_QM"] + expect(v["TOTAL"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_A1", "SWA_Req_A2", "SWA_Req_B(C)1", "SWA_Req_notset1"] + expect(v["SWA_Req"]["ASIL_A"]).to match_array ["SWA_Req_A1", "SWA_Req_A2"] + expect(v["SWA_Req"]["ASIL_B(C)"]).to match_array ["SWA_Req_B(C)1"] + expect(v["SWA_Req"]["QM"]).to match_array [] + expect(v["SWA_Req"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_QM"] + expect(v["SWA_Second"]["ASIL_A"]).to match_array [] + expect(v["SWA_Second"]["ASIL_B(C)"]).to match_array [] + expect(v["SWA_Second"]["QM"]).to match_array ["SWA_Second_QM"] + expect(v["SWA_Second"]["not_set"]).to match_array [] + end + end + end + + context 'cal table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_cal_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_cal_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_cal_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_cal_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_cal_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_cal_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_qm1", "SWA_Req_notset1", "SWA_Req_cal1", "SWA_Req_yes1", "SWA_Second_qm2"] + expect(v["TOTAL"]["CAL_1"]).to match_array ["SWA_Req_cal1"] + expect(v["TOTAL"]["CAL_4"]).to match_array ["SWA_Req_yes1"] + expect(v["TOTAL"]["QM"]).to match_array ["SWA_Req_qm1", "SWA_Second_qm2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_qm1", "SWA_Req_notset1", "SWA_Req_cal1", "SWA_Req_yes1"] + expect(v["SWA_Req"]["CAL_1"]).to match_array ["SWA_Req_cal1"] + expect(v["SWA_Req"]["CAL_4"]).to match_array ["SWA_Req_yes1"] + expect(v["SWA_Req"]["QM"]).to match_array ["SWA_Req_qm1"] + expect(v["SWA_Req"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_qm2"] + expect(v["SWA_Second"]["CAL_1"]).to match_array [] + expect(v["SWA_Second"]["CAL_1"]).to match_array [] + expect(v["SWA_Second"]["QM"]).to match_array ["SWA_Second_qm2"] + expect(v["SWA_Second"]["not_set"]).to match_array [] + end + end + end + + context 'security table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_security_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_security_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_security_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_security_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_security_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_security_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_no1", "SWA_Req_notset1", "SWA_Req_yes1", "SWA_Req_yes2", "SWA_Second_no2"] + expect(v["TOTAL"]["yes"]).to match_array ["SWA_Req_yes1", "SWA_Req_yes2"] + expect(v["TOTAL"]["no"]).to match_array ["SWA_Req_no1", "SWA_Second_no2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_no1", "SWA_Req_notset1", "SWA_Req_yes1", "SWA_Req_yes2"] + expect(v["SWA_Req"]["yes"]).to match_array ["SWA_Req_yes1", "SWA_Req_yes2"] + expect(v["SWA_Req"]["no"]).to match_array ["SWA_Req_no1"] + expect(v["SWA_Req"]["not_set"]).to match_array ["SWA_Req_notset1"] + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_no2"] + expect(v["SWA_Second"]["yes"]).to match_array [] + expect(v["SWA_Second"]["no"]).to match_array ["SWA_Second_no2"] + expect(v["SWA_Second"]["not_set"]).to match_array [] + end + end + end + + context 'referenced/derived table' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_ref_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_ref_none", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_ref_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_ref_empty", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_ref_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_ref_table", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be false + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + + v = data.tr_values("Upstream and Downstream") + + expect(v["TOTAL"]["all"]).to match_array ["SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", + "SWA_Level_all", "SWA_Level_input", "SWA_Level_none", "SWA_Level_software", "SWA_Level_srs", "SWA_Level_swa", + "SWA_Req_no1", "SWA_Second_ref1", "SWA_Parent_swa", "SWA_Req_refderef1", "SWA_Req_refderef2"] + expect(v["TOTAL"]["Downstream Sufficient"]).to match_array ["SWA_Parent_swa", "SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", "SWA_Req_refderef1", "SWA_Req_refderef2"] + expect(v["TOTAL"]["Downstream Missing"]).to match_array ["SWA_Level_all", "SWA_Level_input", "SWA_Level_none", "SWA_Level_software", "SWA_Level_srs", "SWA_Level_swa", "SWA_Req_no1", "SWA_Second_ref1"] + expect(v["TOTAL"]["Upstream Sufficient"]).to match_array ["SWA_Second_ref1", "SWA_Req_refderef1", "SWA_Req_refderef2", "SWA_Level_all", "SWA_Level_software", "SWA_Level_srs", "SWA_Level_swa"] + expect(v["TOTAL"]["Upstream Missing"]).to match_array ["SWA_Level_input", "SWA_Level_none", "SWA_Parent_swa", "SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", "SWA_Req_no1"] + + expect(v["SWA_Req"]["all"]).to match_array ["SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", "SWA_Req_no1", "SWA_Req_refderef1", "SWA_Req_refderef2"] + expect(v["SWA_Req"]["Downstream Sufficient"]).to match_array ["SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", "SWA_Req_refderef1", "SWA_Req_refderef2"] + expect(v["SWA_Req"]["Downstream Missing"]).to match_array ["SWA_Req_no1"] + expect(v["SWA_Req"]["Upstream Sufficient"]).to match_array ["SWA_Req_refderef1", "SWA_Req_refderef2"] + expect(v["SWA_Req"]["Upstream Missing"]).to match_array ["SWA_Req_deref1", "SWA_Req_deref2", "SWA_Req_deref3", "SWA_Req_deref4", "SWA_Req_deref5", "SWA_Req_no1"] + + expect(v["SWA_Second"]["all"]).to match_array ["SWA_Second_ref1"] + expect(v["SWA_Second"]["Downstream Sufficient"]).to match_array [] + expect(v["SWA_Second"]["Downstream Missing"]).to match_array ["SWA_Second_ref1"] + expect(v["SWA_Second"]["Upstream Sufficient"]).to match_array ["SWA_Second_ref1"] + expect(v["SWA_Second"]["Upstream Missing"]).to match_array [] + + expect(v["SWA_Parent"]["all"]).to match_array ["SWA_Parent_swa"] + expect(v["SWA_Parent"]["Downstream Sufficient"]).to match_array ["SWA_Parent_swa"] + expect(v["SWA_Parent"]["Downstream Missing"]).to match_array [] + expect(v["SWA_Parent"]["Upstream Sufficient"]).to match_array [] + expect(v["SWA_Parent"]["Upstream Missing"]).to match_array ["SWA_Parent_swa"] + + expect(v["SWA_Level"]["all"]).to match_array ["SWA_Level_all", "SWA_Level_input", "SWA_Level_none", "SWA_Level_software", "SWA_Level_srs", "SWA_Level_swa"] + expect(v["SWA_Level"]["Downstream Sufficient"]).to match_array [] + expect(v["SWA_Level"]["Downstream Missing"]).to match_array ["SWA_Level_all", "SWA_Level_input", "SWA_Level_none", "SWA_Level_software", "SWA_Level_srs", "SWA_Level_swa"] + expect(v["SWA_Level"]["Upstream Sufficient"]).to match_array ["SWA_Level_all", "SWA_Level_swa", "SWA_Level_software", "SWA_Level_srs"] + expect(v["SWA_Level"]["Upstream Missing"]).to match_array ["SWA_Level_input", "SWA_Level_none"] + end + end + end + + context 'list of specifications' do + table_desc = "type = spec / interface / mod |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_architecture_list_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_ref_none", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be true + expect(data.tr_desc("List of Specifications")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_architecture_list_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_ref_empty", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be true + expect(data.tr_desc("List of Specifications")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_architecture_list_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportArchitecture'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_architecture_list_table", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be false + expect(data.tr_desc("List of Specifications")).to include table_desc + + v = data.tr_list("List of Specifications") + expect(v.length). to be 9 + + table = {"SWA_Req_deref1" => {"mod" => "SWA_Req", "Downstream" => "SWA_Req_refderef1, SWA_Req_refderef2, SWA_Second_ref1", "Upstream" => "[missing]"}, + "SWA_Req_deref2" => {"mod" => "SWA_Req", "Downstream" => "SWA_Req_notset2, index.rst, second.rst", "Upstream" => "[missing]"}, + "SWA_Req_deref3" => {"mod" => "SWA_Req", "Downstream" => "index.rst", "Upstream" => "[missing]"}, + "SWA_Req_deref4" => {"mod" => "SWA_Req", "Downstream" => "abc", "Upstream" => "[missing]"}, + "SWA_Req_deref5" => {"mod" => "SWA_Req", "Downstream" => "efg", "Upstream" => "[missing]"}, + "SWA_Req_no1" => {"mod" => "SWA_Req", "Downstream" => "[missing]", "Upstream" => "[missing]"}, + "SWA_Req_refderef1" => {"mod" => "SWA_Req", "Downstream" => "SWA_Req_refderef2", "Upstream" => "SRS_Req_info1, SWA_Req_deref1, SWA_Req_notset3"}, + "SWA_Req_refderef2" => {"mod" => "SWA_Req", "Downstream" => "SWA_Req_notset2", "Upstream" => "SWA_Req_deref1, SWA_Req_refderef1"}, + "SWA_Second_ref1" => {"mod" => "SWA_Second", "Downstream" => "[missing]", "Upstream" => "SWA_Req_deref1"}} + v.each do |content| + t = table[content["ID"]] + expect(content["mod"]).to eq t["mod"] + expect(content["Downstream"]).to eq t["Downstream"] + expect(content["Upstream"]).to eq t["Upstream"] + end + end + end + end + + end +end diff --git a/dox_trace/spec/tr_general_spec.rb b/dox_trace/spec/tr_general_spec.rb new file mode 100644 index 0000000..a75fa7a --- /dev/null +++ b/dox_trace/spec/tr_general_spec.rb @@ -0,0 +1,85 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report" do + + context 'shall determine the module name of the specifications' do + before(:all) do + @test = Test.new("tr_general_notitle") + @test.run + end + it 'and if not possible, use "Unknown" as fallback', doc_refs: ['DoxTrace_HTML_TraceabilityReportUnknownModule'] do + expect(@test.exit_code).to be == 0 + + data = HtmlData.new("tr_general_notitle", "report.html") + v = data.tr_values("Developer") + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_notset1"] + expect(v["TOTAL"]["Abc AG"]).to match_array [] + expect(v["TOTAL"]["other"]).to match_array [] + expect(v["TOTAL"]["not set"]).to match_array ["CRS_Req_notset1"] + expect(v["Unknown"]["all"]).to match_array ["CRS_Req_notset1"] + expect(v["Unknown"]["Abc AG"]).to match_array [] + expect(v["Unknown"]["other"]).to match_array [] + expect(v["Unknown"]["not set"]).to match_array ["CRS_Req_notset1"] + end + end + + context 'with invalid traceability report category' do + before(:all) do + @test = Test.new("tr_general_invalidcategory") + @test.run + end + it 'shall abort and print an appropriate error message', doc_refs: ['DoxTrace_HTML_TraceabilityReportUnknownCategory'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'report.rst:7: category must be input, software, architecture, module or source' + end + end + + context 'shall have an option to filter for developers' do + before(:all) do + @test = Test.new("tr_general_missingdeveloper") + @test.run + end + it 'and abort the build if not specified', doc_refs: ['DoxTrace_HTML_TraceabilityDeveloper'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'report.rst:7: developer option not specified' + end + end + + context 'shall be tolerant with filtering for developer' do + before(:all) do + @test = Test.new("tr_general_developerregex") + @test.run + end + it 'using a generic regex', doc_refs: ['DoxTrace_HTML_TraceabilityDeveloper'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_general_developerregex", "report.html") + expect(data.tr_nodata?("Status")).to be false + v = data.tr_values("Status") + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_ok1", "SRS_Req_ok2", "SRS_Req_ok3", "SRS_Req_ok4", "SRS_Req_ok5", "SRS_Req_ok6", "SRS_Req_ok7"] + end + end + + context 'shall ignore' do + before(:all) do + @test = Test.new("tr_general_ignore") + @test.run + end + it 'specifications with attribute ignore_in_export', doc_refs: ['DoxTrace_HTML_TraceabilityReportIgnore'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_general_ignore", "report.html") + + v = data.tr_values("Status") + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_2"] + expect(v["TOTAL"]["valid"]).to match_array [] + expect(v["TOTAL"]["draft"]).to match_array ["SMD_Req_2"] + expect(v["TOTAL"]["invalid"]).to match_array [] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_2"] + expect(v["SMD_Req"]["valid"]).to match_array [] + expect(v["SMD_Req"]["draft"]).to match_array ["SMD_Req_2"] + expect(v["SMD_Req"]["invalid"]).to match_array [] + end + end + + end +end diff --git a/dox_trace/spec/tr_input_spec.rb b/dox_trace/spec/tr_input_spec.rb new file mode 100644 index 0000000..4cf6e67 --- /dev/null +++ b/dox_trace/spec/tr_input_spec.rb @@ -0,0 +1,458 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report for input requirements" do + + context 'developer table' do + table_desc = "type = requirement" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_dev_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_dev_none", "report.html") + expect(data.tr_nodata?("Developer")).to be true + expect(data.tr_desc("Developer")).to include table_desc + end + end + + context 'developer table with valid data' do + before(:all) do + @test = Test.new("tr_input_dev_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_dev_table", "report.html") + expect(data.tr_nodata?("Developer")).to be false + expect(data.tr_desc("Developer")).to include table_desc + + v = data.tr_values("Developer") + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_notset1", "CRS_Req_notset2", "CRS_Req_notset3", "CRS_Req_abc1", "CRS_Req_abc2", "CRS_Req_other1", "CRS_Req_abcother1"] + expect(v["TOTAL"]["Abc AG"]).to match_array ["CRS_Req_abc1", "CRS_Req_abc2", "CRS_Req_abcother1"] + expect(v["TOTAL"]["other"]).to match_array ["CRS_Req_other1", "CRS_Req_abcother1"] + expect(v["TOTAL"]["not set"]).to match_array ["CRS_Req_notset1", "CRS_Req_notset2", "CRS_Req_notset3"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_notset1", "CRS_Req_notset2", "CRS_Req_notset3"] + expect(v["Heading"]["Abc AG"]).to match_array [] + expect(v["Heading"]["other"]).to match_array [] + expect(v["Heading"]["not set"]).to match_array ["CRS_Req_notset1", "CRS_Req_notset2", "CRS_Req_notset3"] + expect(v["Second Document"]["all"]).to match_array ["CRS_Req_abc1", "CRS_Req_abc2", "CRS_Req_other1", "CRS_Req_abcother1"] + expect(v["Second Document"]["Abc AG"]).to match_array ["CRS_Req_abc1", "CRS_Req_abc2", "CRS_Req_abcother1"] + expect(v["Second Document"]["other"]).to match_array ["CRS_Req_other1", "CRS_Req_abcother1"] + expect(v["Second Document"]["not set"]).to match_array [] + end + end + end + + context 'status table' do + table_desc = "type = requirement |br| developer = Abc AG" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_status_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_status_none", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_status_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_status_empty", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_status_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_status_table", "report.html") + expect(data.tr_nodata?("Status")).to be false + expect(data.tr_desc("Status")).to include table_desc + + v = data.tr_values("Status") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_valid1", "CRS_Req_valid2", "CRS_Req_valid3", "CRS_Req_draft1", "CRS_Req_draft2", "CRS_Req_invalid1"] + expect(v["TOTAL"]["valid"]).to match_array ["CRS_Req_valid1", "CRS_Req_valid2", "CRS_Req_valid3"] + expect(v["TOTAL"]["draft"]).to match_array ["CRS_Req_draft1", "CRS_Req_draft2"] + expect(v["TOTAL"]["invalid"]).to match_array ["CRS_Req_invalid1"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_valid1", "CRS_Req_valid2", "CRS_Req_draft1", "CRS_Req_draft2", "CRS_Req_invalid1"] + expect(v["Heading"]["valid"]).to match_array ["CRS_Req_valid1", "CRS_Req_valid2"] + expect(v["Heading"]["draft"]).to match_array ["CRS_Req_draft1", "CRS_Req_draft2"] + expect(v["Heading"]["invalid"]).to match_array ["CRS_Req_invalid1"] + expect(v["Second Document"]["all"]).to match_array ["CRS_Req_valid3"] + expect(v["Second Document"]["valid"]).to match_array ["CRS_Req_valid3"] + expect(v["Second Document"]["draft"]).to match_array [] + expect(v["Second Document"]["invalid"]).to match_array [] + end + end + end + + context 'review_status table' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_reviewstatus_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_reviewstatus_none", "report.html") + expect(data.tr_nodata?("Review Status")).to be true + expect(data.tr_desc("Review Status")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_reviewstatus_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_reviewstatus_empty", "report.html") + expect(data.tr_nodata?("Review Status")).to be true + expect(data.tr_desc("Review Status")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_reviewstatus_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_reviewstatus_table", "report.html") + expect(data.tr_nodata?("Review Status")).to be false + expect(data.tr_desc("Review Status")).to include table_desc + + v = data.tr_values("Review Status") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_accepted1", "CRS_Req_accepted2", "CRS_Req_accepted3", "CRS_Req_unclear1", "CRS_Req_unclear2", "CRS_Req_rejected1", "CRS_Req_notrelevant1", "CRS_Req_notreviewed1", "CRS_Req_notreviewed2"] + expect(v["TOTAL"]["accepted"]).to match_array ["CRS_Req_accepted1", "CRS_Req_accepted2", "CRS_Req_accepted3"] + expect(v["TOTAL"]["unclear"]).to match_array ["CRS_Req_unclear1", "CRS_Req_unclear2"] + expect(v["TOTAL"]["rejected"]).to match_array ["CRS_Req_rejected1"] + expect(v["TOTAL"]["not_relevant"]).to match_array ["CRS_Req_notrelevant1"] + expect(v["TOTAL"]["not_reviewed"]).to match_array ["CRS_Req_notreviewed1", "CRS_Req_notreviewed2"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_accepted1", "CRS_Req_accepted2", "CRS_Req_unclear1", "CRS_Req_unclear2", "CRS_Req_rejected1", "CRS_Req_notrelevant1", "CRS_Req_notreviewed1"] + expect(v["Heading"]["accepted"]).to match_array ["CRS_Req_accepted1", "CRS_Req_accepted2"] + expect(v["Heading"]["unclear"]).to match_array ["CRS_Req_unclear1", "CRS_Req_unclear2"] + expect(v["Heading"]["rejected"]).to match_array ["CRS_Req_rejected1"] + expect(v["Heading"]["not_relevant"]).to match_array ["CRS_Req_notrelevant1"] + expect(v["Heading"]["not_reviewed"]).to match_array ["CRS_Req_notreviewed1"] + expect(v["Second Document"]["all"]).to match_array ["CRS_Req_accepted3", "CRS_Req_notreviewed2"] + expect(v["Second Document"]["accepted"]).to match_array ["CRS_Req_accepted3"] + expect(v["Second Document"]["unclear"]).to match_array [] + expect(v["Second Document"]["rejected"]).to match_array [] + expect(v["Second Document"]["not_relevant"]).to match_array [] + expect(v["Second Document"]["not_reviewed"]).to match_array ["CRS_Req_notreviewed2"] + end + end + end + + context 'safety table' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid |br| review_status = accepted" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_safety_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_safety_none", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_safety_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_safety_empty", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_safety_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_safety_table", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be false + expect(data.tr_desc("Functional Safety")).to include table_desc + + v = data.tr_values("Functional Safety") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_A1", "CRS_Req_A2", "CRS_Req_B(C)1", "CRS_Second_QM"] + expect(v["TOTAL"]["ASIL_A"]).to match_array ["CRS_Req_A1", "CRS_Req_A2"] + expect(v["TOTAL"]["ASIL_B(C)"]).to match_array ["CRS_Req_B(C)1"] + expect(v["TOTAL"]["QM"]).to match_array ["CRS_Second_QM"] + expect(v["TOTAL"]["not_set"]).to match_array [] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_A1", "CRS_Req_A2", "CRS_Req_B(C)1"] + expect(v["Heading"]["ASIL_A"]).to match_array ["CRS_Req_A1", "CRS_Req_A2"] + expect(v["Heading"]["ASIL_B(C)"]).to match_array ["CRS_Req_B(C)1"] + expect(v["Heading"]["QM"]).to match_array [] + expect(v["Heading"]["not_set"]).to match_array [] + expect(v["Second Document"]["all"]).to match_array ["CRS_Second_QM"] + expect(v["Second Document"]["ASIL_A"]).to match_array [] + expect(v["Second Document"]["ASIL_B(C)"]).to match_array [] + expect(v["Second Document"]["QM"]).to match_array ["CRS_Second_QM"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'cal table' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid |br| review_status = accepted" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_cal_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_cal_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_cal_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_cal_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_cal_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_cal_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_qm1", "CRS_Req_notset1", "CRS_Req_cal1", "CRS_Req_yes1", "CRS_Second_qm2"] + expect(v["TOTAL"]["CAL_1"]).to match_array ["CRS_Req_cal1"] + expect(v["TOTAL"]["CAL_4"]).to match_array ["CRS_Req_yes1"] + expect(v["TOTAL"]["QM"]).to match_array ["CRS_Req_qm1", "CRS_Second_qm2"] + expect(v["TOTAL"]["not_set"]).to match_array ["CRS_Req_notset1"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_qm1", "CRS_Req_notset1", "CRS_Req_cal1", "CRS_Req_yes1"] + expect(v["Heading"]["CAL_1"]).to match_array ["CRS_Req_cal1"] + expect(v["Heading"]["CAL_4"]).to match_array ["CRS_Req_yes1"] + expect(v["Heading"]["QM"]).to match_array ["CRS_Req_qm1"] + expect(v["Heading"]["not_set"]).to match_array ["CRS_Req_notset1"] + expect(v["Second Document"]["all"]).to match_array ["CRS_Second_qm2"] + expect(v["Second Document"]["CAL_1"]).to match_array [] + expect(v["Second Document"]["CAL_4"]).to match_array [] + expect(v["Second Document"]["QM"]).to match_array ["CRS_Second_qm2"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'security table' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid |br| review_status = accepted" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_security_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_security_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_security_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_security_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_security_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_security_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_no1", "CRS_Req_notset1", "CRS_Req_yes1", "CRS_Req_yes2", "CRS_Second_no2"] + expect(v["TOTAL"]["yes"]).to match_array ["CRS_Req_yes1", "CRS_Req_yes2"] + expect(v["TOTAL"]["no"]).to match_array ["CRS_Req_no1", "CRS_Second_no2"] + expect(v["TOTAL"]["not_set"]).to match_array ["CRS_Req_notset1"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_no1", "CRS_Req_notset1", "CRS_Req_yes1", "CRS_Req_yes2"] + expect(v["Heading"]["yes"]).to match_array ["CRS_Req_yes1", "CRS_Req_yes2"] + expect(v["Heading"]["no"]).to match_array ["CRS_Req_no1"] + expect(v["Heading"]["not_set"]).to match_array ["CRS_Req_notset1"] + expect(v["Second Document"]["all"]).to match_array ["CRS_Second_no2"] + expect(v["Second Document"]["yes"]).to match_array [] + expect(v["Second Document"]["no"]).to match_array ["CRS_Second_no2"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'referenced/derived table' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid |br| review_status = accepted" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_ref_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_ref_none", "report.html") + expect(data.tr_nodata?("Downstream")).to be true + expect(data.tr_desc("Downstream")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_ref_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_ref_empty", "report.html") + expect(data.tr_nodata?("Downstream")).to be true + expect(data.tr_desc("Downstream")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_ref_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_ref_table", "report.html") + expect(data.tr_nodata?("Downstream")).to be false + expect(data.tr_desc("Downstream")).to include table_desc + + v = data.tr_values("Downstream") + + expect(v["TOTAL"]["all"]).to match_array ["CRS_Req_deref1", "CRS_Req_refderef1", "CRS_Req_refderef2", "CRS_Req_deref2", "CRS_Req_deref3", "CRS_Req_ref1"] + expect(v["TOTAL"]["Downstream Sufficient"]).to match_array ["CRS_Req_deref1", "CRS_Req_refderef1", "CRS_Req_refderef2", "CRS_Req_deref2", "CRS_Req_deref3"] + expect(v["TOTAL"]["Downstream Missing"]).to match_array ["CRS_Req_ref1"] + expect(v["Heading"]["all"]).to match_array ["CRS_Req_deref1", "CRS_Req_refderef1", "CRS_Req_refderef2", "CRS_Req_deref2", "CRS_Req_deref3"] + expect(v["Heading"]["Downstream Sufficient"]).to match_array ["CRS_Req_deref1", "CRS_Req_refderef1", "CRS_Req_refderef2", "CRS_Req_deref2", "CRS_Req_deref3"] + expect(v["Heading"]["Downstream Missing"]).to match_array [] + expect(v["Second Document"]["all"]).to match_array ["CRS_Req_ref1"] + expect(v["Second Document"]["Downstream Sufficient"]).to match_array [] + expect(v["Second Document"]["Downstream Missing"]).to match_array ["CRS_Req_ref1"] + end + end + end + + context 'list of requirements' do + table_desc = "type = requirement |br| developer = Abc AG |br| status = valid |br| review_status = accepted" + context 'with no data' do + before(:all) do + @test = Test.new("tr_input_list_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_ref_none", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be true + expect(data.tr_desc("List of Requirements")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_input_list_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_ref_empty", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be true + expect(data.tr_desc("List of Requirements")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_input_list_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportInput'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_input_list_table", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be false + expect(data.tr_desc("List of Requirements")).to include table_desc + + v = data.tr_list("List of Requirements") + expect(v.length). to be 6 + + table = {"CRS_Req_deref1" => {"mod" => "Heading", "Downstream" => "CRS_Req_ref1, CRS_Req_refderef1, CRS_Req_refderef2"}, + "CRS_Req_refderef1" => {"mod" => "Heading", "Downstream" => "CRS_Req_refderef2"}, + "CRS_Req_refderef2" => {"mod" => "Heading", "Downstream" => "CRS_Req_notset2"}, + "CRS_Req_deref2" => {"mod" => "Heading", "Downstream" => "-"}, + "CRS_Req_deref3" => {"mod" => "Heading", "Downstream" => "CRS_Req_notset2, index.rst, second.rst"}, + "CRS_Req_ref1" => {"mod" => "Second Document", "Downstream" => "[missing]"}} + v.each do |content| + t = table[content["ID"]] + expect(content["mod"]).to eq t["mod"] + expect(content["Downstream"]).to eq t["Downstream"] + end + end + end + end + + end +end diff --git a/dox_trace/spec/tr_module_spec.rb b/dox_trace/spec/tr_module_spec.rb new file mode 100644 index 0000000..25904c1 --- /dev/null +++ b/dox_trace/spec/tr_module_spec.rb @@ -0,0 +1,467 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report for module" do + + context 'status table' do + table_desc_deprecated = "type = spec / interface / unit |br| developer = Abc AG" + table_desc = "type = spec / unit |br| developer = Abc AG" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_status_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_status_none", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_status_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_status_empty", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc_deprecated + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_status_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_status_table", "report.html") + expect(data.tr_nodata?("Status")).to be false + expect(data.tr_desc("Status")).to include table_desc_deprecated + + v = data.tr_values("Status") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_draft1", "SMD_Req_draft2", "SMD_Req_invalid1", "SMD_Req_valid1", "SMD_Req_valid2", "SMD_Second_valid3"] + expect(v["TOTAL"]["valid"]).to match_array ["SMD_Req_valid1", "SMD_Req_valid2", "SMD_Second_valid3"] + expect(v["TOTAL"]["draft"]).to match_array ["SMD_Req_draft1", "SMD_Req_draft2"] + expect(v["TOTAL"]["invalid"]).to match_array ["SMD_Req_invalid1"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_draft1", "SMD_Req_draft2", "SMD_Req_invalid1", "SMD_Req_valid1", "SMD_Req_valid2"] + expect(v["SMD_Req"]["valid"]).to match_array ["SMD_Req_valid1", "SMD_Req_valid2"] + expect(v["SMD_Req"]["draft"]).to match_array ["SMD_Req_draft1", "SMD_Req_draft2"] + expect(v["SMD_Req"]["invalid"]).to match_array ["SMD_Req_invalid1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_valid3"] + expect(v["SMD_Second"]["valid"]).to match_array ["SMD_Second_valid3"] + expect(v["SMD_Second"]["draft"]).to match_array [] + expect(v["SMD_Second"]["invalid"]).to match_array [] + end + end + end + + context 'type table' do + table_desc_deprecated = "type = spec / interface / unit |br| developer = Abc AG |br| status = valid" + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_type_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_type_none", "report.html") + expect(data.tr_nodata?("Type")).to be true + expect(data.tr_desc("Type")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_type_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_type_empty", "report.html") + expect(data.tr_nodata?("Type")).to be true + expect(data.tr_desc("Type")).to include table_desc_deprecated + end + end + + context 'with valid data without deprecated interface type' do + before(:all) do + @test = Test.new("tr_module_type_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_type_table", "report.html") + expect(data.tr_nodata?("Type")).to be false + expect(data.tr_desc("Type")).to include table_desc + + v = data.tr_values("Type") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3", "SMD_Req_unit1", "SMD_Second_unit2"] + expect(v["TOTAL"]["spec"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3"] + expect(v["TOTAL"].include?("interface")).to be false + expect(v["TOTAL"]["unit"]).to match_array ["SMD_Req_unit1", "SMD_Second_unit2"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3", "SMD_Req_unit1"] + expect(v["SMD_Req"]["spec"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3"] + expect(v["SMD_Req"]["unit"]).to match_array ["SMD_Req_unit1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_unit2"] + expect(v["SMD_Second"]["spec"]).to match_array [] + expect(v["SMD_Second"]["unit"]).to match_array ["SMD_Second_unit2"] + end + end + context 'with valid data with deprecated interface type' do + before(:all) do + @test = Test.new("tr_module_type_table_deprecated") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_type_table_deprecated", "report.html") + expect(data.tr_nodata?("Type")).to be false + expect(data.tr_desc("Type")).to include table_desc_deprecated + + v = data.tr_values("Type") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_interface1", "SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3", "SMD_Req_unit1", "SMD_Second_unit2"] + expect(v["TOTAL"]["spec"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3"] + expect(v["TOTAL"]["interface"]).to match_array ["SMD_Req_interface1"] + expect(v["TOTAL"]["unit"]).to match_array ["SMD_Req_unit1", "SMD_Second_unit2"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_interface1", "SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3", "SMD_Req_unit1"] + expect(v["SMD_Req"]["spec"]).to match_array ["SMD_Req_spec1", "SMD_Req_spec2", "SMD_Req_spec3"] + expect(v["SMD_Req"]["interface"]).to match_array ["SMD_Req_interface1"] + expect(v["SMD_Req"]["unit"]).to match_array ["SMD_Req_unit1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_unit2"] + expect(v["SMD_Second"]["spec"]).to match_array [] + expect(v["SMD_Second"]["interface"]).to match_array [] + expect(v["SMD_Second"]["unit"]).to match_array ["SMD_Second_unit2"] + end + end + end + + context 'safety table' do + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_safety_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_safety_none", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_safety_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_safety_empty", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_safety_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_safety_table", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be false + expect(data.tr_desc("Functional Safety")).to include table_desc + + v = data.tr_values("Functional Safety") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_A1", "SMD_Req_A2", "SMD_Req_B(C)1", "SMD_Req_notset1", "SMD_Second_QM"] + expect(v["TOTAL"]["ASIL_A"]).to match_array ["SMD_Req_A1", "SMD_Req_A2"] + expect(v["TOTAL"]["ASIL_B(C)"]).to match_array ["SMD_Req_B(C)1"] + expect(v["TOTAL"]["QM"]).to match_array ["SMD_Second_QM"] + expect(v["TOTAL"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_A1", "SMD_Req_A2", "SMD_Req_B(C)1", "SMD_Req_notset1"] + expect(v["SMD_Req"]["ASIL_A"]).to match_array ["SMD_Req_A1", "SMD_Req_A2"] + expect(v["SMD_Req"]["ASIL_B(C)"]).to match_array ["SMD_Req_B(C)1"] + expect(v["SMD_Req"]["QM"]).to match_array [] + expect(v["SMD_Req"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_QM"] + expect(v["SMD_Second"]["ASIL_A"]).to match_array [] + expect(v["SMD_Second"]["ASIL_B(C)"]).to match_array [] + expect(v["SMD_Second"]["QM"]).to match_array ["SMD_Second_QM"] + expect(v["SMD_Second"]["not_set"]).to match_array [] + end + end + end + + context 'cal table' do + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_cal_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_cal_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_cal_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_cal_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_cal_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_cal_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_qm1", "SMD_Req_notset1", "SMD_Req_cal1", "SMD_Req_yes1", "SMD_Second_qm2"] + expect(v["TOTAL"]["CAL_1"]).to match_array ["SMD_Req_cal1"] + expect(v["TOTAL"]["CAL_4"]).to match_array ["SMD_Req_yes1"] + expect(v["TOTAL"]["QM"]).to match_array ["SMD_Req_qm1", "SMD_Second_qm2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_qm1", "SMD_Req_notset1", "SMD_Req_cal1", "SMD_Req_yes1"] + expect(v["SMD_Req"]["CAL_1"]).to match_array ["SMD_Req_cal1"] + expect(v["SMD_Req"]["CAL_4"]).to match_array ["SMD_Req_yes1"] + expect(v["SMD_Req"]["QM"]).to match_array ["SMD_Req_qm1"] + expect(v["SMD_Req"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_qm2"] + expect(v["SMD_Second"]["CAL_1"]).to match_array [] + expect(v["SMD_Second"]["CAL_1"]).to match_array [] + expect(v["SMD_Second"]["QM"]).to match_array ["SMD_Second_qm2"] + expect(v["SMD_Second"]["not_set"]).to match_array [] + end + end + end + + context 'security table' do + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_security_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_security_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_security_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_security_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_security_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_security_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SMD_Req_no1", "SMD_Req_notset1", "SMD_Req_yes1", "SMD_Req_yes2", "SMD_Second_no2"] + expect(v["TOTAL"]["yes"]).to match_array ["SMD_Req_yes1", "SMD_Req_yes2"] + expect(v["TOTAL"]["no"]).to match_array ["SMD_Req_no1", "SMD_Second_no2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_no1", "SMD_Req_notset1", "SMD_Req_yes1", "SMD_Req_yes2"] + expect(v["SMD_Req"]["yes"]).to match_array ["SMD_Req_yes1", "SMD_Req_yes2"] + expect(v["SMD_Req"]["no"]).to match_array ["SMD_Req_no1"] + expect(v["SMD_Req"]["not_set"]).to match_array ["SMD_Req_notset1"] + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_no2"] + expect(v["SMD_Second"]["yes"]).to match_array [] + expect(v["SMD_Second"]["no"]).to match_array ["SMD_Second_no2"] + expect(v["SMD_Second"]["not_set"]).to match_array [] + end + end + end + + context 'referenced/derived table' do + table_desc_deprecated = "type = spec / interface / unit |br| developer = Abc AG |br| status = valid" + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_ref_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_ref_none", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_ref_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_ref_empty", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc_deprecated + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_ref_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_ref_table", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be false + expect(data.tr_desc("Upstream and Downstream")).to include table_desc_deprecated + + v = data.tr_values("Upstream and Downstream") + + expect(v["TOTAL"]["all"]).to match_array [ "SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", + "SMD_Level_all", "SMD_Level_input", "SMD_Level_none", "SMD_Level_smd", "SMD_Level_software", "SMD_Level_srs", "SMD_Level_swa", + "SMD_Req_no1", "SMD_Second_ref1", "SMD_Parent_smd", "SMD_Req_refderef1", "SMD_Req_refderef2"] + expect(v["TOTAL"]["Downstream Sufficient"]).to match_array ["SMD_Parent_smd", "SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", "SMD_Req_refderef1", "SMD_Req_refderef2"] + expect(v["TOTAL"]["Downstream Missing"]).to match_array [ "SMD_Level_all", "SMD_Level_input", "SMD_Level_none", "SMD_Level_smd", "SMD_Level_software", "SMD_Level_srs", "SMD_Level_swa", "SMD_Second_ref1", "SMD_Req_no1"] + expect(v["TOTAL"]["Upstream Sufficient"]).to match_array ["SMD_Second_ref1", "SMD_Req_refderef1", "SMD_Req_refderef2", "SMD_Level_all", "SMD_Level_smd", "SMD_Level_swa"] + expect(v["TOTAL"]["Upstream Missing"]).to match_array ["SMD_Parent_smd", "SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", "SMD_Req_no1", "SMD_Level_none", "SMD_Level_input", "SMD_Level_software", "SMD_Level_srs"] + + expect(v["SMD_Req"]["all"]).to match_array ["SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", "SMD_Req_no1", "SMD_Req_refderef1", "SMD_Req_refderef2"] + expect(v["SMD_Req"]["Downstream Sufficient"]).to match_array ["SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", "SMD_Req_refderef1", "SMD_Req_refderef2"] + expect(v["SMD_Req"]["Downstream Missing"]).to match_array ["SMD_Req_no1"] + expect(v["SMD_Req"]["Upstream Sufficient"]).to match_array ["SMD_Req_refderef1", "SMD_Req_refderef2"] + expect(v["SMD_Req"]["Upstream Missing"]).to match_array ["SMD_Req_deref1", "SMD_Req_deref2", "SMD_Req_deref3", "SMD_Req_deref4", "SMD_Req_no1"] + + expect(v["SMD_Second"]["all"]).to match_array ["SMD_Second_ref1"] + expect(v["SMD_Second"]["Downstream Sufficient"]).to match_array [] + expect(v["SMD_Second"]["Downstream Missing"]).to match_array ["SMD_Second_ref1"] + expect(v["SMD_Second"]["Upstream Sufficient"]).to match_array ["SMD_Second_ref1"] + expect(v["SMD_Second"]["Upstream Missing"]).to match_array [] + + expect(v["SMD_Parent"]["all"]).to match_array ["SMD_Parent_smd"] + expect(v["SMD_Parent"]["Downstream Sufficient"]).to match_array ["SMD_Parent_smd"] + expect(v["SMD_Parent"]["Downstream Missing"]).to match_array [] + expect(v["SMD_Parent"]["Upstream Sufficient"]).to match_array [] + expect(v["SMD_Parent"]["Upstream Missing"]).to match_array ["SMD_Parent_smd"] + + expect(v["SMD_Level"]["all"]).to match_array ["SMD_Level_all", "SMD_Level_input", "SMD_Level_none", "SMD_Level_smd", "SMD_Level_software", "SMD_Level_srs", "SMD_Level_swa"] + expect(v["SMD_Level"]["Downstream Sufficient"]).to match_array [] + expect(v["SMD_Level"]["Downstream Missing"]).to match_array ["SMD_Level_all", "SMD_Level_input", "SMD_Level_none", "SMD_Level_smd", "SMD_Level_software", "SMD_Level_srs", "SMD_Level_swa"] + expect(v["SMD_Level"]["Upstream Sufficient"]).to match_array ["SMD_Level_all", "SMD_Level_smd", "SMD_Level_swa"] + expect(v["SMD_Level"]["Upstream Missing"]).to match_array ["SMD_Level_input", "SMD_Level_none", "SMD_Level_software", "SMD_Level_srs"] + end + end + end + + context 'list of specifications' do + table_desc_deprecated = "type = spec / interface / unit |br| developer = Abc AG |br| status = valid" + table_desc = "type = spec / unit |br| developer = Abc AG |br| status = valid" + + context 'with no data' do + before(:all) do + @test = Test.new("tr_module_list_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_ref_none", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be true + expect(data.tr_desc("List of Specifications")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_module_list_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_ref_empty", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be true + expect(data.tr_desc("List of Specifications")).to include table_desc_deprecated + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_module_list_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportModule'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_module_list_table", "report.html") + expect(data.tr_nodata?("List of Specifications")).to be false + expect(data.tr_desc("List of Specifications")).to include table_desc_deprecated + + v = data.tr_list("List of Specifications") + expect(v.length). to be 10 + + table = { + "SMD_Req_AbcccccccccccccccccccccccccccccccccccxAbcccc123xA-1" => {"mod" => "SMD_Req", "Downstream" => "SMD_Req_AbcccccccccccxAbcccc123xA-2, AbccccccccccccccccccccccccccccccccccxAbcccc123xA.txt", "Upstream" => "[missing]"}, + "SMD_Req_AbcccccccccccxAbcccc123xA-2" => {"mod" => "SMD_Req", "Downstream" => "[missing]", "Upstream" => "SMD_Req_AbcccccccccccccccccccccccccccccccccccxAbcccc123xA-1"}, + "SMD_Req_deref1" => {"mod" => "SMD_Req", "Downstream" => "SMD_Req_refderef1, SMD_Req_refderef2, SMD_Second_ref1", "Upstream" => "[missing]"}, + "SMD_Req_deref2" => {"mod" => "SMD_Req", "Downstream" => "SMD_Req_notset2, index.rst, second.rst", "Upstream" => "[missing]"}, + "SMD_Req_deref3" => {"mod" => "SMD_Req", "Downstream" => "index.rst", "Upstream" => "[missing]"}, + "SMD_Req_deref4" => {"mod" => "SMD_Req", "Downstream" => "invalid_ref", "Upstream" => "[missing]"}, + "SMD_Req_no1" => {"mod" => "SMD_Req", "Downstream" => "[missing]", "Upstream" => "[missing]"}, + "SMD_Req_refderef1" => {"mod" => "SMD_Req", "Downstream" => "SMD_Req_refderef2", "Upstream" => "SMD_Req_deref1, SMD_Req_notset3, SRS_Req_info1"}, + "SMD_Req_refderef2" => {"mod" => "SMD_Req", "Downstream" => "SMD_Req_notset2", "Upstream" => "SMD_Req_deref1, SMD_Req_refderef1"}, + "SMD_Second_ref1" => {"mod" => "SMD_Second", "Downstream" => "[missing]", "Upstream" => "SMD_Req_deref1"}} + v.each do |content| + t = table[content["ID"]] + expect(content["mod"]).to eq t["mod"] + expect(content["Downstream"]).to eq t["Downstream"] + expect(content["Upstream"]).to eq t["Upstream"] + end + end + end + end + + end +end diff --git a/dox_trace/spec/tr_software_spec.rb b/dox_trace/spec/tr_software_spec.rb new file mode 100644 index 0000000..5de6ed1 --- /dev/null +++ b/dox_trace/spec/tr_software_spec.rb @@ -0,0 +1,382 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report for software requirements" do + + context 'status table' do + table_desc = "type = requirement / srs |br| developer = Abc AG" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_status_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_status_none", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_status_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_status_empty", "report.html") + expect(data.tr_nodata?("Status")).to be true + expect(data.tr_desc("Status")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_status_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_status_table", "report.html") + expect(data.tr_nodata?("Status")).to be false + expect(data.tr_desc("Status")).to include table_desc + + v = data.tr_values("Status") + + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_valid1", "SRS_Req_valid2", "SRS_Req_valid3", "SRS_Req_draft1", "SRS_Req_draft2", "SRS_Req_invalid1"] + expect(v["TOTAL"]["valid"]).to match_array ["SRS_Req_valid1", "SRS_Req_valid2", "SRS_Req_valid3"] + expect(v["TOTAL"]["draft"]).to match_array ["SRS_Req_draft1", "SRS_Req_draft2"] + expect(v["TOTAL"]["invalid"]).to match_array ["SRS_Req_invalid1"] + expect(v["Heading"]["all"]).to match_array ["SRS_Req_valid1", "SRS_Req_valid2", "SRS_Req_draft2"] + expect(v["Heading"]["valid"]).to match_array ["SRS_Req_valid1", "SRS_Req_valid2"] + expect(v["Heading"]["draft"]).to match_array ["SRS_Req_draft2"] + expect(v["Heading"]["invalid"]).to match_array [] + expect(v["SRS_Req"]["all"]).to match_array ["SRS_Req_draft1", "SRS_Req_invalid1"] + expect(v["SRS_Req"]["valid"]).to match_array [] + expect(v["SRS_Req"]["draft"]).to match_array ["SRS_Req_draft1"] + expect(v["SRS_Req"]["invalid"]).to match_array ["SRS_Req_invalid1"] + expect(v["Second Document"]["all"]).to match_array ["SRS_Req_valid3"] + expect(v["Second Document"]["valid"]).to match_array ["SRS_Req_valid3"] + expect(v["Second Document"]["draft"]).to match_array [] + expect(v["Second Document"]["invalid"]).to match_array [] + end + end + end + + context 'safety table' do + table_desc = "type = requirement / srs |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_safety_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_safety_none", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_safety_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_safety_empty", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be true + expect(data.tr_desc("Functional Safety")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_safety_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_safety_table", "report.html") + expect(data.tr_nodata?("Functional Safety")).to be false + expect(data.tr_desc("Functional Safety")).to include table_desc + + v = data.tr_values("Functional Safety") + + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_A1", "SRS_Req_A2", "SRS_Req_B(C)1", "SRS_Req_notset1", "SRS_Second_QM"] + expect(v["TOTAL"]["ASIL_A"]).to match_array ["SRS_Req_A1", "SRS_Req_A2"] + expect(v["TOTAL"]["ASIL_B(C)"]).to match_array ["SRS_Req_B(C)1"] + expect(v["TOTAL"]["QM"]).to match_array ["SRS_Second_QM"] + expect(v["TOTAL"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["SRS_Req"]["all"]).to match_array ["SRS_Req_B(C)1", "SRS_Req_notset1"] + expect(v["SRS_Req"]["ASIL_A"]).to match_array [] + expect(v["SRS_Req"]["ASIL_B(C)"]).to match_array ["SRS_Req_B(C)1"] + expect(v["SRS_Req"]["QM"]).to match_array [] + expect(v["SRS_Req"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["Heading"]["all"]).to match_array ["SRS_Req_A1", "SRS_Req_A2"] + expect(v["Heading"]["ASIL_A"]).to match_array ["SRS_Req_A1", "SRS_Req_A2"] + expect(v["Heading"]["ASIL_B(C)"]).to match_array [] + expect(v["Heading"]["QM"]).to match_array [] + expect(v["Heading"]["not_set"]).to match_array [] + expect(v["Second Document"]["all"]).to match_array ["SRS_Second_QM"] + expect(v["Second Document"]["ASIL_A"]).to match_array [] + expect(v["Second Document"]["ASIL_B(C)"]).to match_array [] + expect(v["Second Document"]["QM"]).to match_array ["SRS_Second_QM"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'cal table' do + table_desc = "type = requirement / srs |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_cal_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_cal_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_cal_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_cal_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_cal_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_cal_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_qm1", "SRS_Req_notset1", "SRS_Req_cal1", "SRS_Req_yes1", "SRS_Second_qm2"] + expect(v["TOTAL"]["CAL_1"]).to match_array ["SRS_Req_cal1"] + expect(v["TOTAL"]["CAL_4"]).to match_array ["SRS_Req_yes1"] + expect(v["TOTAL"]["QM"]).to match_array ["SRS_Req_qm1", "SRS_Second_qm2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["SRS_Req"]["all"]).to match_array ["SRS_Req_qm1", "SRS_Req_notset1"] + expect(v["SRS_Req"]["CAL_1"]).to match_array [] + expect(v["SRS_Req"]["CAL_4"]).to match_array [] + expect(v["SRS_Req"]["QM"]).to match_array ["SRS_Req_qm1"] + expect(v["SRS_Req"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["Heading"]["all"]).to match_array ["SRS_Req_cal1", "SRS_Req_yes1"] + expect(v["Heading"]["CAL_1"]).to match_array ["SRS_Req_cal1"] + expect(v["Heading"]["CAL_4"]).to match_array ["SRS_Req_yes1"] + expect(v["Heading"]["QM"]).to match_array [] + expect(v["Heading"]["not_set"]).to match_array [] + expect(v["Second Document"]["all"]).to match_array ["SRS_Second_qm2"] + expect(v["Second Document"]["CAL_1"]).to match_array [] + expect(v["Second Document"]["CAL_4"]).to match_array [] + expect(v["Second Document"]["QM"]).to match_array ["SRS_Second_qm2"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'security table' do + table_desc = "type = requirement / srs |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_security_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_security_none", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_security_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_security_empty", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be true + expect(data.tr_desc("Cyber Security")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_security_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_security_table", "report.html") + expect(data.tr_nodata?("Cyber Security")).to be false + expect(data.tr_desc("Cyber Security")).to include table_desc + + v = data.tr_values("Cyber Security") + + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_no1", "SRS_Req_notset1", "SRS_Req_yes1", "SRS_Req_yes2", "SRS_Second_no2"] + expect(v["TOTAL"]["yes"]).to match_array ["SRS_Req_yes1", "SRS_Req_yes2"] + expect(v["TOTAL"]["no"]).to match_array ["SRS_Req_no1", "SRS_Second_no2"] + expect(v["TOTAL"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["SRS_Req"]["all"]).to match_array ["SRS_Req_no1", "SRS_Req_notset1"] + expect(v["SRS_Req"]["yes"]).to match_array [] + expect(v["SRS_Req"]["no"]).to match_array ["SRS_Req_no1"] + expect(v["SRS_Req"]["not_set"]).to match_array ["SRS_Req_notset1"] + expect(v["Heading"]["all"]).to match_array ["SRS_Req_yes1", "SRS_Req_yes2"] + expect(v["Heading"]["yes"]).to match_array ["SRS_Req_yes1", "SRS_Req_yes2"] + expect(v["Heading"]["no"]).to match_array [] + expect(v["Heading"]["not_set"]).to match_array [] + expect(v["Second Document"]["all"]).to match_array ["SRS_Second_no2"] + expect(v["Second Document"]["yes"]).to match_array [] + expect(v["Second Document"]["no"]).to match_array ["SRS_Second_no2"] + expect(v["Second Document"]["not_set"]).to match_array [] + end + end + end + + context 'referenced/derived table' do + table_desc = "type = requirement / srs |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_ref_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_ref_none", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_ref_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_ref_empty", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be true + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_ref_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_ref_table", "report.html") + expect(data.tr_nodata?("Upstream and Downstream")).to be false + expect(data.tr_desc("Upstream and Downstream")).to include table_desc + + v = data.tr_values("Upstream and Downstream") + + expect(v["TOTAL"]["all"]).to match_array ["SRS_Req_deref1", "SRS_Req_refderef1", "SRS_Req_refderef2", "SRS_Req_deref2", "SRS_Req_deref3", "SRS_Req_ref1"] + expect(v["TOTAL"]["Downstream Sufficient"]).to match_array ["SRS_Req_deref1", "SRS_Req_refderef1", "SRS_Req_refderef2", "SRS_Req_deref2", "SRS_Req_deref3"] + expect(v["TOTAL"]["Downstream Missing"]).to match_array ["SRS_Req_ref1"] + expect(v["TOTAL"]["Upstream Sufficient"]).to match_array ["SRS_Req_refderef1", "SRS_Req_refderef2", "SRS_Req_ref1"] + expect(v["TOTAL"]["Upstream Missing"]).to match_array ["SRS_Req_deref1", "SRS_Req_deref2", "SRS_Req_deref3"] + expect(v["Heading"]["all"]).to match_array ["SRS_Req_deref1", "SRS_Req_refderef2"] + expect(v["Heading"]["Downstream Sufficient"]).to match_array ["SRS_Req_deref1", "SRS_Req_refderef2"] + expect(v["Heading"]["Downstream Missing"]).to match_array [] + expect(v["Heading"]["Upstream Sufficient"]).to match_array ["SRS_Req_refderef2"] + expect(v["Heading"]["Upstream Missing"]).to match_array ["SRS_Req_deref1"] + expect(v["SRS_Req"]["all"]).to match_array ["SRS_Req_refderef1", "SRS_Req_deref2", "SRS_Req_deref3"] + expect(v["SRS_Req"]["Downstream Sufficient"]).to match_array ["SRS_Req_refderef1", "SRS_Req_deref2", "SRS_Req_deref3"] + expect(v["SRS_Req"]["Downstream Missing"]).to match_array [] + expect(v["SRS_Req"]["Upstream Sufficient"]).to match_array ["SRS_Req_refderef1"] + expect(v["SRS_Req"]["Upstream Missing"]).to match_array ["SRS_Req_deref2", "SRS_Req_deref3"] + expect(v["Second Document"]["all"]).to match_array ["SRS_Req_ref1"] + expect(v["Second Document"]["Downstream Sufficient"]).to match_array [] + expect(v["Second Document"]["Downstream Missing"]).to match_array ["SRS_Req_ref1"] + expect(v["Second Document"]["Upstream Sufficient"]).to match_array ["SRS_Req_ref1"] + expect(v["Second Document"]["Upstream Missing"]).to match_array [] + end + end + end + + context 'list of requirements' do + table_desc = "type = requirement / srs |br| developer = Abc AG |br| status = valid" + context 'with no data' do + before(:all) do + @test = Test.new("tr_software_list_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_ref_none", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be true + expect(data.tr_desc("List of Requirements")).to include table_desc + end + end + + context 'with all data filtered out' do + before(:all) do + @test = Test.new("tr_software_list_empty") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_ref_empty", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be true + expect(data.tr_desc("List of Requirements")).to include table_desc + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_software_list_table") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSoftware'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_software_list_table", "report.html") + expect(data.tr_nodata?("List of Requirements")).to be false + expect(data.tr_desc("List of Requirements")).to include table_desc + + v = data.tr_list("List of Requirements") + expect(v.length). to be 6 + + table = {"SRS_Req_deref1" => {"mod" => "Heading", "Downstream" => "SRS_Req_ref1, SRS_Req_refderef1, SRS_Req_refderef2", "Upstream" => "[missing]"}, + "SRS_Req_refderef1" => {"mod" => "SRS_Req", "Downstream" => "SRS_Req_refderef2", "Upstream" => "SRS_Req_deref1"}, + "SRS_Req_refderef2" => {"mod" => "Heading", "Downstream" => "SRS_Req_notset2", "Upstream" => "SRS_Req_deref1, SRS_Req_refderef1"}, + "SRS_Req_deref2" => {"mod" => "SRS_Req", "Downstream" => "-", "Upstream" => "[missing]"}, + "SRS_Req_deref3" => {"mod" => "SRS_Req", "Downstream" => "SRS_Req_notset2, index.rst, second.rst", "Upstream" => "[missing]"}, + "SRS_Req_ref1" => {"mod" => "Second Document", "Downstream" => "[missing]", "Upstream" => "SRS_Req_deref1"}} + v.each do |content| + t = table[content["ID"]] + expect(content["mod"]).to eq t["mod"] + expect(content["Downstream"]).to eq t["Downstream"] + expect(content["Upstream"]).to eq t["Upstream"] + end + end + end + end + + end +end diff --git a/dox_trace/spec/tr_source_spec.rb b/dox_trace/spec/tr_source_spec.rb new file mode 100644 index 0000000..df90071 --- /dev/null +++ b/dox_trace/spec/tr_source_spec.rb @@ -0,0 +1,41 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The traceability report for source" do + + context 'with no data' do + before(:all) do + @test = Test.new("tr_source_none") + @test.run + end + it 'shall display an appropriate note instead of an empty table', doc_refs: ['DoxTrace_HTML_TraceabilityReportSource'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_source_none", "report.html") + expect(data.tr_nodata?("Sources")).to be true + end + end + + context 'with valid data' do + before(:all) do + @test = Test.new("tr_source_list") + @test.run + end + it 'shall contain correct data with module/value pairs including TOTAL and links', doc_refs: ['DoxTrace_HTML_TraceabilityReportSource'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("tr_source_list", "report.html") + + sources = data.tr_getSection("Sources") + list = {} + bullets = sources.split("
  • ")[1..-1] + bullets.each do |b| + filtered = b.gsub(/<.*?>/, "").strip.split("\n") + list[filtered[0]] = filtered[1].split(", ") + end + + expect(list["index.rst"]).to match_array ["SMD_Req_deref2", "SMD_Req_deref3"] + expect(list["second.rst"]).to match_array ["SMD_Req_deref2"] + end + end + + end +end diff --git a/dox_trace/spec/undefined_refs_spec.rb b/dox_trace/spec/undefined_refs_spec.rb new file mode 100644 index 0000000..39ba1e7 --- /dev/null +++ b/dox_trace/spec/undefined_refs_spec.rb @@ -0,0 +1,36 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The directive undefined_refs" do + context 'for specifications with undefined references' do + before(:all) do + @test = Test.new("undefined_refs_list") + @test.run + end + + it 'shall generate a list of specifications including their undefined references', doc_refs: ['DoxTrace_HTML_UndefinedRefsListDirective'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("undefined_refs_list", "undefined_refs.html") + + expect(data.html).to match(/#swa_spec_1.*SWA_Spec_1.*SWA_Spec_100, BLAH, FASEL/m) + expect(data.html).to match(/#swa_spec_2.*SWA_Spec_2.*BLAH/m) + expect(data.html).to match(/#swa_spec_3.*SWA_Spec_3.*FASEL/m) + end + end + + context 'for specifications without undefined references' do + before(:all) do + @test = Test.new("undefined_refs_empty") + @test.run + end + + it 'shall generate a helper note that no undefined references exist', doc_refs: ['DoxTrace_HTML_UndefinedRefsListDirective'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("undefined_refs_empty", "undefined_refs.html") + + expect(data.html).to match(/No undefined references found./m) + end + end + + end +end diff --git a/dox_trace/spec/upstream_references_spec.rb b/dox_trace/spec/upstream_references_spec.rb new file mode 100644 index 0000000..027ed52 --- /dev/null +++ b/dox_trace/spec/upstream_references_spec.rb @@ -0,0 +1,49 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The calculated attribute Upstream References" do + context 'for specifications' do + before(:all) do + @test = Test.new("upstream_references") + @test.run + end + + it 'shall be displayed correctly without any error', doc_refs: ['DoxTrace_HTML_UpstreamRefs'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("upstream_references", "index.html") + + expect(data.value("SRS_Requirement_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("SRS_Information_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("InputRequirement_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("InputInformation_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("SRS_Srs_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("SWA_Spec_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("SMD_Unit_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + expect(data.value("SWA_Interface_BackwardRefsShown", "Upstream References")).to eq '#inputrequirement_parent' + + expect(data.value("SMD_Unit_All", "Upstream References")).to eq [ + "#srs_requirement_ref", "#srs_information_ref", "#inputrequirement_ref", "#inputinformation_ref", + "#srs_srs_ref", "#swa_spec_ref", "#smd_unit_ref", "#swa_interface_ref"].sort.join(", ") + + expect(data.value("SWA_Spec_Unique", "Upstream References")).to eq ["#swa_interface_uniqueparent", "#swa_spec_uniqueparent"].sort.join(", ") + + expect(data.value("SWA_Spec_RoundTrip", "Upstream References")).to eq '[missing]' + expect(data.value("SMD_Spec_RoundTrip", "Upstream References")).to eq '#swa_spec_roundtrip' + + expect(data.value("SRS_Requirement_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SRS_Information_RefsDefault", "Upstream References")).to eq '-' + expect(data.value("InputRequirement_RefsDefault", "Upstream References")).to eq '-' + expect(data.value("InputInformation_RefsDefault", "Upstream References")).to eq '-' + expect(data.value("SRS_Srs_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SWA_Mod_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SWA_Spec_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SMD_Unit_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SWA_Interface_RefsDefault", "Upstream References")).to eq '[missing]' + expect(data.value("SMD_Interface_RefsDefault", "Upstream References")).to eq '[missing]' + + expect(data.value("SRS_Srs_Tool", "Upstream References")).to eq '-' + expect(data.value("SRS_srs_Invalid", "Upstream References")).to eq '-' + end + end + end +end diff --git a/dox_trace/spec/usage_spec.rb b/dox_trace/spec/usage_spec.rb new file mode 100644 index 0000000..823c02f --- /dev/null +++ b/dox_trace/spec/usage_spec.rb @@ -0,0 +1,103 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute usage" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("usage") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_Usage', 'DoxTrace_HTML_Usage'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("usage", "index.html") + + expect(data.value("SWA_Mod_UsageEmpty", "usage")).to eq '-' + expect(data.value("SWA_Mod_UsageDev", "usage")).to eq 'Dev' + end + + it 'shall not be exported', doc_refs: ['DoxTrace_Export_Usage'] do + dim = File.read("#{$test_input_dir}/usage/export_root/swa/index.dim") + expect(dim).not_to match(/reuse/) + end + end + + context 'specified in a requirement directive' do + before(:all) do + @test = Test.new("usage_requirement") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "requirement" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + + context 'specified in a information directive' do + before(:all) do + @test = Test.new("usage_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + + context 'specified in a spec directive' do + before(:all) do + @test = Test.new("usage_spec") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "spec" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + + context 'specified in a unit directive' do + before(:all) do + @test = Test.new("usage_unit") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "unit" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + + context 'specified in a interface directive' do + before(:all) do + @test = Test.new("usage_interface") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "interface" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + + context 'specified in a srs directive' do + before(:all) do + @test = Test.new("usage_srs") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_Usage'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "srs" directive' + expect(@test.test_stderr).to include 'unknown option: "usage"' + end + end + end +end diff --git a/dox_trace/spec/verification_criteria_spec.rb b/dox_trace/spec/verification_criteria_spec.rb new file mode 100644 index 0000000..3145216 --- /dev/null +++ b/dox_trace/spec/verification_criteria_spec.rb @@ -0,0 +1,90 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute verification_criteria" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("verification_criteria") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_VerificationCriteria', 'DoxTrace_HTML_VerificationCriteria'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("verification_criteria", "index.html") + + expect(data.value("SRS_Requirement_VcSet", "verification_criteria")).to eq 'Aa: #available!' + expect(data.value("InputRequirement_VcSet", "verification_criteria")).to eq 'Bb' + expect(data.value("SRS_Srs_VcSet", "verification_criteria")).to eq 'Aa: #available!' + expect(data.value("SWA_Spec_VcSet", "verification_criteria")).to eq 'Cc' + expect(data.value("SMD_Unit_VcSet", "verification_criteria")).to eq 'Hello
    world!' + expect(data.value("SWA_Interface_VcSet", "verification_criteria")).to eq 'Dd' + expect(data.exist?("SMD_Interface_VcSet", "verification_criteria")).to be false + + expect(data.value("SRS_Requirement_VcDefault", "verification_criteria")).to eq '[missing]' + expect(data.value("InputRequirement_VcDefault", "verification_criteria")).to eq '-' + expect(data.value("SRS_Srs_VcDefault", "verification_criteria")).to eq '[missing]' + expect(data.value("SWA_Spec_VcDefault", "verification_criteria")).to eq '-' + expect(data.value("SMD_Unit_VcDefault", "verification_criteria")).to eq '-' + expect(data.value("SWA_Interface_VcDefault", "verification_criteria")).to eq '-' + expect(data.exist?("SMD_Interface_VcDefault", "verification_criteria")).to be false + + expect(data.value("SRS_Requirement_VcDefaultTool", "verification_criteria")).to eq '-' + expect(data.value("SRS_Requirement_VcDefaultStruck", "verification_criteria")).to eq '-' + expect(data.value("SRS_Srs_VcDefaultTool", "verification_criteria")).to eq '-' + expect(data.value("SRS_Srs_VcDefaultStruck", "verification_criteria")).to eq '-' + + expect(data.value("SRS_Srs_VcEmpty", "verification_criteria")).to eq '[missing]' + expect(data.value("SRS_Requirement_VcEmptyRaw", "verification_criteria")).to eq '[missing]' + + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_VerificationCriteria', 'DoxTrace_Export_VerificationCriteria', 'DoxTrace_Export_Attributes'] do + srs = @test.dim_original_data["spec/test_input/verification_criteria/export_root/srs/index.dim"] + expect(srs["SRS_Srs_VcSet"]["verification_criteria"]).to eq 'See Sphinx documentation.' + expect(srs["SRS_Srs_VcDefault"]["verification_criteria"]).to eq '' + expect(srs["SRS_Srs_VcDefaultTool"]["verification_criteria"]).to eq '' + expect(srs["SRS_Srs_VcDefaultStruck"]["verification_criteria"]).to eq '' + expect(srs["SRS_Srs_VcEmpty"]["verification_criteria"]).to eq '' + + swa = @test.dim_original_data["spec/test_input/verification_criteria/export_root/swa/index.dim"] + expect(swa["SWA_Spec_VcSet"]["verification_criteria"]).to eq 'See Sphinx documentation.' + expect(swa["SWA_Interface_VcSet"]["verification_criteria"]).to eq 'See Sphinx documentation.' + expect(swa["SWA_Spec_VcDefault"]["verification_criteria"]).to eq '' + expect(swa["SWA_Interface_VcDefault"]["verification_criteria"]).to eq '' + + smd = @test.dim_original_data["spec/test_input/verification_criteria/export_root/smd/index.dim"] + expect(smd["SMD_Unit_VcSet"]["verification_criteria"]).to eq 'See Sphinx documentation.' + expect(smd["SMD_Interface_VcSet"]["verification_criteria"]).to eq nil + expect(smd["SMD_Unit_VcDefault"]["verification_criteria"]).to eq '' + expect(smd["SMD_Interface_VcDefault"]["verification_criteria"]).to eq nil + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("verification_criteria_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_VerificationCriteria'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "verification_criteria"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("verification_criteria_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_VerificationCriteria'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "verification_criteria"' + end + end + + end +end diff --git a/dox_trace/spec/verification_methods_spec.rb b/dox_trace/spec/verification_methods_spec.rb new file mode 100644 index 0000000..5df4452 --- /dev/null +++ b/dox_trace/spec/verification_methods_spec.rb @@ -0,0 +1,110 @@ +require_relative 'framework/helper' + +module Sphinx + describe "The attribute verification_methods" do + context 'with correct syntax' do + before(:all) do + @test = Test.new("verification_methods") + @test.run + end + + it 'shall be loaded and displayed correctly without any error', doc_refs: ['DoxTrace_Syntax_VerificationMethods', 'DoxTrace_HTML_VerificationMethods'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("verification_methods", "index.html") + + expect(data.value("SRS_Requirement_VerificationMethodsSet", "verification_methods")).to eq 'on_target, off_target' + expect(data.value("InputRequirement_VerificationMethodsSet", "verification_methods")).to eq 'manual' + expect(data.value("SRS_Srs_VerificationMethodsSet", "verification_methods")).to eq 'on_target, off_target' + expect(data.value("SWA_Spec_VerificationMethodsSet", "verification_methods")).to eq 'off_target, on_target' + expect(data.value("SMD_Unit_VerificationMethodsSet", "verification_methods")).to eq 'none' + expect(data.value("SWA_Interface_VerificationMethodsSet", "verification_methods")).to eq 'off_target' + expect(data.exist?("SMD_Interface_VerificationMethodsSet", "verification_methods")).to be false + + expect(data.value("SRS_Requirement_VerificationMethodsDefault", "verification_methods")).to eq '-' + expect(data.value("InputRequirement_VerificationMethodsDefault", "verification_methods")).to eq '-' + expect(data.value("SRS_Srs_VerificationMethodsDefault", "verification_methods")).to eq 'on_target' + expect(data.value("SWA_Spec_VerificationMethodsDefault", "verification_methods")).to eq 'on_target' + expect(data.value("SMD_Spec_VerificationMethodsDefault", "verification_methods")).to eq 'off_target' + expect(data.value("SMD_Unit_VerificationMethodsDefault", "verification_methods")).to eq 'off_target' + expect(data.value("SWA_Interface_VerificationMethodsDefault", "verification_methods")).to eq 'on_target' + + expect(data.exist?("SMD_Interface_VerificationMethodsDefault", "verification_methods")).to be false + expect(data.exist?("SWA_Mod_VerificationMethodsDefault", "verification_methods")).to be false + end + + it 'shall get the value from test_setups if verification_methods is not defined', doc_refs: ['DoxTrace_Syntax_TestSetupsToVerificationMethods', 'DoxTrace_HTML_VerificationMethods', 'DoxTrace_HTML_TestSetups'] do + expect(@test.exit_code).to be == 0 + data = HtmlData.new("verification_methods", "index.html") + + expect(data.value("SWA_Spec_VerificationMethodsBackward", "verification_methods")).to eq 'off_target, on_target' + expect(data.exist?("SWA_Spec_VerificationMethodsBackward", "test_setups")).to be false + expect(data.value("SWA_Spec_VerificationMethodsBackwardBoth", "verification_methods")).to eq 'manual' + expect(data.exist?("SWA_Spec_VerificationMethodsBackwardBoth", "test_setups")).to be false + end + + it 'shall be exported correctly', doc_refs: ['DoxTrace_Syntax_VerificationMethods', 'DoxTrace_Export_Attributes', 'DoxTrace_Export_VerificationMethods', 'DoxTrace_Export_TestSetups'] do + srs = @test.dim_original_data["spec/test_input/verification_methods/export_root/srs/index.dim"] + expect(srs["SRS_Srs_VerificationMethodsSet"]["verification_methods"]).to eq 'on_target, off_target' + expect(srs["SRS_Srs_VerificationMethodsDefault"]["verification_methods"]).to eq 'on_target' + + swa = @test.dim_original_data["spec/test_input/verification_methods/export_root/swa/index.dim"] + expect(swa["SWA_Spec_VerificationMethodsSet"]["verification_methods"]).to eq 'off_target, on_target' + expect(swa["SWA_Interface_VerificationMethodsSet"]["verification_methods"]).to eq 'off_target' + expect(swa["SWA_Spec_VerificationMethodsDefault"]["verification_methods"]).to eq 'on_target' + expect(swa["SWA_Interface_VerificationMethodsDefault"]["verification_methods"]).to eq 'on_target' + + expect(swa["SWA_Spec_VerificationMethodsBackward"]["verification_methods"]).to eq 'off_target, on_target' + expect(swa["SWA_Spec_VerificationMethodsBackwardBoth"]["verification_methods"]).to eq 'manual' + content = File.read("spec/test_input/verification_methods/export_root/swa/index.dim") + expect(content).not_to include "test_setups" + + smd = @test.dim_original_data["spec/test_input/verification_methods/export_root/smd/index.dim"] + expect(smd["SMD_Interface_VerificationMethodsSet"]["verification_methods"]).to eq 'none' + expect(smd["SMD_Unit_VerificationMethodsSet"]["verification_methods"]).to eq 'none' + expect(smd["SMD_Spec_VerificationMethodsDefault"]["verification_methods"]).to eq 'off_target' + expect(smd["SMD_Unit_VerificationMethodsDefault"]["verification_methods"]).to eq 'off_target' + expect(smd["SMD_Interface_VerificationMethodsDefault"]["verification_methods"]).to eq 'none' + end + end + + context 'specified in an interface directive' do + before(:all) do + @test = Test.new("verification_methods_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_VerificationMethods'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "verification_methods"' + end + end + + context 'specified in an information directive' do + before(:all) do + @test = Test.new("verification_methods_information") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_VerificationMethods'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "information" directive' + expect(@test.test_stderr).to include 'unknown option: "verification_methods"' + end + end + + context 'specified in an mod directive' do + before(:all) do + @test = Test.new("verification_methods_mod") + @test.run + end + + it 'shall cause dox_trace to abort with exit code != 0 and print an error message', doc_refs: ['DoxTrace_Syntax_VerificationMethods'] do + expect(@test.exit_code).to be > 0 + expect(@test.test_stderr).to include 'index.rst:7:Error in "mod" directive' + expect(@test.test_stderr).to include 'unknown option: "verification_methods"' + end + + end + end +end diff --git a/dox_trace/spec/zzz_dummy_spec.rb b/dox_trace/spec/zzz_dummy_spec.rb new file mode 100644 index 0000000..703149e --- /dev/null +++ b/dox_trace/spec/zzz_dummy_spec.rb @@ -0,0 +1,13 @@ +require_relative 'framework/helper' + +module Sphinx + +describe "LastTestReached" do + + it 'done', doc_refs: ["IGNORE"] do + # do nothing + end + +end + +end diff --git a/dox_util/LICENSE b/dox_util/LICENSE new file mode 100644 index 0000000..7a4a3ea --- /dev/null +++ b/dox_util/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/dox_util/MANIFEST.in b/dox_util/MANIFEST.in new file mode 100644 index 0000000..2107f77 --- /dev/null +++ b/dox_util/MANIFEST.in @@ -0,0 +1 @@ +exclude MANIFEST.in diff --git a/dox_util/README.md b/dox_util/README.md new file mode 100644 index 0000000..198278c --- /dev/null +++ b/dox_util/README.md @@ -0,0 +1,11 @@ +# Overview + +dox_util is a collection of small convenience-features for Sphinx documentations: + +- Makes links to external websites more convenient. +- Optimizes built-in linkcheck behaviour of Sphinx. +- Referenceable rules role. +- Several ways to link to source code. +- Tolerant toctree which ignores missing files and other useful directives. +- Light-weight todo role. +- Weak references which do not warn if labels do not exist. diff --git a/dox_util/documentation/.gitignore b/dox_util/documentation/.gitignore new file mode 100644 index 0000000..a9a1de9 --- /dev/null +++ b/dox_util/documentation/.gitignore @@ -0,0 +1,2 @@ +build +footer.yaml diff --git a/dox_util/documentation/Makefile b/dox_util/documentation/Makefile new file mode 100644 index 0000000..87a79a1 --- /dev/null +++ b/dox_util/documentation/Makefile @@ -0,0 +1,12 @@ +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" -W $(SPHINXOPTS) $(O) diff --git a/dox_util/documentation/footer.rb b/dox_util/documentation/footer.rb new file mode 100644 index 0000000..8317ef1 --- /dev/null +++ b/dox_util/documentation/footer.rb @@ -0,0 +1,24 @@ +require 'time' +require 'yaml' + +$stdout.sync = true + +def parseTime(time) + # input e.g.: 2022-12-24 11:59:59 +0100 + DateTime.parse(time).new_offset(0).strftime("%Y-%m-%d %H:%M:%S") +end + +data = {} +file_dir = File.dirname(__FILE__) +Dir.chdir(file_dir + "/..") do + branch = `git branch --show-current`.strip + remote = `git remote get-url origin`.strip.gsub(/\/\/.*@/, '//') # assuming origin + folder = `git rev-parse --show-prefix`.strip.gsub(/\/$/, '') + time_sha1 = `git log -n 1 --pretty="format:%cd|%h" --date=iso -- . 2>&1`.split("|") + time = parseTime(time_sha1[0]) + sha1 = time_sha1[1] + + data["."] = "Based on #{remote}, folder #{folder}, from #{time}, commit #{sha1}." +end + +File.write(file_dir + "/footer.yaml", data.to_yaml) diff --git a/dox_util/documentation/requirements.txt b/dox_util/documentation/requirements.txt new file mode 100644 index 0000000..d02595c --- /dev/null +++ b/dox_util/documentation/requirements.txt @@ -0,0 +1,9 @@ +Sphinx==7.2.6 +sphinx-rtd-theme==2.0.0 +sphinx-copybutton==0.5.2 +sphinxcontrib-jquery==4.1 +Pygments==2.17.2 +docutils==0.20.1 +PyYAML==6.0.1 +packaging==21.3 ; python_version < "3.11" +packaging==23.2 ; python_version >= "3.11" diff --git a/dox_util/documentation/source/conf.py b/dox_util/documentation/source/conf.py new file mode 100644 index 0000000..e51cb89 --- /dev/null +++ b/dox_util/documentation/source/conf.py @@ -0,0 +1,34 @@ +import sys +from pathlib import Path +from datetime import datetime + +EXTENSION_ROOT = Path("../../..") +sys.path = [str(path.resolve()) for path in EXTENSION_ROOT.glob("dox_*")] + sys.path + +project = "dox_util" +author = "Accenture" +copyright = ( + f"{datetime.now().year} Accenture. All rights reserved. " + f"Accenture proprietary and confidential material" +) + +global __version__ +exec(open(f"../../{project}/version.py", "r").read(), globals()) +version = __version__ + +html_context = {"document_status_default": "Released", "data_classification_default": None} + +extensions = [ + "sphinxcontrib.jquery", + "sphinx.ext.extlinks", + "sphinx.ext.todo", + "dox_style", + "dox_util", +] + + +extlinks = {"website": ("https://accenture.com/%s", None), "other_doc": ("../../other/%s", None)} + +todo_include_todos = True + +dox_style_footer = "footer.yaml" diff --git a/dox_util/documentation/source/index.rst b/dox_util/documentation/source/index.rst new file mode 100644 index 0000000..7bafebf --- /dev/null +++ b/dox_util/documentation/source/index.rst @@ -0,0 +1,48 @@ +.. _dox_util: + +dox_util +======== + +Collection of small convenience features for Sphinx documentations. + +.. list-table:: + :widths: 30 70 + :header-rows: 1 + :width: 100% + + * - Name + - Description + * - :doc:`pages/user/extlinks` + - Makes links to external websites more convenient. + * - :doc:`pages/user/linkcheck` + - Optimizes built-in linkcheck behaviour of Sphinx. + * - :doc:`pages/user/rule` + - Referenceable rules role. + * - :doc:`pages/user/source` + - Several ways to link to source code. + * - :doc:`pages/user/toctree` + - Tolerant toctree which ignores missing files and other useful directives. + * - :doc:`pages/user/todo` + - Light-weight todo role. + * - :doc:`pages/user/weak` + - Weak references which do not warn if labels do not exist. + +.. toctree:: + :maxdepth: 1 + :caption: User Documentation + :hidden: + + pages/user/extlinks + pages/user/linkcheck + pages/user/rule + pages/user/source + pages/user/toctree + pages/user/todo + pages/user/weak + +.. toctree:: + :maxdepth: 1 + :caption: Appendix + :hidden: + + pages/appendix/changelog diff --git a/dox_util/documentation/source/pages/appendix/changelog.rst b/dox_util/documentation/source/pages/appendix/changelog.rst new file mode 100644 index 0000000..4c4de50 --- /dev/null +++ b/dox_util/documentation/source/pages/appendix/changelog.rst @@ -0,0 +1,9 @@ +Changelog +========= + +0.1.0 +----- + +October 23, 2024 + +- Initial public release. diff --git a/dox_util/documentation/source/pages/user/extlinks.rst b/dox_util/documentation/source/pages/user/extlinks.rst new file mode 100644 index 0000000..2a58a9a --- /dev/null +++ b/dox_util/documentation/source/pages/user/extlinks.rst @@ -0,0 +1,63 @@ +extlinks +======== + +The ``sphinx.ext.extlinks`` third party extension provides base paths for external links. +These base paths are set up once in conf.py and can be used from the rst files. + +With ``dox_util`` it is possible to specify relative paths based on the root of the +documentation (in the *Makefile* usually called *SOURCE*). + +Example: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - html + - conf.py / rst + * - Accenture :website:`careers `. + + See also :other_doc:`some/folder`. + + See also :other_doc:`other doc `. + - .. code-block:: rst + + # conf.py + + extensions = [ + ... + 'sphinx.ext.extlinks', + 'dox_util' + ] + + extlinks = {'website' ('https://accenture.com/%s', None), + 'other_doc': ('../../other/%s', None)} + + # RST file + + Accenture :website:`careers `. + + See also :other_doc:`some/folder`. + + See also :other_doc:`other doc `. + +It's a good practice to use the *replace* directive provided by Sphinx. + +Example: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - html + - rst + * - Accenture |careers|. + + .. |careers| replace:: :website:`careers ` + - .. code-block:: rst + + # very readable text + Accenture |careers|. + + # usually defined at the bottom of the document + .. |careers| replace:: :website:`careers ` diff --git a/dox_util/documentation/source/pages/user/linkcheck.rst b/dox_util/documentation/source/pages/user/linkcheck.rst new file mode 100644 index 0000000..7b9641c --- /dev/null +++ b/dox_util/documentation/source/pages/user/linkcheck.rst @@ -0,0 +1,11 @@ +linkcheck +========= + +This extension overwrites the standard behaviour of the built-in linkcheck of Sphinx. + +Sphinx documentations can include links to services which require a login. If not logged in, the +HTML error code is 403. + +*linkcheck* ignores 403 instead of treating this as an error, which means everyone can build the +documentation even without having access to these services or when the systems are down. +The small acceptable drawback is that when not logged in, the links are not validated. diff --git a/dox_util/documentation/source/pages/user/rule.rst b/dox_util/documentation/source/pages/user/rule.rst new file mode 100644 index 0000000..0c176a5 --- /dev/null +++ b/dox_util/documentation/source/pages/user/rule.rst @@ -0,0 +1,32 @@ +rule +==== + +The *rule* role highlights a rule and provides a unique ID, which can be referenced within the +documentation. + +Example: + +.. list-table:: + :widths: 50 50 + :width: 100% + :header-rows: 1 + + * - html + - rst + * - :rule:`CodingConvention-Naming-Class` + Class names must be written in ``CamelCase``. + - .. code-block:: rst + + :rule:`CodingConvention-Naming-Class` + Class names must be written in ``CamelCase``. + * - This rule can be referenced like this: + :ref:`CodingConvention-Naming-Class`. + - .. code-block:: rst + + This rule can be referenced like this: + :ref:`CodingConvention-Naming-Class`. + +When exporting to HTML, anchors are created which can be used to reference these rules from a code +review tool. A rule refers to itself, which makes it easy to copy/paste the link. + +Naming convention for the IDs: ``-[-]`` diff --git a/dox_util/documentation/source/pages/user/source.rst b/dox_util/documentation/source/pages/user/source.rst new file mode 100644 index 0000000..91c79a1 --- /dev/null +++ b/dox_util/documentation/source/pages/user/source.rst @@ -0,0 +1,58 @@ +source +====== + +``dox_util`` provides several ways to reference source code. + +Including a Source File +----------------------- + +The Sphinx built-in ``literalinclude`` has an unpleasant downside. The path in RST and therefore in +HTML is relative to the rst-file, so typically some ".." are included. + +With ``sourceinclude`` from this extension it is possible to specify files relative from the folder +above *doc*. + +Comparison example: + +.. code-block:: + + /doc/sub/page.rst + /include/mod/example.h + +.. code-block:: rst + + .. literalinclude:: ../../include/mod/example.h + :start-after: MARKER1 + :end-before: MARKER2 + :language: c++ + :dedent: 4 + :caption: + + .. sourceinclude:: include/mod/example.h + :start-after: MARKER1 + :end-before: MARKER2 + :language: c++ + :dedent: 4 + :caption: + +In case no *doc* folder is in the path between Sphinx root and the rst-file, the source file can +also be specified relative to the rst-file. + +Referencing a Source File +------------------------- + +To simply reference a source file use ``:source:````. +The result will be a highlighted string, not a clickable reference. +The path is relative to the module root, similar to ``sourceinclude``. +This role checks for **existence** of the file. In case the file does not exist, an error is +returned. + +| Example: +| ``:source:`source/include/MemoryManager.h``` results in :source:`source/include/MemoryManager.h`. + + +Note, that Sphinx has a built-in type ``:file:``. It does *no* existence check and it is relative to +the rst-file. + +| Example: +| ``:file:`source/include/DoesNotExist.h``` results in :file:`source/include/DoesNotExist.h`. diff --git a/dox_util/documentation/source/pages/user/source/include/MemoryManager.h b/dox_util/documentation/source/pages/user/source/include/MemoryManager.h new file mode 100644 index 0000000..7bfff5c --- /dev/null +++ b/dox_util/documentation/source/pages/user/source/include/MemoryManager.h @@ -0,0 +1 @@ +// intended to be empty diff --git a/dox_util/documentation/source/pages/user/toctree.rst b/dox_util/documentation/source/pages/user/toctree.rst new file mode 100644 index 0000000..c41d8e9 --- /dev/null +++ b/dox_util/documentation/source/pages/user/toctree.rst @@ -0,0 +1,88 @@ +toctree +======= + +.. _tolerant-toctree: + +tolerant-toctree +---------------- + +The ``tolerant-toctree`` directive works the same as the regular ``toctree`` +directive except that non-existing files will not result in a warning. + +| Glob pattern ``*`` and ``?`` are supported, e.g. *toctree/example\**. +| If no file is found, the toctree is not rendered. + +It's used when files are generated and/or are not always there. + +Example: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - html + - rst + * - .. tolerant-toctree:: + :caption: Tree 1 + :glob: + + toctree/example1 + toctree/*2 + toctree/example3 + + .. tolerant-toctree:: + :caption: Tree 2 + :glob: + + toctree/doesNot*Exist + toctree/sameHere + + - .. code-block:: rst + + .. tolerant-toctree:: + :caption: Tree 1 + :glob: + + toctree/example1 + toctree/*2 + toctree/example3 + + .. tolerant-toctree:: + :caption: Tree 2 + :glob: + + toctree/doesNot*Exist + toctree/sameHere + +| *toctree/example3* does not exist, so this entry will be ignored. +| *Tree 2* is completely hidden because no files are found. + +doclist +------- + +| The ``doctree`` directive creates a flat bullet list of doc-links. + The same glob pattern as for ``toctree`` are supported. +| It has no options. + + +Example: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - html + - rst + * - .. doclist:: + + toctree/example1 + toctree/example2 + * + + - .. code-block:: rst + + .. doclist:: + + toctree/example1 + toctree/example2 + * diff --git a/dox_util/documentation/source/pages/user/toctree/example1.rst b/dox_util/documentation/source/pages/user/toctree/example1.rst new file mode 100644 index 0000000..bf47f3b --- /dev/null +++ b/dox_util/documentation/source/pages/user/toctree/example1.rst @@ -0,0 +1,4 @@ +Example 1 +========= + +Intended to be empty. diff --git a/dox_util/documentation/source/pages/user/toctree/example2.rst b/dox_util/documentation/source/pages/user/toctree/example2.rst new file mode 100644 index 0000000..53a0e4e --- /dev/null +++ b/dox_util/documentation/source/pages/user/toctree/example2.rst @@ -0,0 +1,4 @@ +Example 2 +========= + +Intended to be empty. diff --git a/dox_util/documentation/source/pages/user/todo.rst b/dox_util/documentation/source/pages/user/todo.rst new file mode 100644 index 0000000..908a8f9 --- /dev/null +++ b/dox_util/documentation/source/pages/user/todo.rst @@ -0,0 +1,30 @@ +todo +==== + +These are several possibilities to document a todo: + +- Explain what needs to be be done by using simple text. +- An *invisible* comment for the maintainers of the documentation. +- The third party ``sphinx.ext.todo`` directive: + + .. todo:: + + It adds an intrusive todo-box for each todo. Use it with care to avoid noise in the + documentation. +- The ``:todo:`` role from this extension for a short text like a single word. + The todo-keyword is not visible, but you can still search for "todo" in the sources of the + documentation. + + Example: + + .. list-table:: + :widths: 50 50 + :width: 100% + :header-rows: 1 + + * - html + - rst + * - :ref:`dox_util` and :todo:`another extension`. + - .. code-block:: rst + + :ref:`dox_util` and :todo:`another extension`. diff --git a/dox_util/documentation/source/pages/user/weak.rst b/dox_util/documentation/source/pages/user/weak.rst new file mode 100644 index 0000000..d790593 --- /dev/null +++ b/dox_util/documentation/source/pages/user/weak.rst @@ -0,0 +1,41 @@ +weak +==== + +*Sphinx* is based on *docutils*. In *docutils* it's up to the user to decide whether a missing label +shall result in a warning or not. *Sphinx* does not support this feature. + +This extension provides references which behave like regular references but by default missing +labels are ignored: + +.. list-table:: + :widths: 50 50 + :header-rows: 1 + + * - rst + - html + * - + - :weakref:`refDoesNotExist` + - :weakref:`dox_util` + - :weakref:`this extension ` + + - .. code-block:: rst + + - :weakref:`refDoesNotExist` + - :weakref:`dox_util` + - :weakref:`this extension ` + * - + - :weakdoc:`docDoesNotExist` + - :weakdoc:`../../index` + - :weakdoc:`this extension <../../index>` + + - .. code-block:: rst + + - :weakdoc:`docDoesNotExist` + - :weakdoc:`../../index` + - :weakdoc:`this extension <../../index>` + +To globally re-enable the warnings, add the following line to ``conf.py``: + +.. code-block:: python + + enable_weak_warnings = True diff --git a/dox_util/dox_util/__init__.py b/dox_util/dox_util/__init__.py new file mode 100644 index 0000000..6ae3e29 --- /dev/null +++ b/dox_util/dox_util/__init__.py @@ -0,0 +1,52 @@ +from .extlinks import * +from .linkcheck import * +from .rule import * +from .source import * +from .toctree import * +from .todo import * +from .weak import * +from .version import __version__ + +from pathlib import Path + + +def config_inited(app, config): + static = Path.joinpath(Path(__file__).parent, "_static").as_posix() + config.html_static_path.append(static) + app.add_css_file("dox_util_colors.css") + + +def setup(app): + # extlinks + app.connect("builder-inited", setup_link_roles) + + # linkcheck + app.add_builder(builder=LinkChecker, override=True) + + # rule + app.add_role("rule", rule_role) + + # source + app.add_role("source", source_role) + app.add_directive("sourceinclude", SourceInclude) + + # toctree + app.add_directive("tolerant-toctree", TolerantTocTree) + app.add_directive("doclist", DocList) + + # todo + app.add_role("todo", todo_role) + + # weak + app.add_role("weakref", weak_role) + app.add_role("weakdoc", weak_role) + app.add_config_value("enable_weak_warnings", False, "html") + + # common CSS definitions + app.connect("config-inited", config_inited) + + return { + "version": __version__, + "parallel_read_safe": True, + "parallel_write_safe": True, + } diff --git a/dox_util/dox_util/_static/dox_util_colors.css b/dox_util/dox_util/_static/dox_util_colors.css new file mode 100644 index 0000000..5965b05 --- /dev/null +++ b/dox_util/dox_util/_static/dox_util_colors.css @@ -0,0 +1,3 @@ +.literal.highlight.highlight-source { background: #FFFFFF; color:mediumpurple; } +.literal.highlight.highlight-todo { background: #FFFFFF; color:red; } +.literal.highlight.highlight-rule { background: #FFFFFF; color:blue; font-weight: bold; } diff --git a/dox_util/dox_util/extlinks.py b/dox_util/dox_util/extlinks.py new file mode 100644 index 0000000..d6b84ea --- /dev/null +++ b/dox_util/dox_util/extlinks.py @@ -0,0 +1,31 @@ +import os +from sphinx.util.nodes import split_explicit_title +from docutils import nodes, utils + + +def make_link_role(_name: str, base_url: str, caption: str): + def role(_role, _rawtext, text, _lineno, inliner, _options={}, _content=[]): + text = utils.unescape(text) + has_explicit_title, title, part = split_explicit_title(text) + if base_url.startswith(".."): + doc = os.path.dirname(inliner.document.current_source) + src = inliner.document.settings.env.app.srcdir + to_src = os.path.relpath(src, doc) + full_url = os.path.join(str(to_src), base_url % part).replace("\\", "/") + else: + full_url = base_url % part + if not has_explicit_title: + if caption is None: + title = full_url + else: + title = caption % part + ref_node = nodes.reference(title, title, internal=False, refuri=full_url) + return [ref_node], [] + + return role + + +def setup_link_roles(app): + if "extlinks" in app.config: + for name, (base_url, caption) in app.config.extlinks.items(): + app.add_role(name, make_link_role(name, base_url, caption), override=True) diff --git a/dox_util/dox_util/linkcheck.py b/dox_util/dox_util/linkcheck.py new file mode 100644 index 0000000..c814030 --- /dev/null +++ b/dox_util/dox_util/linkcheck.py @@ -0,0 +1,11 @@ +from sphinx.builders.linkcheck import CheckExternalLinksBuilder + + +# Get rid of warnings when not logged into a web service +class LinkChecker(CheckExternalLinksBuilder): + def process_result(self, result): + if result.status == "broken" and "403" in result.message: + result = result._replace(status="working") + self._broken.pop(result.uri) + self._good.add(result.uri) + super().process_result(result) diff --git a/dox_util/dox_util/rule.py b/dox_util/dox_util/rule.py new file mode 100644 index 0000000..20a91b2 --- /dev/null +++ b/dox_util/dox_util/rule.py @@ -0,0 +1,32 @@ +import re +from docutils import nodes +from sphinx.util import logging + +logger = logging.getLogger(__name__) + +rule_pattern = re.compile(r"^[^-\s]+-[^-\s]+(-[^-\s]+|)$") + + +def rule_role(_role, rawtext, text, lineno, inliner, _options={}, _content=[]): + env = inliner.document.settings.env + rule_id = text.lower() + + if not rule_pattern.match(text): + logger.warning("%s.rst:%d: Invalid rule pattern %s" % (env.docname, lineno, text)) + + if rule_id in env.domaindata["std"]["anonlabels"] or rule_id in env.domaindata["std"]["labels"]: + raise ValueError("Rule %s found twice" % rule_id) + + # make node referencable + env.domaindata["std"]["anonlabels"][rule_id] = env.docname, rule_id + env.domaindata["std"]["labels"][rule_id] = env.docname, rule_id, text + + node = nodes.literal(rawtext, "[rule] ") + node.set_class("highlight") + node.set_class("highlight-rule") + + self_ref = nodes.reference(text, text, refdocname=env.docname, refid=rule_id) + node.append(self_ref) + + target_node = nodes.target("", "", node, ids=[rule_id]) + return [target_node], [] diff --git a/dox_util/dox_util/source.py b/dox_util/dox_util/source.py new file mode 100644 index 0000000..d743522 --- /dev/null +++ b/dox_util/dox_util/source.py @@ -0,0 +1,41 @@ +from docutils import nodes +import os.path +from sphinx.directives.code import LiteralInclude + +from sphinx.util import logging + +logger = logging.getLogger(__name__) + + +def source_role(_role, rawtext, text, lineno, inliner, _options={}, _content=[]): + rst_file = inliner.document.settings.env.docname + split_rst_file = rst_file.replace("\\", "/").split("/doc/") + file = None + if len(split_rst_file) > 1: # source referenced from regular module + path2mod = "../" * (split_rst_file[-1].count("/") + 1) + file = os.path.join(os.path.dirname(inliner.document.current_source), path2mod + text) + if not file or not os.path.isfile(str(file)): # fallback for non-standard modules + file = os.path.join(os.path.dirname(inliner.document.current_source), text) + if not os.path.isfile(str(file)): + logger.error( + '%s.rst:%d: file "%s" not found' % (inliner.document.settings.env.docname, lineno, text) + ) + + node = nodes.literal(rawtext, text) + node.set_class("highlight") + node.set_class("highlight-source") + + return [node], [] + + +class SourceInclude(LiteralInclude): + def run(self): + if "caption" in self.options and not self.options["caption"]: + self.options["caption"] = self.arguments[0] + + split_docname = self.env.docname.replace("\\", "/").split("/doc/") + if len(split_docname) > 1: + path2mod = "../" * (split_docname[-1].count("/") + 1) + self.arguments[0] = path2mod + self.arguments[0] + + return super().run() diff --git a/dox_util/dox_util/toctree.py b/dox_util/dox_util/toctree.py new file mode 100644 index 0000000..184bba0 --- /dev/null +++ b/dox_util/dox_util/toctree.py @@ -0,0 +1,77 @@ +import re +import os + +from sphinx.directives.other import TocTree +from sphinx.util import docname_join +from sphinx.util.matching import patfilter + +from sphinx.util.docutils import SphinxDirective +from docutils import nodes +from docutils.statemachine import ViewList + +from typing import List + +glob_re = re.compile(r".*[*?\[].*") + + +class TolerantTocTree(TocTree): + content: List[str] + + def run(self): + new_content = [] + all_docnames = self.env.found_docs.copy() + all_docnames.remove(self.env.docname) + + for entry in self.content: + patname = docname_join(self.env.docname, entry) + if patname in all_docnames: + new_content.append(entry) + elif "glob" in self.options and glob_re.match(entry): + if len(patfilter(all_docnames, patname)) > 0: + new_content.append(entry) + self.content = new_content + return super().run() + + +class DocList(SphinxDirective): + has_content = True + required_arguments = 0 + optional_arguments = 0 + + def run(self): + all_docnames = self.env.found_docs.copy() + filename = self.get_source_info()[0] + line_number = self.get_source_info()[1] + + docs = [] + for entry in self.content: + if not entry: + continue + if glob_re.match(entry): + patname = docname_join(self.env.docname, entry) + docnames = sorted(patfilter(all_docnames, patname)) + docs.extend(docnames) + if not docnames: + raise AttributeError( + "%s.rst:%d: doclist glob pattern %r didn't match any documents" + % (self.env.docname, line_number, entry) + ) + else: + docs.append(docname_join(self.env.docname, entry)) + + rst = ViewList() + for docname in docs: + dir_docname = os.path.dirname(self.env.docname) + rel_docname = os.path.relpath(docname, dir_docname).replace("\\", "/") + entry = f"- :doc:`{rel_docname}`" + rst.append(entry, filename, line_number) + + node = nodes.section() + node.document = self.state.document + self.state.nested_parse(rst, 0, node) + + for generated_node in node.traverse(): + generated_node.source = self.env.docname + ".rst" + generated_node.line = line_number + + return node.children diff --git a/dox_util/dox_util/todo.py b/dox_util/dox_util/todo.py new file mode 100644 index 0000000..7eb1743 --- /dev/null +++ b/dox_util/dox_util/todo.py @@ -0,0 +1,8 @@ +from docutils import nodes + + +def todo_role(_role, rawtext, text, _lineno, _inliner, _options={}, _content=[]): + node = nodes.literal(rawtext, text) + node.set_class("highlight") + node.set_class("highlight-todo") + return [node], [] diff --git a/dox_util/dox_util/version.py b/dox_util/dox_util/version.py new file mode 100644 index 0000000..3dc1f76 --- /dev/null +++ b/dox_util/dox_util/version.py @@ -0,0 +1 @@ +__version__ = "0.1.0" diff --git a/dox_util/dox_util/weak.py b/dox_util/dox_util/weak.py new file mode 100644 index 0000000..27faf28 --- /dev/null +++ b/dox_util/dox_util/weak.py @@ -0,0 +1,34 @@ +import re + +from docutils import nodes +from sphinx import addnodes +from sphinx.util import logging + +logger = logging.getLogger(__name__) +weakref_pattern = re.compile("^([^<]+)(<([^>]+)>|)$") + + +def weak_role(role, _rawtext, text, lineno, inliner, _options={}, _content=[]): + text = text.strip() + ref = weakref_pattern.findall(text) + if len(ref) == 0: + logger.warning( + "%s.rst:%d: invalid ref pattern %s" + % (inliner.document.settings.env.docname, lineno, text) + ) + + ref_text = ref[0][0].strip() + explicit = ref[0][1] != "" + target = ref[0][2].strip() if explicit else ref_text + + ref_node = addnodes.pending_xref( + "", + refdomain="std", + refexplicit=explicit, + reftarget=target.lower(), + reftype="ref" if role == "weakref" else "doc", + refwarn=inliner.document.settings.env.app.config.enable_weak_warnings, + ) + + ref_node += nodes.Text(ref_text) + return [ref_node], [] diff --git a/dox_util/pyproject.toml b/dox_util/pyproject.toml new file mode 100644 index 0000000..c546732 --- /dev/null +++ b/dox_util/pyproject.toml @@ -0,0 +1,28 @@ +[build-system] +requires = ["setuptools >= 70.0.0"] +build-backend = "setuptools.build_meta" + +[project] +name = "dox_util" +dynamic = ["version"] +authors = [ + { name="Accenture" }, +] +description = "Collection of small convenience-features for Sphinx documentations." +readme = "README.md" +requires-python = ">=3.8" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", +] +license = {text = "Apache-2.0"} + +[project.urls] +Homepage = "https://github.com/esrlabs/dox" +Issues = "https://github.com/esrlabs/dox/issues" + +[tool.setuptools] +license-files = ["LICENSE"] +dynamic.version = {attr = "dox_util.version.__version__"} +package-data."*" = ['_static/*', "LICENSE"] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..aa4949a --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,2 @@ +[tool.black] +line-length = 100
  • \s*\[missing\]\s*<\/p><\/td><\/tr>/m, "") + data.html.gsub!(/