1104-Add support to designate a method as abstract

Added logic to allow rendering of a method name with italics or underline based on modifier at beginning of name to set css style
This commit is contained in:
Justin Greywolf
2019-12-09 17:41:26 -08:00
parent cf5d7478fc
commit 6fdf30357c
4 changed files with 86 additions and 12 deletions

View File

@@ -163,4 +163,28 @@ describe('Class diagram', () => {
);
cy.get('svg');
});
it('5: should render a simple class diagram with abstract method', () => {
imgSnapshotTest(
`
classDiagram
Class01 <|-- AveryLongClass : Cool
Class01 : |someMethod()
`,
{}
);
cy.get('svg');
});
it('6: should render a simple class diagram with static method', () => {
imgSnapshotTest(
`
classDiagram
Class01 <|-- AveryLongClass : Cool
Class01 : $someMethod()
`,
{}
);
cy.get('svg');
});
});

View File

@@ -105,17 +105,10 @@ Naming convention: a class name should be composed of alphanumeric (unicode allo
UML provides mechanisms to represent class members, such as attributes and methods, and additional information about them.
#### Visibility
To specify the visibility of a class member (i.e. any attribute or method), these notations may be placed before the member's name, but is it optional:
Mermaid distinguishes between attributes and functions/methods based on if the **parenthesis** `()` are present or not. The ones with `()` are treated as functions/methods, and others as attributes.
- `+` Public
- `-` Private
- `#` Protected
- `~` Package
Mermaid distinguishes between attributes and functions/methods based on if the **parenthesis** `()` are present or not. The one with `()` are treated as functions/methods, and others as attributes.
There are two ways to define the members of a class, and regardless of the whichever syntax is used to define the members, the output will still be same. The two different ways are :
There are two ways to define the members of a class, and regardless of whichever syntax is used to define the members, the output will still be same. The two different ways are :
- Associate a member of a class using **:** (colon) followed by member name, useful to define one member at a time. For example:
```
@@ -125,7 +118,7 @@ There are two ways to define the members of a class, and regardless of the which
BankAccount : +deposit(amount)
BankAccount : +withdrawl(amount)
```
```mermaid
``` mermaid
classDiagram
class BankAccount
BankAccount : +String owner
@@ -150,7 +143,22 @@ class BankAccount{
+BigDecimal balance
+deposit(amount)
+withdrawl(amount)
}```
}
```
#### Visibility
To specify the visibility of a class member (i.e. any attribute or method), these notations may be placed before the member's name, but it is optional:
- `+` Public
- `-` Private
- `#` Protected
- `~` Package
>_note_ you can also add additional _classifers_ to a method definition using the following notations (similar to visibliity above):
> - `|` Abstract e.g.: `|someAbstractMethod()`
> - `$` Static e.g.: `$someStaticMethod()`
## Defining Relationship
A relationship is a general term covering the specific types of logical connections found on class and object diagrams.

View File

@@ -400,5 +400,27 @@ describe('class diagram, ', function () {
expect(testClass.methods[0]).toBe('test()');
expect(testClass.methods[1]).toBe('foo()');
});
it('should handle abstract methods', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : |someMethod()';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.annotations.length).toBe(0);
expect(testClass.members.length).toBe(0);
expect(testClass.methods.length).toBe(1);
expect(testClass.methods[0]).toBe('|someMethod()');
});
it('should handle static methods', function () {
const str = 'classDiagram\n' + 'class Class1\n' + 'Class1 : $someMethod()';
parser.parse(str);
const testClass = parser.yy.getClass('Class1');
expect(testClass.annotations.length).toBe(0);
expect(testClass.members.length).toBe(0);
expect(testClass.methods.length).toBe(1);
expect(testClass.methods[0]).toBe('$someMethod()');
});
});
});

View File

@@ -281,10 +281,30 @@ const drawClass = function(elem, classDef) {
logger.info('Rendering class ' + classDef);
const addTspan = function(textEl, txt, isFirst) {
let displayText = txt;
let cssStyle = '';
let classifier = txt.substring(0 , 1);
switch (classifier) {
case '|':
cssStyle = 'font-style:italic;';
displayText = txt.substring(1);
break;
case '$':
cssStyle = 'text-decoration:underline;';
displayText = txt.substring(1);
break;
}
const tSpan = textEl
.append('tspan')
.attr('x', conf.padding)
.text(txt);
.text(displayText);
if (cssStyle !== '') {
tSpan.attr('style', cssStyle);
}
if (!isFirst) {
tSpan.attr('dy', conf.textHeight);
}