Skip to content

Commit

Permalink
Merge pull request #51 from ouhammmourachid/add-requirement-diagram
Browse files Browse the repository at this point in the history
add requiremnt with enumration for types and verificationmethod and risk
  • Loading branch information
ouhammmourachid authored Nov 9, 2023
2 parents f5d7511 + 92fe0dd commit 1c05fd0
Show file tree
Hide file tree
Showing 9 changed files with 224 additions and 3 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.2.2
current_version = 0.2.3
config_newlines = None
commit = True
tag = True
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,16 +42,23 @@ graph TD;
clas(ClassDiagram)
gra(Graph)
erDigram(ERDiagram)
pie(PieDiagram)
reqDiagram(RequiremntDiagram)
erdiagram-link(Link)
entity(Entity)
flow-link(Link)
node(Node)
requiremnt(Requiremnt)
element(Element)
mer --> flow
mer --> clas
mer --> gra
mer --> erDigram
mer --> pie
mer --> reqDiagram
flow --> node & flow-link
erDigram --> entity & erdiagram-link
reqDiagram --> requiremnt & element
```

## Technologies Used
Expand Down
2 changes: 1 addition & 1 deletion mermaid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
from ._main import Mermaid
from ._utils import load, text_to_snake_case

__version__: str = '0.2.2'
__version__: str = '0.2.3'
28 changes: 28 additions & 0 deletions mermaid/reqdiagram/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from mermaid.graph import Graph

from .element import *
from .link import *
from .requirement import *


class RequirementDiagram(Graph):
def __init__(self, title: str, elements: list[Element],
requirements: list[Requirement], links: list[Link]) -> None:
super().__init__(title, '')
self.elements: list[Element] = elements if elements is not None else []
self.requirements: list[
Requirement] = requirements if requirements is not None else []
self.links: list[Link] = links if links is not None else []
self._build_script()

def _build_script(self) -> None:
super()._build_script()
script: str = '\nrequirementDiagram\n'
for element in self.elements:
script += str(element) + '\n'
for requirement in self.requirements:
script += str(requirement) + '\n'

for link in self.links:
script += f'{link}\n'
self.script += script
18 changes: 18 additions & 0 deletions mermaid/reqdiagram/element.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from typing import Optional


class Element:
def __init__(self,
name: str,
type_: str,
docRef: Optional[str] = None) -> None:
self.name: str = name
self.type_: str = type_
self.docRef: Optional[str] = docRef

def __str__(self) -> str:
string: str = f'element {self.name} {{\n'
string += f'\ttype: "{self.type_}"\n'
string += f'\tdocRef: {self.docRef}\n' if self.docRef else ''
string += '}\n'
return string
15 changes: 15 additions & 0 deletions mermaid/reqdiagram/link.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import Union

from .element import Element
from .requirement import Requirement


class Link:
def __init__(self, source: Union[Element, Requirement],
destination: Union[Element, Requirement], type_: str) -> None:
self.source: Union[Element, Requirement] = source
self.destination: Union[Element, Requirement] = destination
self.type_: str = type_

def __str__(self) -> str:
return f'{self.source.name} - {self.type_} -> {self.destination.name}'
47 changes: 47 additions & 0 deletions mermaid/reqdiagram/requirement.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from enum import Enum
from typing import Union


class Risk(Enum):
LOW = 'Low'
MEDIUM = 'Medium'
HIGH = 'High'


class VerifyMethod(Enum):
ANALYSIS = 'Analysis'
INSPECTION = 'Inspection'
TEST = 'Test'
DEMONSTRATION = 'Demonstration'


class Type(Enum):
REQUIREMENT = 'requirement'
FUNCTIONAL = 'functionalRequirement'
INTERFACE = 'interfaceRequirement'
PERFORMANCE = 'performanceRequirement'
PHYSICAL = 'physicalRequirement'
DESIGN_CONSTRAINT = 'designConstraint'


class Requirement:
def __init__(self, id_: str, name: str, text: str, type_: Union[str, Type],
risk: Union[str, Risk],
verifymethod: Union[str, VerifyMethod]) -> None:
self.id_: str = id_
self.name: str = name
self.text: str = text
self.type_: str = type_ if isinstance(type_, str) else type_.value
self.risk: str = risk if isinstance(risk, str) else risk.value
self.verifymethod: str = verifymethod if isinstance(
verifymethod, str) else verifymethod.value

def __str__(self) -> str:
string: str = ''
string += f'{self.type_} {self.name} {{\n'
string += f'\tid: {self.id_}\n'
string += f'\ttext: {self.text}\n'
string += f'\trisk: {self.risk}\n'
string += f'\tverifymethod: {self.verifymethod}\n'
string += '}\n'
return string
106 changes: 106 additions & 0 deletions mermaid/tests/test_requirementdiagram.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import unittest
from unittest import mock

from mermaid.reqdiagram import Element, Link, Requirement, RequirementDiagram, Risk, Type, VerifyMethod


class TestRequirement(unittest.TestCase):
def test_create_requirement_with_str(self):
requirement = Requirement('1', 'test_req', 'the test text.',
'requirement', 'high', 'Test')
expect_str = """requirement test_req {
\tid: 1
\ttext: the test text.
\trisk: high
\tverifymethod: Test
}
"""
self.assertEqual(expect_str, str(requirement))

def test_create_requirement_with_enum(self):
requirement = Requirement('1', 'test_req', 'the test text.',
Type.INTERFACE, Risk.LOW,
VerifyMethod.ANALYSIS)
expect_str = """interfaceRequirement test_req {
\tid: 1
\ttext: the test text.
\trisk: Low
\tverifymethod: Analysis
}
"""
self.assertEqual(expect_str, str(requirement))


class TestElement(unittest.TestCase):
def test_element_with_docref(self):
element = Element('test_entity', 'simulation', '/test/test_....py')
expect_str = """element test_entity {
\ttype: "simulation"
\tdocRef: /test/test_....py
}
"""
self.assertEqual(expect_str, str(element))

def test_element_without_docref(self):
element = Element('test_entity', 'simulation')
expect_str = """element test_entity {
\ttype: "simulation"
}
"""
self.assertEqual(expect_str, str(element))


class TestLink(unittest.TestCase):
def test_string_link_with_element_requirement(self):
element = mock.Mock()
element.name = 'test_entity'
requirement = mock.Mock()
requirement.name = 'test_req'
link = Link(element, requirement, 'traces')
expect_str = 'test_entity - traces -> test_req'

self.assertEqual(expect_str, str(link))

def test_string_link_with_requirements(self):
requirement_1 = mock.Mock()
requirement_1.name = 'test_req'
requirement_2 = mock.Mock()
requirement_2.name = 'test_req2'
link = Link(requirement_1, requirement_2, 'contains')
expect_str = 'test_req - contains -> test_req2'

self.assertEqual(expect_str, str(link))


class TestRequirementDiagram(unittest.TestCase):
def test_script_diagram(self):
elements = [
Element('test_entity_1', 'simulation'),
Element('test_entity_2', 'simulation')
]
requirements = [
Requirement('1.1', 'test_req_1', 'the test text.', 'requirement',
'high', 'Test'),
Requirement('1.2', 'test_req_2', 'the test text.', 'requirement',
'high', 'Test')
]
links = [
Link(elements[0], requirements[0], 'traces'),
Link(elements[1], requirements[1], 'traces'),
Link(requirements[0], requirements[1], 'contains')
]
diagram = RequirementDiagram('simple requirement', elements,
requirements, links)
expect_str = f"""---
title: simple requirement
---
requirementDiagram
{elements[0]}
{elements[1]}
{requirements[0]}
{requirements[1]}
{links[0]}
{links[1]}
{links[2]}
"""
self.assertEqual(expect_str, diagram.script)
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "mermaid-py"
version = "0.2.2"
version = "0.2.3"
description = "A simple interface for the the famous lib mermaid-js to create diagrams."
authors = ["ouhammmourachid <[email protected]>"]
readme = "README.md"
Expand Down

0 comments on commit 1c05fd0

Please sign in to comment.