From 2493721d73c6b2945e191c406cc843b003a303fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Sun, 3 Sep 2023 19:12:00 +0200 Subject: [PATCH 01/10] Use string literals for examples --- .../ObjectDiagramExampleTests.cs | 216 +-- .../SequenceDiagramExampleTests.cs | 1157 +++++++++-------- 2 files changed, 769 insertions(+), 604 deletions(-) diff --git a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs index d9909bf..3b34499 100644 --- a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs @@ -12,11 +12,14 @@ public class ObjectDiagramExampleTests public void DefinitionOfObjects() { // Arrange - var example = @"@startuml -object firstObject -object ""My Second Object"" as o2 -@enduml -"; + var example = + """ + @startuml + object firstObject + object "My Second Object" as o2 + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -34,22 +37,25 @@ object firstObject public void RelationsBetweenObjects() { // Arrange - var example = @"@startuml -object Object01 -object Object02 -object Object03 -object Object04 -object Object05 -object Object06 -object Object07 -object Object08 - -Object01 <|-- Object02 -Object03 *-- Object04 -Object05 o-- ""4"" Object06 -Object07 .. Object08 : some labels -@enduml -"; + var example = + """ + @startuml + object Object01 + object Object02 + object Object03 + object Object04 + object Object05 + object Object06 + object Object07 + object Object08 + + Object01 <|-- Object02 + Object03 *-- Object04 + Object05 o-- "4" Object06 + Object07 .. Object08 : some labels + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -78,17 +84,20 @@ Object05 o-- ""4"" Object06 public void AssociationsObjects() { // Arrange - var example = @"@startuml -object o1 -object o2 -diamond dia -object o3 - -o1 --> dia -o2 --> dia -dia --> o3 -@enduml -"; + var example = + """ + @startuml + object o1 + object o2 + diamond dia + object o3 + + o1 --> dia + o2 --> dia + dia --> o3 + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -112,15 +121,18 @@ object o3 public void AddingFields01() { // Arrange - var example = @"@startuml + var example = + """ + @startuml + + object user -object user + user : name = "Dummy" + user : id = 123 -user : name = ""Dummy"" -user : id = 123 + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -142,15 +154,18 @@ object user public void AddingFields02() { // Arrange - var example = @"@startuml + var example = + """ + @startuml -object user { -name = ""Dummy"" -id = 123 -} + object user { + name = "Dummy" + id = 123 + } + + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -172,14 +187,17 @@ object user { public void MapTableOrAssociativeArray01() { // Arrange - var example = @"@startuml -map CapitalCity { -UK => London -USA => Washington -Germany => Berlin -} -@enduml -"; + var example = + """ + @startuml + map CapitalCity { + UK => London + USA => Washington + Germany => Berlin + } + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -200,14 +218,17 @@ map CapitalCity { public void MapTableOrAssociativeArray02() { // Arrange - var example = @"@startuml -map ""Map **Contry => CapitalCity**"" as CC { -UK => London -USA => Washington -Germany => Berlin -} -@enduml -"; + var example = + """ + @startuml + map "Map **Contry => CapitalCity**" as CC { + UK => London + USA => Washington + Germany => Berlin + } + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -228,14 +249,17 @@ public void MapTableOrAssociativeArray02() public void MapTableOrAssociativeArray03() { // Arrange - var example = @"@startuml -map ""map: Map"" as users { -1 => Alice -2 => Bob -3 => Charlie -} -@enduml -"; + var example = + """ + @startuml + map "map: Map" as users { + 1 => Alice + 2 => Bob + 3 => Charlie + } + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -256,16 +280,19 @@ public void MapTableOrAssociativeArray03() public void MapTableOrAssociativeArray04() { // Arrange - var example = @"@startuml -object London + var example = + """ + @startuml + object London -map CapitalCity { -UK *-> London -USA => Washington -Germany => Berlin -} -@enduml -"; + map CapitalCity { + UK *-> London + USA => Washington + Germany => Berlin + } + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -288,21 +315,24 @@ map CapitalCity { public void MapTableOrAssociativeArray05() { // Arrange - var example = @"@startuml -object London -object Washington -object Berlin -object NewYork - -map CapitalCity { -UK *-> London -USA *--> Washington -Germany *---> Berlin -} - -NewYork --> CapitalCity::USA -@enduml -"; + var example = + """ + @startuml + object London + object Washington + object Berlin + object NewYork + + map CapitalCity { + UK *-> London + USA *--> Washington + Germany *---> Berlin + } + + NewYork --> CapitalCity::USA + @enduml + + """; var stringBuilder = new StringBuilder(); diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index de304e0..5f213cb 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -12,14 +12,17 @@ public class SequenceDiagramExampleTests public void BasicExamples() { // Arrange - var example = @"@startuml -Alice -> Bob : Authentication Request -Bob --> Alice : Authentication Response + var example = + """ + @startuml + Alice -> Bob : Authentication Request + Bob --> Alice : Authentication Response -Alice -> Bob : Another authentication Request -Alice <-- Bob : Another authentication Response -@enduml -"; + Alice -> Bob : Another authentication Request + Alice <-- Bob : Another authentication Response + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -40,24 +43,27 @@ public void BasicExamples() public void DeclaringParticipant01() { // Arrange - var example = @"@startuml -participant participant as Foo -actor actor as Foo1 -boundary boundary as Foo2 -control control as Foo3 -entity entity as Foo4 -database database as Foo5 -collections collections as Foo6 -queue queue as Foo7 -Foo -> Foo1 : To actor -Foo -> Foo2 : To boundary -Foo -> Foo3 : To control -Foo -> Foo4 : To entity -Foo -> Foo5 : To database -Foo -> Foo6 : To collections -Foo -> Foo7 : To queue -@enduml -"; + var example = + """ + @startuml + participant participant as Foo + actor actor as Foo1 + boundary boundary as Foo2 + control control as Foo3 + entity entity as Foo4 + database database as Foo5 + collections collections as Foo6 + queue queue as Foo7 + Foo -> Foo1 : To actor + Foo -> Foo2 : To boundary + Foo -> Foo3 : To control + Foo -> Foo4 : To entity + Foo -> Foo5 : To database + Foo -> Foo6 : To collections + Foo -> Foo7 : To queue + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -88,21 +94,24 @@ queue queue as Foo7 public void DeclaringParticipant02() { // Arrange - var example = @"@startuml -actor Bob #red -' The only difference between actor -' and participant is the drawing -participant Alice -participant ""I have a really\nlong name"" as L #99FF99 -/' You can also declare: - participant L as ""I have a really\nlong name"" #99FF99 - '/ - -Alice -> Bob : Authentication Request -Bob -> Alice : Authentication Response -Bob -> L : Log transaction -@enduml -"; + var example = + """ + @startuml + actor Bob #red + ' The only difference between actor + ' and participant is the drawing + participant Alice + participant "I have a really\nlong name" as L #99FF99 + /' You can also declare: + participant L as "I have a really\nlong name" #99FF99 + '/ + + Alice -> Bob : Authentication Request + Bob -> Alice : Authentication Response + Bob -> L : Log transaction + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -128,12 +137,15 @@ participant L as ""I have a really\nlong name"" #99FF99 public void DeclaringParticipant03() { // Arrange - var example = @"@startuml -participant Last order 30 -participant Middle order 20 -participant First order 10 -@enduml -"; + var example = + """ + @startuml + participant Last order 30 + participant Middle order 20 + participant First order 10 + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -152,14 +164,17 @@ participant First order 10 public void UseNonLettersInParticipants() { // Arrange - var example = @"@startuml -Alice -> ""Bob()"" : Hello -""Bob()"" -> ""This is very\nlong"" as Long -' You can also declare: -' ""Bob()"" -> Long as ""This is very\nlong"" -Long --> ""Bob()"" : ok -@enduml -"; + var example = + """ + @startuml + Alice -> "Bob()" : Hello + "Bob()" -> "This is very\nlong" as Long + ' You can also declare: + ' "Bob()" -> Long as "This is very\nlong" + Long --> "Bob()" : ok + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -180,10 +195,13 @@ public void UseNonLettersInParticipants() public void MessageToSelf01() { // Arrange - var example = @"@startuml -Alice -> Alice : This is a signal to self.\nIt also demonstrates\nmultiline \ntext -@enduml -"; + var example = + """ + @startuml + Alice -> Alice : This is a signal to self.\nIt also demonstrates\nmultiline \ntext + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -200,10 +218,13 @@ public void MessageToSelf01() public void MessageToSelf02() { // Arrange - var example = @"@startuml -Alice <- Alice : This is a signal to self.\nIt also demonstrates\nmultiline \ntext -@enduml -"; + var example = + """ + @startuml + Alice <- Alice : This is a signal to self.\nIt also demonstrates\nmultiline \ntext + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -220,12 +241,15 @@ public void MessageToSelf02() public void TextAlignment01() { // Arrange - var example = @"@startuml -skinparam sequenceMessageAlignment right -Bob -> Alice : Request -Alice -> Bob : Response -@enduml -"; + var example = + """ + @startuml + skinparam sequenceMessageAlignment right + Bob -> Alice : Request + Alice -> Bob : Response + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -244,12 +268,15 @@ skinparam sequenceMessageAlignment right public void TextAlignment02() { // Arrange - var example = @"@startuml -skinparam responseMessageBelowArrow true -Bob -> Alice : hello -Alice -> Bob : ok -@enduml -"; + var example = + """ + @startuml + skinparam responseMessageBelowArrow true + Bob -> Alice : hello + Alice -> Bob : ok + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -268,21 +295,24 @@ skinparam responseMessageBelowArrow true public void ChangeArrowStyle01() { // Arrange - var example = @"@startuml -Bob ->x Alice -Bob -> Alice -Bob ->> Alice -Bob -\ Alice -Bob \\- Alice -Bob //-- Alice - -Bob ->o Alice -Bob o\\-- Alice - -Bob <-> Alice -Bob <->o Alice -@enduml -"; + var example = + """ + @startuml + Bob ->x Alice + Bob -> Alice + Bob ->> Alice + Bob -\ Alice + Bob \\- Alice + Bob //-- Alice + + Bob ->o Alice + Bob o\\-- Alice + + Bob <-> Alice + Bob <->o Alice + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -310,21 +340,24 @@ Bob o\\-- Alice public void ChangeArrowStyle02() { // Arrange - var example = @"@startuml -Bob ->x Alice -Bob -> Alice -Bob ->> Alice -Bob -\ Alice -Bob \\- Alice -Bob //-- Alice - -Bob ->o Alice -Bob o\\-- Alice - -Bob <-> Alice -Bob <->o Alice -@enduml -"; + var example = + """ + @startuml + Bob ->x Alice + Bob -> Alice + Bob ->> Alice + Bob -\ Alice + Bob \\- Alice + Bob //-- Alice + + Bob ->o Alice + Bob o\\-- Alice + + Bob <-> Alice + Bob <->o Alice + @enduml + + """; var stringBuilder = new StringBuilder(); var bob = new Bob(); @@ -354,11 +387,14 @@ Bob o\\-- Alice public void ChangeArrowColor() { // Arrange - var example = @"@startuml -Bob -[#red]> Alice : hello -Alice --[#0000FF]> Bob : ok -@enduml -"; + var example = + """ + @startuml + Bob -[#red]> Alice : hello + Alice --[#0000FF]> Bob : ok + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -376,12 +412,15 @@ public void ChangeArrowColor() public void MessageSequenceNumbering01() { // Arrange - var example = @"@startuml -autonumber -Bob -> Alice : Authentication Request -Bob <- Alice : Authentication Response -@enduml -"; + var example = + """ + @startuml + autonumber + Bob -> Alice : Authentication Request + Bob <- Alice : Authentication Response + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -400,21 +439,24 @@ public void MessageSequenceNumbering01() public void MessageSequenceNumbering02() { // Arrange - var example = @"@startuml -autonumber -Bob -> Alice : Authentication Request -Bob <- Alice : Authentication Response + var example = + """ + @startuml + autonumber + Bob -> Alice : Authentication Request + Bob <- Alice : Authentication Response + + autonumber 15 + Bob -> Alice : Another authentication Request + Bob <- Alice : Another authentication Response -autonumber 15 -Bob -> Alice : Another authentication Request -Bob <- Alice : Another authentication Response + autonumber 40 10 + Bob -> Alice : Yet another authentication Request + Bob <- Alice : Yet another authentication Response -autonumber 40 10 -Bob -> Alice : Yet another authentication Request -Bob <- Alice : Yet another authentication Response + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -442,21 +484,24 @@ autonumber 40 10 public void MessageSequenceNumbering03() { // Arrange - var example = @"@startuml -autonumber ""[000]"" -Bob -> Alice : Authentication Request -Bob <- Alice : Authentication Response + var example = + """ + @startuml + autonumber "[000]" + Bob -> Alice : Authentication Request + Bob <- Alice : Authentication Response -autonumber 15 ""(##)"" -Bob -> Alice : Another authentication Request -Bob <- Alice : Another authentication Response + autonumber 15 "(##)" + Bob -> Alice : Another authentication Request + Bob <- Alice : Another authentication Response -autonumber 40 10 ""Message 0 "" -Bob -> Alice : Yet another authentication Request -Bob <- Alice : Yet another authentication Response + autonumber 40 10 "Message 0 " + Bob -> Alice : Yet another authentication Request + Bob <- Alice : Yet another authentication Response -@enduml -"; + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -484,26 +529,29 @@ public void MessageSequenceNumbering03() public void MessageSequenceNumbering04() { // Arrange - var example = @"@startuml -autonumber 10 10 ""[000]"" -Bob -> Alice : Authentication Request -Bob <- Alice : Authentication Response + var example = + """ + @startuml + autonumber 10 10 "[000]" + Bob -> Alice : Authentication Request + Bob <- Alice : Authentication Response + + autonumber stop + Bob -> Alice : dummy -autonumber stop -Bob -> Alice : dummy + autonumber resume "Message 0 " + Bob -> Alice : Yet another authentication Request + Bob <- Alice : Yet another authentication Response -autonumber resume ""Message 0 "" -Bob -> Alice : Yet another authentication Request -Bob <- Alice : Yet another authentication Response + autonumber stop + Bob -> Alice : dummy -autonumber stop -Bob -> Alice : dummy + autonumber resume 1 "Message 0 " + Bob -> Alice : Yet another authentication Request + Bob <- Alice : Yet another authentication Response + @enduml -autonumber resume 1 ""Message 0 "" -Bob -> Alice : Yet another authentication Request -Bob <- Alice : Yet another authentication Response -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -536,29 +584,32 @@ autonumber stop public void MessageSequenceNumbering05() { // Arrange - var example = @"@startuml -autonumber 1.1.1 -Alice -> Bob : Authentication request -Bob --> Alice : Response - -autonumber inc A -' Now we have 2.1.1 -Alice -> Bob : Another authentication request -Bob --> Alice : Response - -autonumber inc B -' Now we have 2.2.1 -Alice -> Bob : Another authentication request -Bob --> Alice : Response - -autonumber inc A -' Now we have 3.1.1 -Alice -> Bob : Another authentication request -autonumber inc B -' Now we have 3.2.1 -Bob --> Alice : Response -@enduml -"; + var example = + """ + @startuml + autonumber 1.1.1 + Alice -> Bob : Authentication request + Bob --> Alice : Response + + autonumber inc A + ' Now we have 2.1.1 + Alice -> Bob : Another authentication request + Bob --> Alice : Response + + autonumber inc B + ' Now we have 2.2.1 + Alice -> Bob : Another authentication request + Bob --> Alice : Response + + autonumber inc A + ' Now we have 3.1.1 + Alice -> Bob : Another authentication request + autonumber inc B + ' Now we have 3.2.1 + Bob --> Alice : Response + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -594,18 +645,21 @@ autonumber inc B public void PageTitleHeaderAndFooter() { // Arrange - var example = @"@startuml + var example = + """ + @startuml -header Page Header -footer Page %page% of %lastpage% + header Page Header + footer Page %page% of %lastpage% -title Example Title + title Example Title -Alice -> Bob : message 1 -Alice -> Bob : message 2 + Alice -> Bob : message 1 + Alice -> Bob : message 2 -@enduml -"; + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -630,21 +684,24 @@ title Example Title public void SplittingDiagrams() { // Arrange - var example = @"@startuml -Alice -> Bob : message 1 -Alice -> Bob : message 2 + var example = + """ + @startuml + Alice -> Bob : message 1 + Alice -> Bob : message 2 + + newpage -newpage + Alice -> Bob : message 3 + Alice -> Bob : message 4 -Alice -> Bob : message 3 -Alice -> Bob : message 4 + newpage A title for the\nlast page -newpage A title for the\nlast page + Alice -> Bob : message 5 + Alice -> Bob : message 6 + @enduml -Alice -> Bob : message 5 -Alice -> Bob : message 6 -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -672,31 +729,34 @@ public void SplittingDiagrams() public void GroupingMessages() { // Arrange - var example = @"@startuml -Alice -> Bob : Authentication Request + var example = + """ + @startuml + Alice -> Bob : Authentication Request -alt successful case + alt successful case -Bob -> Alice : Authentication Accepted + Bob -> Alice : Authentication Accepted -else some kind of failure + else some kind of failure -Bob -> Alice : Authentication Failure -group My own label -Alice -> Log : Log attack start -loop 1000 times -Alice -> Bob : DNS Attack -end -Alice -> Log : Log attack end -end + Bob -> Alice : Authentication Failure + group My own label + Alice -> Log : Log attack start + loop 1000 times + Alice -> Bob : DNS Attack + end + Alice -> Log : Log attack end + end -else Another type of failure + else Another type of failure -Bob -> Alice : Please repeat + Bob -> Alice : Please repeat -end -@enduml -"; + end + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -734,18 +794,21 @@ loop 1000 times public void SecondaryGroupLabel() { // Arrange - var example = @"@startuml -Alice -> Bob : Authentication Request -Bob -> Alice : Authentication Failure -group My own label [My own label 2] -Alice -> Log : Log attack start -loop 1000 times -Alice -> Bob : DNS Attack -end -Alice -> Log : Log attack end -end -@enduml -"; + var example = + """ + @startuml + Alice -> Bob : Authentication Request + Bob -> Alice : Authentication Failure + group My own label [My own label 2] + Alice -> Log : Log attack start + loop 1000 times + Alice -> Bob : DNS Attack + end + Alice -> Log : Log attack end + end + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -770,21 +833,24 @@ loop 1000 times public void NotesOnMessages() { // Arrange - var example = @"@startuml -Alice -> Bob : hello -note left : this is a first note - -Bob -> Alice : ok -note right : this is another note - -Bob -> Bob : I am thinking -note left -a note -can also be defined -on several lines -end note -@enduml -"; + var example = + """ + @startuml + Alice -> Bob : hello + note left : this is a first note + + Bob -> Alice : ok + note right : this is another note + + Bob -> Bob : I am thinking + note left + a note + can also be defined + on several lines + end note + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -812,27 +878,30 @@ end note public void SomeOtherNotes() { // Arrange - var example = @"@startuml -participant Alice -participant Bob -note left of Alice #aqua -This is displayed -left of Alice. -end note + var example = + """ + @startuml + participant Alice + participant Bob + note left of Alice #aqua + This is displayed + left of Alice. + end note + + note right of Alice : This is displayed right of Alice. -note right of Alice : This is displayed right of Alice. + note over Alice : This is displayed over Alice. -note over Alice : This is displayed over Alice. + note over Alice,Bob #FFAAAA : This is displayed\n over Bob and Alice. -note over Alice,Bob #FFAAAA : This is displayed\n over Bob and Alice. + note over Bob,Alice + This is yet another + example of + a long note. + end note + @enduml -note over Bob,Alice -This is yet another -example of -a long note. -end note -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -866,26 +935,29 @@ end note public void ChangingNotesShape() { // Arrange - var example = @"@startuml -caller -> server : conReq -hnote over caller : idle -caller <- server : conConf -rnote over server - ""r"" as rectangle - ""h"" as hexagon -end rnote -rnote over server - this is - on several - lines -end rnote -hnote over caller - this is - on several - lines -end hnote -@enduml -"; + var example = + """ + @startuml + caller -> server : conReq + hnote over caller : idle + caller <- server : conConf + rnote over server + "r" as rectangle + "h" as hexagon + end rnote + rnote over server + this is + on several + lines + end rnote + hnote over caller + this is + on several + lines + end hnote + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -918,15 +990,18 @@ end hnote public void NoteOverAllParticipants() { // Arrange - var example = @"@startuml -Alice -> Bob : m1 -Bob -> Charlie : m2 -note over Alice,Charlie : Old method for note over all part. with:\n """"note over //FirstPart, LastPart//"""". -note across : New method with:\n""""note across"""" -Bob -> Alice -hnote across : Note across all part. -@enduml -"; + var example = + """ + @startuml + Alice -> Bob : m1 + Bob -> Charlie : m2 + note over Alice,Charlie : Old method for note over all part. with:\n ""note over //FirstPart, LastPart//"". + note across : New method with:\n""note across"" + Bob -> Alice + hnote across : Note across all part. + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -948,12 +1023,15 @@ public void NoteOverAllParticipants() public void SeveralNotesAlignedAtTheSameLevel01() { // Arrange - var example = @"@startuml -note over Alice : initial state of Alice -note over Bob : initial state of Bob -Bob -> Alice : hello -@enduml -"; + var example = + """ + @startuml + note over Alice : initial state of Alice + note over Bob : initial state of Bob + Bob -> Alice : hello + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -972,12 +1050,15 @@ public void SeveralNotesAlignedAtTheSameLevel01() public void SeveralNotesAlignedAtTheSameLevel02() { // Arrange - var example = @"@startuml -note over Alice : initial state of Alice -/ note over Bob : initial state of Bob -Bob -> Alice : hello -@enduml -"; + var example = + """ + @startuml + note over Alice : initial state of Alice + / note over Bob : initial state of Bob + Bob -> Alice : hello + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -996,36 +1077,39 @@ public void SeveralNotesAlignedAtTheSameLevel02() public void CreoleAndHtml() { // Arrange - var example = @"@startuml -participant Alice -participant ""The **Famous** Bob"" as Bob - -Alice -> Bob : hello --there-- -... Some ~~long delay~~ ... -Bob -> Alice : ok -note left - This is **bold** - This is //italics// - This is """"monospaced"""" - This is --stroked-- - This is __underlined__ - This is ~~waved~~ -end note - -Alice -> Bob : A //well formatted// message -note right of Alice - This is displayed - __left of__ Alice. -end note -note left of Bob - This is displayed - **left of Alice Bob**. -end note -note over Alice,Bob - This is hosted by -end note -@enduml -"; + var example = + """ + @startuml + participant Alice + participant "The **Famous** Bob" as Bob + + Alice -> Bob : hello --there-- + ... Some ~~long delay~~ ... + Bob -> Alice : ok + note left + This is **bold** + This is //italics// + This is ""monospaced"" + This is --stroked-- + This is __underlined__ + This is ~~waved~~ + end note + + Alice -> Bob : A //well formatted// message + note right of Alice + This is displayed + __left of__ Alice. + end note + note left of Bob + This is displayed + **left of Alice Bob**. + end note + note over Alice,Bob + This is hosted by + end note + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1068,20 +1152,23 @@ end note public void DividerOrSeparator() { // Arrange - var example = @"@startuml + var example = + """ + @startuml + + == Initialization == -== Initialization == + Alice -> Bob : Authentication Request + Bob --> Alice : Authentication Response -Alice -> Bob : Authentication Request -Bob --> Alice : Authentication Response + == Repetition == -== Repetition == + Alice -> Bob : Another authentication Request + Alice <-- Bob : another authentication Response -Alice -> Bob : Another authentication Request -Alice <-- Bob : another authentication Response + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -1108,20 +1195,23 @@ public void DividerOrSeparator() public void Reference() { // Arrange - var example = @"@startuml -participant Alice -actor Bob + var example = + """ + @startuml + participant Alice + actor Bob -ref over Alice,Bob : init + ref over Alice,Bob : init -Alice -> Bob : hello + Alice -> Bob : hello -ref over Bob - This can be on - several lines -end ref -@enduml -"; + ref over Bob + This can be on + several lines + end ref + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1148,16 +1238,19 @@ end ref public void Delay() { // Arrange - var example = @"@startuml + var example = + """ + @startuml + + Alice -> Bob : Authentication Request + ... + Bob --> Alice : Authentication Response + ...5 minutes later... + Bob --> Alice : Good Bye ! -Alice -> Bob : Authentication Request -... -Bob --> Alice : Authentication Response -...5 minutes later... -Bob --> Alice : Good Bye ! + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -1180,14 +1273,17 @@ ...5 minutes later... public void TextWrapping() { // Arrange - var example = @"@startuml -skinparam MaxMessageSize 50 -participant a -participant b -a -> b : this\nis\nmanually\ndone -a -> b : this is a very long message on several words -@enduml -"; + var example = + """ + @startuml + skinparam MaxMessageSize 50 + participant a + participant b + a -> b : this\nis\nmanually\ndone + a -> b : this is a very long message on several words + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1208,19 +1304,22 @@ participant b public void Space() { // Arrange - var example = @"@startuml + var example = + """ + @startuml -Alice -> Bob : message 1 -Bob --> Alice : ok -||| -Alice -> Bob : message 2 -Bob --> Alice : ok -||45|| -Alice -> Bob : message 3 -Bob --> Alice : ok + Alice -> Bob : message 1 + Bob --> Alice : ok + ||| + Alice -> Bob : message 2 + Bob --> Alice : ok + ||45|| + Alice -> Bob : message 3 + Bob --> Alice : ok -@enduml -"; + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1246,28 +1345,31 @@ public void Space() public void LifelineActivationAndDestruction01() { // Arrange - var example = @"@startuml -participant User + var example = + """ + @startuml + participant User + + User -> A : DoWork + activate A -User -> A : DoWork -activate A + A -> B : << createRequest >> + activate B -A -> B : << createRequest >> -activate B + B -> C : DoWork + activate C + C --> B : WorkDone + destroy C -B -> C : DoWork -activate C -C --> B : WorkDone -destroy C + B --> A : RequestCreated + deactivate B -B --> A : RequestCreated -deactivate B + A -> User : Done + deactivate A -A -> User : Done -deactivate A + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -1302,26 +1404,29 @@ deactivate A public void LifelineActivationAndDestruction02() { // Arrange - var example = @"@startuml -participant User + var example = + """ + @startuml + participant User + + User -> A : DoWork + activate A #FFBBBB -User -> A : DoWork -activate A #FFBBBB + A -> A : Internal call + activate A #DarkSalmon -A -> A : Internal call -activate A #DarkSalmon + A -> B : << createRequest >> + activate B -A -> B : << createRequest >> -activate B + B --> A : RequestCreated + deactivate B + deactivate A + A -> User : Done + deactivate A -B --> A : RequestCreated -deactivate B -deactivate A -A -> User : Done -deactivate A + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -1354,19 +1459,22 @@ deactivate A public void LifelineActivationAndDestruction03() { // Arrange - var example = @"@startuml -autoactivate on -alice -> bob : hello -bob -> bob : self call -bill -> bob #005500 : hello from thread 2 -bob -> george ** : create -return done in thread 2 -return rc -bob -> george !! : delete -return success - -@enduml -"; + var example = + """ + @startuml + autoactivate on + alice -> bob : hello + bob -> bob : self call + bill -> bob #005500 : hello from thread 2 + bob -> george ** : create + return done in thread 2 + return rc + bob -> george !! : delete + return success + + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1392,13 +1500,16 @@ autoactivate on public void Return() { // Arrange - var example = @"@startuml -Bob -> Alice : hello -activate Alice -Alice -> Alice : some action -return bye -@enduml -"; + var example = + """ + @startuml + Bob -> Alice : hello + activate Alice + Alice -> Alice : some action + return bye + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1418,20 +1529,23 @@ activate Alice public void ParticipantCreation() { // Arrange - var example = @"@startuml -Bob -> Alice : hello + var example = + """ + @startuml + Bob -> Alice : hello + + create Other + Alice -> Other : new -create Other -Alice -> Other : new + create control String + Alice -> String + note right : You can also put notes! -create control String -Alice -> String -note right : You can also put notes! + Alice --> Bob : ok -Alice --> Bob : ok + @enduml -@enduml -"; + """; var stringBuilder = new StringBuilder(); @@ -1458,17 +1572,20 @@ create control String public void ShortcutSyntaxForActivationDeactivationCreation() { // Arrange - var example = @"@startuml -alice -> bob ++ : hello -bob -> bob ++ : self call -bob -> bib ++ #005500 : hello -bob -> george ** : create -return done -return rc -bob -> george !! : delete -return success -@enduml -"; + var example = + """ + @startuml + alice -> bob ++ : hello + bob -> bob ++ : self call + bob -> bib ++ #005500 : hello + bob -> george ** : create + return done + return rc + bob -> george !! : delete + return success + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1492,12 +1609,15 @@ public void ShortcutSyntaxForActivationDeactivationCreation() public void MixActivationAndDeactivationOnSameLine01() { // Arrange - var example = @"@startuml -alice -> bob ++ : hello1 -bob -> charlie --++ : hello2 -charlie --> alice -- : ok -@enduml -"; + var example = + """ + @startuml + alice -> bob ++ : hello1 + bob -> charlie --++ : hello2 + charlie --> alice -- : ok + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1516,13 +1636,16 @@ public void MixActivationAndDeactivationOnSameLine01() public void MixActivationAndDeactivationOnSameLine02() { // Arrange - var example = @"@startuml -alice -> bob --++ #Gold : hello -bob -> alice --++ #Gold : you too -alice -> bob -- : step1 -alice -> bob : step2 -@enduml -"; + var example = + """ + @startuml + alice -> bob --++ #Gold : hello + bob -> alice --++ #Gold : you too + alice -> bob -- : step1 + alice -> bob : step2 + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1542,22 +1665,25 @@ public void MixActivationAndDeactivationOnSameLine02() public void IncomingAndOutgoingMessages01() { // Arrange - var example = @"@startuml -[-> A : DoWork + var example = + """ + @startuml + [-> A : DoWork -activate A + activate A -A -> A : Internal call -activate A + A -> A : Internal call + activate A -A ->] : << createRequest >> + A ->] : << createRequest >> -A <--] : RequestCreated -deactivate A -[<- A : Done -deactivate A -@enduml -"; + A <--] : RequestCreated + deactivate A + [<- A : Done + deactivate A + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1586,30 +1712,33 @@ deactivate A public void IncomingAndOutgoingMessages02() { // Arrange - var example = @"@startuml -participant Alice -participant Bob #lightblue -Alice -> Bob -Bob -> Carol -... -[-> Bob -[o-> Bob -[o->o Bob -[x-> Bob -... -[<- Bob -[x<- Bob -... -Bob ->] -Bob ->o] -Bob o->o] -Bob ->x] -... -Bob <-] -Bob x<-] - -@enduml -"; + var example = + """ + @startuml + participant Alice + participant Bob #lightblue + Alice -> Bob + Bob -> Carol + ... + [-> Bob + [o-> Bob + [o->o Bob + [x-> Bob + ... + [<- Bob + [x<- Bob + ... + Bob ->] + Bob ->o] + Bob o->o] + Bob ->x] + ... + Bob <-] + Bob x<-] + + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1646,16 +1775,19 @@ Bob x<-] public void ShortArrowsForIncomingAndOutgoingMessages() { // Arrange - var example = @"@startuml -?-> Alice : """"?->""""\n**short** to actor1 -[-> Alice : """"[->""""\n**from start** to actor1 -[-> Bob : """"[->""""\n**from start** to actor2 -?-> Bob : """"?->""""\n**short** to actor2 -Alice ->] : """"->]""""\nfrom actor1 **to end** -Alice ->? : """"->?""""\n**short** from actor1 -Alice -> Bob : """"->"""" \nfrom actor1 to actor2 -@enduml -"; + var example = + """ + @startuml + ?-> Alice : ""?->""\n**short** to actor1 + [-> Alice : ""[->""\n**from start** to actor1 + [-> Bob : ""[->""\n**from start** to actor2 + ?-> Bob : ""?->""\n**short** to actor2 + Alice ->] : ""->]""\nfrom actor1 **to end** + Alice ->? : ""->?""\n**short** from actor1 + Alice -> Bob : ""->"" \nfrom actor1 to actor2 + @enduml + + """; var stringBuilder = new StringBuilder(); @@ -1678,9 +1810,12 @@ public void ShortArrowsForIncomingAndOutgoingMessages() public void Template() { // Arrange - var example = @"@startuml -@enduml -"; + var example = + """ + @startuml + @enduml + + """; var stringBuilder = new StringBuilder(); From d874ca3c1b0771a0d00b296f59b5db2a8d3cb10d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Mon, 4 Sep 2023 20:41:52 +0200 Subject: [PATCH 02/10] Small improvements to ParticipantName --- .../SequenceDiagrams/ParticipantName.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/PlantUml.Builder/SequenceDiagrams/ParticipantName.cs b/src/PlantUml.Builder/SequenceDiagrams/ParticipantName.cs index b87fb29..2d9cadf 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/ParticipantName.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/ParticipantName.cs @@ -1,18 +1,17 @@ using System.Text.RegularExpressions; +using static System.Text.RegularExpressions.RegexOptions; namespace PlantUml.Builder.SequenceDiagrams; public class ParticipantName { - private static readonly Regex nameAlias = new("^(?:[\"]?(?[^\"]+)(?:[\"][\\s]*|[\\s]+)as[\\s]+(?[^\"\\s]+)|(?[^\"\\s]+)[\\s]+as(?:[\\s]*[\"]|[\\s]+)(?[^\"]+)[\"]?|[\"]?(?[^\"]+)[\"]?)$", RegexOptions.Singleline | RegexOptions.Compiled); - private const string ValidNameChars = "0123456789_@."; + private static readonly Regex nameAlias = new("^(?:[\"]?(?[^\"]+)(?:[\"][\\s]*|[\\s]+)as[\\s]+(?[^\"\\s]+)|(?[^\"\\s]+)[\\s]+as(?:[\\s]*[\"]|[\\s]+)(?[^\"]+)[\"]?|[\"]?(?[^\"]+)[\"]?)$", Singleline | Compiled); + private static readonly HashSet validNameChars = new("0123456789_@.".ToCharArray()); public string Name { get; private set; } public string Alias { get; private set; } = string.Empty; - internal static readonly ParticipantName Outside = new(string.Empty + ArrowParts.LeftExternal + ArrowParts.RightExternal); - public ParticipantName(string name) : this(name, default) { @@ -80,9 +79,11 @@ private static string FormatLongName(string name) private static bool MustBeQuoted(string name) { - foreach (var c in name) + for (int i = 0; i < name.Length; i++) { - if (char.IsLetter(c) || ValidNameChars.IndexOf(c) > -1) + char c = name[i]; + + if (char.IsLetter(c) || validNameChars.Contains(c)) { continue; } From 668c0cc28cadb0d9e65c69e95cfe7008ce7bb24d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Mon, 4 Sep 2023 22:08:27 +0200 Subject: [PATCH 03/10] Add links to original examples and rename methods to match page --- .../ObjectDiagramExampleTests.cs | 10 +++ .../SequenceDiagramExampleTests.cs | 88 ++++++++++++++++++- 2 files changed, 95 insertions(+), 3 deletions(-) diff --git a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs index 3b34499..9c7fedd 100644 --- a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs @@ -8,6 +8,7 @@ namespace PlantUml.Builder.Examples; [TestClass] public class ObjectDiagramExampleTests { + /// [TestMethod] public void DefinitionOfObjects() { @@ -33,6 +34,7 @@ object firstObject stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void RelationsBetweenObjects() { @@ -80,6 +82,7 @@ Object05 o-- "4" Object06 stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void AssociationsObjects() { @@ -117,6 +120,7 @@ object o3 stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void AddingFields01() { @@ -150,6 +154,7 @@ object user stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void AddingFields02() { @@ -183,6 +188,7 @@ object user { stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MapTableOrAssociativeArray01() { @@ -214,6 +220,7 @@ map CapitalCity { stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MapTableOrAssociativeArray02() { @@ -245,6 +252,7 @@ public void MapTableOrAssociativeArray02() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MapTableOrAssociativeArray03() { @@ -276,6 +284,7 @@ public void MapTableOrAssociativeArray03() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MapTableOrAssociativeArray04() { @@ -311,6 +320,7 @@ map CapitalCity { stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MapTableOrAssociativeArray05() { diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index 5f213cb..4620864 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -8,6 +8,7 @@ namespace PlantUml.Builder.Examples; [TestClass] public class SequenceDiagramExampleTests { + /// [TestMethod] public void BasicExamples() { @@ -39,6 +40,7 @@ public void BasicExamples() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void DeclaringParticipant01() { @@ -90,6 +92,7 @@ queue queue as Foo7 stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void DeclaringParticipant02() { @@ -133,6 +136,7 @@ participant L as "I have a really\nlong name" #99FF99 stringBuilder.ToString().Should().BeEquivalentTo(example.Replace("\r", "")); } + /// [TestMethod] public void DeclaringParticipant03() { @@ -160,6 +164,7 @@ participant First order 10 stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void UseNonLettersInParticipants() { @@ -191,6 +196,7 @@ public void UseNonLettersInParticipants() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageToSelf01() { @@ -214,6 +220,7 @@ public void MessageToSelf01() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageToSelf02() { @@ -237,6 +244,7 @@ public void MessageToSelf02() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void TextAlignment01() { @@ -264,6 +272,7 @@ skinparam sequenceMessageAlignment right stringBuilder.ToString().Should().BeEquivalentTo(example.Replace("\r", "")); } + /// [TestMethod] public void TextAlignment02() { @@ -291,6 +300,7 @@ skinparam responseMessageBelowArrow true stringBuilder.ToString().Should().BeEquivalentTo(example.Replace("\r", "")); } + /// [TestMethod] public void ChangeArrowStyle01() { @@ -336,6 +346,7 @@ Bob o\\-- Alice stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void ChangeArrowStyle02() { @@ -360,6 +371,7 @@ Bob o\\-- Alice """; var stringBuilder = new StringBuilder(); + var bob = new Bob(); var alice = new Alice(); @@ -383,6 +395,7 @@ Bob o\\-- Alice stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void ChangeArrowColor() { @@ -408,6 +421,7 @@ public void ChangeArrowColor() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageSequenceNumbering01() { @@ -435,6 +449,7 @@ public void MessageSequenceNumbering01() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageSequenceNumbering02() { @@ -480,6 +495,7 @@ autonumber 40 10 stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageSequenceNumbering03() { @@ -525,6 +541,7 @@ public void MessageSequenceNumbering03() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageSequenceNumbering04() { @@ -580,6 +597,7 @@ autonumber stop stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void MessageSequenceNumbering05() { @@ -641,6 +659,43 @@ autonumber inc B stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// + [TestMethod] + public void MessageSequenceNumbering06() + { + // Arrange + var example = + """ + @startuml + autonumber 10 + Alice -> Bob + note right + the autonumber works everywhere. + Here, its value is ** %autonumber% ** + end note + Bob --> Alice : //This is the response %autonumber%// + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AutoNumber(10); + stringBuilder.Arrow("Alice", "->", "Bob"); + stringBuilder.StartNote(NotePosition.Right); + stringBuilder.Text(" the autonumber works everywhere."); + stringBuilder.Text(" Here, its value is ** %autonumber% **"); + stringBuilder.EndNote(); + stringBuilder.Arrow("Bob", "-->", "Alice", "//This is the response %autonumber%//"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// [TestMethod] public void PageTitleHeaderAndFooter() { @@ -680,6 +735,7 @@ title Example Title stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void SplittingDiagrams() { @@ -725,6 +781,7 @@ public void SplittingDiagrams() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void GroupingMessages() { @@ -790,6 +847,7 @@ loop 1000 times stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void SecondaryGroupLabel() { @@ -829,6 +887,7 @@ loop 1000 times stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void NotesOnMessages() { @@ -874,6 +933,7 @@ end note stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void SomeOtherNotes() { @@ -931,6 +991,7 @@ end note stringBuilder.ToString().Should().BeEquivalentTo(example.Replace("\r", "")); } + /// [TestMethod] public void ChangingNotesShape() { @@ -986,6 +1047,7 @@ end hnote stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void NoteOverAllParticipants() { @@ -1019,6 +1081,7 @@ public void NoteOverAllParticipants() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void SeveralNotesAlignedAtTheSameLevel01() { @@ -1046,6 +1109,7 @@ public void SeveralNotesAlignedAtTheSameLevel01() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void SeveralNotesAlignedAtTheSameLevel02() { @@ -1073,6 +1137,7 @@ public void SeveralNotesAlignedAtTheSameLevel02() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void CreoleAndHtml() { @@ -1148,6 +1213,7 @@ end note stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void DividerOrSeparator() { @@ -1191,6 +1257,7 @@ public void DividerOrSeparator() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void Reference() { @@ -1234,6 +1301,7 @@ end ref stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void Delay() { @@ -1269,6 +1337,7 @@ ...5 minutes later... stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void TextWrapping() { @@ -1300,6 +1369,7 @@ participant b stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void Space() { @@ -1341,6 +1411,7 @@ public void Space() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void LifelineActivationAndDestruction01() { @@ -1400,6 +1471,7 @@ deactivate A stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void LifelineActivationAndDestruction02() { @@ -1455,6 +1527,7 @@ deactivate A stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void LifelineActivationAndDestruction03() { @@ -1496,6 +1569,7 @@ autoactivate on stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void Return() { @@ -1525,6 +1599,7 @@ activate Alice stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void ParticipantCreation() { @@ -1568,8 +1643,9 @@ create control String stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] - public void ShortcutSyntaxForActivationDeactivationCreation() + public void ShortcutSyntaxForActivationDeactivationCreation01() { // Arrange var example = @@ -1605,8 +1681,9 @@ public void ShortcutSyntaxForActivationDeactivationCreation() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] - public void MixActivationAndDeactivationOnSameLine01() + public void ShortcutSyntaxForActivationDeactivationCreation02() { // Arrange var example = @@ -1632,8 +1709,9 @@ public void MixActivationAndDeactivationOnSameLine01() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] - public void MixActivationAndDeactivationOnSameLine02() + public void ShortcutSyntaxForActivationDeactivationCreation03() { // Arrange var example = @@ -1661,6 +1739,7 @@ public void MixActivationAndDeactivationOnSameLine02() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void IncomingAndOutgoingMessages01() { @@ -1708,6 +1787,7 @@ deactivate A stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void IncomingAndOutgoingMessages02() { @@ -1771,6 +1851,7 @@ Bob x<-] stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void ShortArrowsForIncomingAndOutgoingMessages() { @@ -1806,6 +1887,7 @@ public void ShortArrowsForIncomingAndOutgoingMessages() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// [TestMethod] public void Template() { From 0292cb46888612d77dc80c79ddf5315cd7f490a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= Date: Mon, 4 Sep 2023 22:10:06 +0200 Subject: [PATCH 04/10] Add stereotype to participants --- docs/commands.md | 30 ++--- .../StringBuilderExtensions/Actor.cs | 12 +- .../StringBuilderExtensions/Boundary.cs | 12 +- .../StringBuilderExtensions/Collections.cs | 12 +- .../StringBuilderExtensions/Control.cs | 12 +- .../StringBuilderExtensions/Database.cs | 12 +- .../StringBuilderExtensions/Entity.cs | 12 +- .../StringBuilderExtensions/Participant.cs | 12 +- .../ParticipantBase.cs | 24 ++-- .../StringBuilderExtensions/Queue.cs | 28 +++-- .../SequenceDiagramExampleTests.cs | 104 ++++++++++++++++++ .../StringBuilderExtensions/ActorTests.cs | 4 + .../StringBuilderExtensions/BoundaryTests.cs | 4 + .../CollectionsTests.cs | 4 + .../StringBuilderExtensions/CreateTests.cs | 4 +- .../StringBuilderExtensions/DatabaseTests.cs | 4 + .../StringBuilderExtensions/EntityTests.cs | 4 + .../ParticipantTests.cs | 2 + .../StringBuilderExtensions/QueueTests.cs | 5 + 19 files changed, 238 insertions(+), 63 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index a91bb0e..d017fc0 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -127,21 +127,21 @@ Following the PlantUML source code. | ignore newpage | no | | | newpage [\] | yes | `NewPage` | | create [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Create` | -| participant \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Participant` | -| actor \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Actor` | -| create actor \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateActor` | -| boundary \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Boundary` | -| create boundary \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateBoundary` | -| collections \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Collections` | -| create collections \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateCollections` | -| control \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Control` | -| create control \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateControl` | -| entity \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Entity` | -| create entity \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateEntity` | -| database \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Database` | -| create database \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateDatabase` | -| queue \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Queue` | -| create queue \<NAME> [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateQueue` | +| participant \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Participant` | +| actor \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Actor` | +| create actor \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateActor` | +| boundary \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Boundary` | +| create boundary \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateBoundary` | +| collections \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Collections` | +| create collections \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateCollections` | +| control \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Control` | +| create control \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateControl` | +| entity \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Entity` | +| create entity \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateEntity` | +| database \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Database` | +| create database \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateDatabase` | +| queue \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `Queue` | +| create queue \<NAME> [\<STEREO>] [order \<ORDER>] [\<URL>] [\<COLOR>] | partial | `CreateQueue` | | ref[\<COLOR>] over \<NAME>[,\<NAME>] : [\<URL>] [\<TEXT>] | partial | `Ref` | | ref[\<COLOR>] over \<NAME>[,\<NAME>] | partial | `StartRef` | | end ref | yes | `EndRef` | diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Actor.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Actor.cs index 575dd01..b82e6ee 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Actor.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Actor.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the actor.</param> /// <param name="color">Optional color of the actor.</param> /// <param name="order">Optional order of the actor.</param> + /// <param name="stereotype">Optional stereotype of the actor.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Actor(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Actor(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Actor, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Actor, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Actor(this StringBuilder stringBuilder, string name, string d /// <param name="displayName">Optional display name of the actor.</param> /// <param name="color">Optional color of the actor.</param> /// <param name="order">Optional order of the actor.</param> + /// <param name="stereotype">Optional stereotype of the actor.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateActor(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateActor(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Actor, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Actor, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Boundary.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Boundary.cs index 0b7e5b1..8d02efe 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Boundary.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Boundary.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the boundary.</param> /// <param name="color">Optional color of the boundary.</param> /// <param name="order">Optional order of the boundary.</param> + /// <param name="stereotype">Optional stereotype of the boundary.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Boundary(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Boundary(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Boundary, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Boundary, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Boundary(this StringBuilder stringBuilder, string name, strin /// <param name="displayName">Optional display name of the boundary.</param> /// <param name="color">Optional color of the boundary.</param> /// <param name="order">Optional order of the boundary.</param> + /// <param name="stereotype">Optional stereotype of the boundary.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateBoundary(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateBoundary(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Boundary, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Boundary, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Collections.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Collections.cs index b477ad2..cf1f1bf 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Collections.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Collections.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the collections.</param> /// <param name="color">Optional color of the collections.</param> /// <param name="order">Optional order of the collections.</param> + /// <param name="stereotype">Optional stereotype of the collections.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Collections(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Collections(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Collections, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Collections, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Collections(this StringBuilder stringBuilder, string name, st /// <param name="displayName">Optional display name of the collections.</param> /// <param name="color">Optional color of the collections.</param> /// <param name="order">Optional order of the collections.</param> + /// <param name="stereotype">Optional stereotype of the collections.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateCollections(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateCollections(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Collections, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Collections, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Control.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Control.cs index fcf343a..0829cc6 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Control.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Control.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the control.</param> /// <param name="color">Optional color of the control.</param> /// <param name="order">Optional order of the control.</param> + /// <param name="stereotype">Optional stereotype of the control.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Control(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Control(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Control, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Control, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Control(this StringBuilder stringBuilder, string name, string /// <param name="displayName">Optional display name of the participant.</param> /// <param name="color">Optional color of the control.</param> /// <param name="order">Optional order of the control.</param> + /// <param name="stereotype">Optional stereotype of the control.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateControl(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateControl(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Control, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Control, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Database.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Database.cs index b4e1115..87bc5ef 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Database.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Database.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the database.</param> /// <param name="color">Optional color of the database.</param> /// <param name="order">Optional order of the database.</param> + /// <param name="stereotype">Optional stereotype of the database.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Database(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Database(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Database, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Database, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Database(this StringBuilder stringBuilder, string name, strin /// <param name="displayName">Optional display name of the database.</param> /// <param name="color">Optional color of the database.</param> /// <param name="order">Optional order of the database.</param> + /// <param name="stereotype">Optional stereotype of the database.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateDatabase(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateDatabase(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Database, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Database, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Entity.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Entity.cs index e211a44..5ed5503 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Entity.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Entity.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the entity.</param> /// <param name="color">Optional color of the entity.</param> /// <param name="order">Optional order of the entity.</param> + /// <param name="stereotype">Optional stereotype of the entity.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Entity(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Entity(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Entity, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Entity, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Entity(this StringBuilder stringBuilder, string name, string /// <param name="displayName">Optional display name of the entity.</param> /// <param name="color">Optional color of the entity.</param> /// <param name="order">Optional order of the entity.</param> + /// <param name="stereotype">Optional stereotype of the entity.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateEntity(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateEntity(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Entity, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Entity, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Participant.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Participant.cs index 81742e5..c06dcc5 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Participant.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Participant.cs @@ -9,11 +9,13 @@ public static partial class StringBuilderExtensions /// <param name="displayName">Optional display name of the participant.</param> /// <param name="color">Optional color of the participant.</param> /// <param name="order">Optional order of the participant.</param> + /// <param name="stereotype">Optional stereotype of the participant.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Participant(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Participant(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Participant, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Participant, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> @@ -23,10 +25,12 @@ public static void Participant(this StringBuilder stringBuilder, string name, st /// <param name="displayName">Optional display name of the participant.</param> /// <param name="color">Optional color of the participant.</param> /// <param name="order">Optional order of the participant.</param> + /// <param name="stereotype">Optional stereotype of the participant.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Create(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Create(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.None, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.None, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/ParticipantBase.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/ParticipantBase.cs index ebf266b..d246ec7 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/ParticipantBase.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/ParticipantBase.cs @@ -7,11 +7,13 @@ public static partial class StringBuilderExtensions /// </summary> /// <param name="participantType">The type of participant.</param> /// <param name="name">The name of the participant.</param> - /// <param name="color">Optional color for the participant.</param> - /// <param name="order">Optional order of the participant.</param> + /// <param name="color">Color for the participant.</param> + /// <param name="order">Order of the participant.</param> + /// <param name="stereotype">Stereotype of the participant.</param> + /// <param name="customSpot">Custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - internal static void ParticipantBase(this StringBuilder stringBuilder, ParticipantType participantType, ParticipantName name, Color color, int? order) + internal static void ParticipantBase(this StringBuilder stringBuilder, ParticipantType participantType, ParticipantName name, Color color, int? order, string stereotype, CustomSpot customSpot) { ArgumentNullException.ThrowIfNull(stringBuilder); @@ -23,6 +25,12 @@ internal static void ParticipantBase(this StringBuilder stringBuilder, Participa stringBuilder.Append(name); + if (stereotype is not null) + { + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.StereoType(stereotype, customSpot); + } + if (order.HasValue) { stringBuilder.Append(Constant.Symbols.Space); @@ -45,16 +53,18 @@ internal static void ParticipantBase(this StringBuilder stringBuilder, Participa /// </summary> /// <param name="name">The name of the participant.</param> /// <param name="participantType">The type of participant.</param> - /// <param name="color">Optional color for the participant.</param> - /// <param name="order">Optional order of the participant.</param> + /// <param name="color">Color for the participant.</param> + /// <param name="order">Order of the participant.</param> + /// <param name="stereotype">Stereotype of the participant.</param> + /// <param name="customSpot">Custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - internal static void CreateParticipantBase(this StringBuilder stringBuilder, ParticipantName name, ParticipantType participantType = ParticipantType.None, Color color = null, int? order = null) + internal static void CreateParticipantBase(this StringBuilder stringBuilder, ParticipantName name, ParticipantType participantType, Color color, int? order, string stereotype, CustomSpot customSpot) { ArgumentNullException.ThrowIfNull(stringBuilder); stringBuilder.Append(Constant.Words.Create); stringBuilder.Append(Constant.Symbols.Space); - stringBuilder.ParticipantBase(participantType, name, color, order); + stringBuilder.ParticipantBase(participantType, name, color, order, stereotype, customSpot); } } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Queue.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Queue.cs index c523d6e..8249927 100644 --- a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Queue.cs +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Queue.cs @@ -5,28 +5,32 @@ public static partial class StringBuilderExtensions /// <summary> /// Create a queue. /// </summary> - /// <param name="name">The name of the control.</param> - /// <param name="displayName">Optional display name of the control.</param> - /// <param name="color">Optional color of the control.</param> - /// <param name="order">Optional order of the control.</param> + /// <param name="name">The name of the queue.</param> + /// <param name="displayName">Optional display name of the queue.</param> + /// <param name="color">Optional color of the queue.</param> + /// <param name="order">Optional order of the queue.</param> + /// <param name="stereotype">Optional stereotype of the queue.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void Queue(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void Queue(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.ParticipantBase(ParticipantType.Queue, new ParticipantName(name, displayName), color, order); + stringBuilder.ParticipantBase(ParticipantType.Queue, new ParticipantName(name, displayName), color, order, stereotype, customSpot); } /// <summary> /// Create a queue. /// </summary> - /// <param name="name">The name of the control.</param> - /// <param name="displayName">Optional display name of the participant.</param> - /// <param name="color">Optional color of the control.</param> - /// <param name="order">Optional order of the control.</param> + /// <param name="name">The name of the queue.</param> + /// <param name="displayName">Optional display name of the queue.</param> + /// <param name="color">Optional color of the queue.</param> + /// <param name="order">Optional order of the queue.</param> + /// <param name="stereotype">Optional stereotype of the queue.</param> + /// <param name="customSpot">Optional custom spot of the stereotype.</param> /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> /// <exception cref="ArgumentException">Thrown when <paramref name="name"/> is <see langword="null"/>, empty of only white space.</exception> - public static void CreateQueue(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null) + public static void CreateQueue(this StringBuilder stringBuilder, string name, string displayName = null, Color color = null, int? order = null, string stereotype = default, CustomSpot customSpot = default) { - stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Queue, color, order); + stringBuilder.CreateParticipantBase(new ParticipantName(name, displayName), ParticipantType.Queue, color, order, stereotype, customSpot); } } diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index 4620864..ef5d960 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -1887,6 +1887,110 @@ public void ShortArrowsForIncomingAndOutgoingMessages() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#94190c2f242a5df2"/> + [TestMethod] + public void StereotypesAndSpots01() + { + // Arrange + var example = + """ + @startuml + + participant "Famous Bob" as Bob << Generated >> + participant Alice <<(C,#ADD1B2) Testable>> + + Bob -> Alice : First message + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.Participant("Bob", "Famous Bob", stereotype: " Generated "); + stringBuilder.Participant("Alice",stereotype: " Testable", customSpot: new CustomSpot('C', "#ADD1B2")); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Bob", "->", "Alice", "First message"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#94190c2f242a5df2"/> + [TestMethod] + public void StereotypesAndSpots02() + { + // Arrange + var example = + """ + @startuml + + skinparam guillemet false + participant "Famous Bob" as Bob << Generated >> + participant Alice <<(C,#ADD1B2) Testable>> + + Bob -> Alice : First message + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.SkinParameter("guillemet", false); + stringBuilder.Participant("Bob", "Famous Bob", stereotype: " Generated "); + stringBuilder.Participant("Alice", stereotype: " Testable", customSpot: new CustomSpot('C', "#ADD1B2")); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Bob", "->", "Alice", "First message"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#94190c2f242a5df2"/> + [TestMethod] + public void StereotypesAndSpots03() + { + // Arrange + var example = + """ + @startuml + + participant Bob <<(C,#ADD1B2) >> + participant Alice <<(C,#ADD1B2) >> + + Bob -> Alice : First message + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.Participant("Bob", stereotype: " ", customSpot: new CustomSpot('C', "#ADD1B2")); + stringBuilder.Participant("Alice", stereotype: " ", customSpot: new CustomSpot('C', "#ADD1B2")); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Bob", "->", "Alice", "First message"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + /// <seealso href=""/> [TestMethod] public void Template() diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ActorTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ActorTests.cs index fe2249a..2abdbdc 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ActorTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ActorTests.cs @@ -60,11 +60,15 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Actor", "actor \"Actor A\" as actorA", "actorA", "Actor A") }; yield return new object[] { new MethodExpectationTestData("Actor", "actor actorA #AliceBlue", "actorA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("Actor", "actor actorA order 10", "actorA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("Actor", "actor actorA <<Stereo>>", "actorA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Actor", "actor actorA <<(C,#336699)Stereo>>", "actorA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor actorA", "actorA") }; yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor \"Actor A\" as actor", "actor", "Actor A") }; yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor actorA #AliceBlue", "actorA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor actorA order 10", "actorA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor actorA <<Stereo>>", "actorA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateActor", "create actor actorA <<(C,#336699)Stereo>>", "actorA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/BoundaryTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/BoundaryTests.cs index 2f0d0d0..5440c77 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/BoundaryTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/BoundaryTests.cs @@ -60,11 +60,15 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Boundary", "boundary \"Boundary A\" as boundaryA", "boundaryA", "Boundary A") }; yield return new object[] { new MethodExpectationTestData("Boundary", "boundary boundaryA #AliceBlue", "boundaryA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("Boundary", "boundary boundaryA order 10", "boundaryA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("Boundary", "boundary boundaryA <<Stereo>>", "boundaryA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Boundary", "boundary boundaryA <<(C,#336699)Stereo>>", "boundaryA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary boundaryA", "boundaryA") }; yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary \"Boundary A\" as boundaryA", "boundaryA", "Boundary A") }; yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary boundaryA #AliceBlue", "boundaryA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary boundaryA order 10", "boundaryA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary boundaryA <<Stereo>>", "boundaryA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateBoundary", "create boundary boundaryA <<(C,#336699)Stereo>>", "boundaryA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CollectionsTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CollectionsTests.cs index 126834e..191684b 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CollectionsTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CollectionsTests.cs @@ -60,11 +60,15 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Collections", "collections \"Collections A\" as collectionsA", "collectionsA", "Collections A") }; yield return new object[] { new MethodExpectationTestData("Collections", "collections collectionsA #AliceBlue", "collectionsA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("Collections", "collections collectionsA order 10", "collectionsA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("Collections", "collections collectionsA <<Stereo>>", "collectionsA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Collections", "collections collectionsA <<(C,#336699)Stereo>>", "collectionsA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections collectionsA", "collectionsA") }; yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections \"Collections A\" as collectionsA", "collectionsA", "Collections A") }; yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections collectionsA #AliceBlue", "collectionsA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections collectionsA order 10", "collectionsA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections collectionsA <<Stereo>>", "collectionsA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateCollections", "create collections collectionsA <<(C,#336699)Stereo>>", "collectionsA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CreateTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CreateTests.cs index f2c47c9..4810d6d 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CreateTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/CreateTests.cs @@ -56,7 +56,9 @@ private static IEnumerable<object[]> GetValidNotations() { yield return new object[] { new MethodExpectationTestData("Create", "create actorA", "actorA").WithDisplayName("Create - Default create line") }; yield return new object[] { new MethodExpectationTestData("Create", "create actorA order 10", "actorA", null, null, 10).WithDisplayName("Create - Create line with order") }; - } + yield return new object[] { new MethodExpectationTestData("Create", "create actorA <<Stereo>>", "actorA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Create", "create actorA <<(C,#336699)Stereo>>", "actorA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; + } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); } diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/DatabaseTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/DatabaseTests.cs index 8faf4ad..bbc94ac 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/DatabaseTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/DatabaseTests.cs @@ -60,11 +60,15 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Database", "database \"Database A\" as databaseA", "databaseA", "Database A") }; yield return new object[] { new MethodExpectationTestData("Database", "database databaseA #AliceBlue", "databaseA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("Database", "database databaseA order 10", "databaseA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("Database", "database databaseA <<Stereo>>", "databaseA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Database", "database databaseA <<(C,#336699)Stereo>>", "databaseA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database databaseA", "databaseA") }; yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database \"Database A\" as databaseA", "databaseA", "Database A") }; yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database databaseA #AliceBlue", "databaseA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database databaseA order 10", "databaseA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database databaseA <<Stereo>>", "databaseA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateDatabase", "create database databaseA <<(C,#336699)Stereo>>", "databaseA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/EntityTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/EntityTests.cs index 21c372d..e6b7ba4 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/EntityTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/EntityTests.cs @@ -60,11 +60,15 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Entity", "entity \"Entity A\" as entityA", "entityA", "Entity A") }; yield return new object[] { new MethodExpectationTestData("Entity", "entity entityA #AliceBlue", "entityA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("Entity", "entity entityA order 10", "entityA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("Entity", "entity entityA <<Stereo>>", "entityA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Entity", "entity entityA <<(C,#336699)Stereo>>", "entityA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity entityA", "entityA") }; yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity \"Entity A\" as entityA", "entityA", "Entity A") }; yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity entityA #AliceBlue", "entityA", null, (Color)"AliceBlue") }; yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity entityA order 10", "entityA", null, null, 10) }; + yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity entityA <<Stereo>>", "entityA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateEntity", "create entity entityA <<(C,#336699)Stereo>>", "entityA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ParticipantTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ParticipantTests.cs index 0ab05b4..5310c7c 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ParticipantTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/ParticipantTests.cs @@ -59,6 +59,8 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Participant", "participant actorA #AliceBlue", "actorA", null, (Color)"AliceBlue").WithDisplayName("Participant - With color") }; yield return new object[] { new MethodExpectationTestData("Participant", "participant actorA #AliceBlue", "actorA", null, (Color)"#AliceBlue").WithDisplayName("Participant - With color (with hashtag)") }; yield return new object[] { new MethodExpectationTestData("Participant", "participant actorA order 10", "actorA", null, null, 10).WithDisplayName("Participant - With order") }; + yield return new object[] { new MethodExpectationTestData("Participant", "participant actorA <<Stereo>>", "actorA", null, null, null, "Stereo").WithDisplayName("Participant - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Participant", "participant actorA <<(C,#336699)Stereo>>", "actorA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Participant - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/QueueTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/QueueTests.cs index 4055455..8820ae0 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/QueueTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/QueueTests.cs @@ -60,11 +60,16 @@ private static IEnumerable<object[]> GetValidNotations() yield return new object[] { new MethodExpectationTestData("Queue", "queue \"Queue A\" as queueA", "queueA", "Queue A").WithDisplayName("Queue - With display name") }; yield return new object[] { new MethodExpectationTestData("Queue", "queue queueA #AliceBlue", "queueA", null, (Color)"AliceBlue").WithDisplayName("Queue - With color") }; yield return new object[] { new MethodExpectationTestData("Queue", "queue queueA order 10", "queueA", null, null, 10).WithDisplayName("Queue - With order 10") }; + yield return new object[] { new MethodExpectationTestData("Queue", "queue queueA <<Stereo>>", "queueA", null, null, null, "Stereo").WithDisplayName("Queue - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("Queue", "queue queueA <<(C,#336699)Stereo>>", "queueA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("Queue - With custom spot") }; + yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue queueA", "queueA").WithDisplayName("CreateQueue - Basic notation") }; yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue \"Queue A\" as queueA", "queueA", "Queue A").WithDisplayName("CreateQueue - With display name") }; yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue queueA #AliceBlue", "queueA", null, (Color)"AliceBlue").WithDisplayName("CreateQueue - With color") }; yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue queueA order 10", "queueA", null, null, 10).WithDisplayName("CreateQueue - With order 10") }; + yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue queueA <<Stereo>>", "queueA", null, null, null, "Stereo").WithDisplayName("CreateQueue - With sterotype") }; + yield return new object[] { new MethodExpectationTestData("CreateQueue", "create queue queueA <<(C,#336699)Stereo>>", "queueA", null, null, null, "Stereo", new CustomSpot('C', "336699")).WithDisplayName("CreateQueue - With custom spot") }; } public static string GetValidNotationTestDisplayName(MethodInfo _, object[] data) => TestHelpers.GetValidNotationTestDisplayName(data); From 4505cc667a504c51a0fe7aa825a573d13695fe5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Mon, 4 Sep 2023 22:10:42 +0200 Subject: [PATCH 05/10] Add title examples and fix newlines in title --- .../StringBuilderExtensions/Title.cs | 2 +- .../SequenceDiagramExampleTests.cs | 69 +++++++++++++++++++ .../StringBuilderExtensions/TitleTests.cs | 8 ++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/src/PlantUml.Builder/StringBuilderExtensions/Title.cs b/src/PlantUml.Builder/StringBuilderExtensions/Title.cs index b3b98ed..e009ebc 100644 --- a/src/PlantUml.Builder/StringBuilderExtensions/Title.cs +++ b/src/PlantUml.Builder/StringBuilderExtensions/Title.cs @@ -15,7 +15,7 @@ public static void Title(this StringBuilder stringBuilder, string title) stringBuilder.Append(Constant.Words.Title); stringBuilder.Append(Constant.Symbols.Space); - stringBuilder.Append(title); + stringBuilder.Append(title.Replace("\n", "\\n")); stringBuilder.AppendNewLine(); } } diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index ef5d960..f665a6d 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -1991,6 +1991,75 @@ public void StereotypesAndSpots03() stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#a21f56b1869e89e5"/> + [TestMethod] + public void MoreInformationOnTitles01() + { + // Arrange + var example = + """ + @startuml + + title __Simple__ **communication** example + + Alice -> Bob : Authentication Request + Bob -> Alice : Authentication Response + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.Title("__Simple__ **communication** example"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Alice", "->", "Bob", "Authentication Request"); + stringBuilder.Arrow("Bob", "->", "Alice", "Authentication Response"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#a21f56b1869e89e5"/> + [TestMethod] + public void MoreInformationOnTitles02() + { + // Arrange + var example = + """ + @startuml + + title __Simple__ communication example\non several lines + + Alice -> Bob : Authentication Request + Bob -> Alice : Authentication Response + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.Title("__Simple__ communication example\non several lines"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Alice", "->", "Bob", "Authentication Request"); + stringBuilder.Arrow("Bob", "->", "Alice", "Authentication Response"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href=""/> [TestMethod] public void Template() diff --git a/tests/PlantUml.Builder.Tests/StringBuilderExtensions/TitleTests.cs b/tests/PlantUml.Builder.Tests/StringBuilderExtensions/TitleTests.cs index c8a31ba..1de74a0 100644 --- a/tests/PlantUml.Builder.Tests/StringBuilderExtensions/TitleTests.cs +++ b/tests/PlantUml.Builder.Tests/StringBuilderExtensions/TitleTests.cs @@ -37,16 +37,18 @@ public void TextMustContainAValue(string text) .WithParameterName("title"); } + [DataRow("Title", "title Title", DisplayName = "Title - Simple title")] + [DataRow("Title\nNewLine", "title Title\\nNewLine", DisplayName = "Title - Newlines are escaped")] [TestMethod] - public void TitleIsRenderedCorrectly() + public void TitleIsRenderedCorrectly(string title, string expected) { // Arrange var stringBuilder = new StringBuilder(); // Act - stringBuilder.Title("Title"); + stringBuilder.Title(title); // Assert - stringBuilder.ToString().Should().Be("title Title\n"); + stringBuilder.ToString().Should().Be($"{expected}\n"); } } From d3344a2a893ff2c5021b64182ffca023f66de128 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Tue, 5 Sep 2023 20:49:47 +0200 Subject: [PATCH 06/10] Add show/hide footbox commands --- docs/commands.md | 4 +- src/PlantUml.Builder/Constant.cs | 2 + .../StringBuilderExtensions/FootBox.cs | 32 ++++++++++++++++ .../SequenceDiagramExampleTests.cs | 37 +++++++++++++++++++ .../StringBuilderExtensions/FootBoxTests.cs | 31 ++++++++++++++++ .../StringBuilderExtensionMethodTests.cs | 2 + 6 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/FootBox.cs create mode 100644 tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/FootBoxTests.cs diff --git a/docs/commands.md b/docs/commands.md index d017fc0..8d98de6 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -102,8 +102,8 @@ Following the PlantUML source code. | end box | yes | `BoxEnd` | | delay [\<LABEL>] | yes | `Delay` | | divider [\<LABEL>] | yes | `Divider` | -| hide footbox | no | | -| show footbox | no | | +| hide footbox | yes | `HideFootBox` | +| show footbox | yes | `ShowFootBox` | | opt [\<COLOR>] [\<COMMENT>] | no | | | end | yes | `GroupEnd` | | alt [\<COLOR>] [\<COMMENT>] | partial | `AltStart` | diff --git a/src/PlantUml.Builder/Constant.cs b/src/PlantUml.Builder/Constant.cs index 86b39a5..2b276a1 100644 --- a/src/PlantUml.Builder/Constant.cs +++ b/src/PlantUml.Builder/Constant.cs @@ -72,6 +72,7 @@ public static class Words public const string Empty = "empty"; public const string End = "end"; public const string Extends = "extends"; + public const string Footbox = "footbox"; public const string Footer = "footer"; public const string Group = "group"; public const string Header = "header"; @@ -97,6 +98,7 @@ public static class Words public const string Return = "return"; public const string Separator = "separator"; public const string Set = "set"; + public const string Show = "show"; public const string SkinParam = "skinparam"; public const string Start = "start"; public const string Static = "static"; diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/FootBox.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/FootBox.cs new file mode 100644 index 0000000..37444d7 --- /dev/null +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/FootBox.cs @@ -0,0 +1,32 @@ +namespace PlantUml.Builder.SequenceDiagrams; + +public static partial class StringBuilderExtensions +{ + /// <summary> + /// Renders the hide foot box command. + /// </summary> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> + public static void HideFootBox(this StringBuilder stringBuilder) + { + ArgumentNullException.ThrowIfNull(stringBuilder); + + stringBuilder.Append(Constant.Words.Hide); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Footbox); + stringBuilder.AppendNewLine(); + } + + /// <summary> + /// Renders the show foot box command. + /// </summary> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> + public static void ShowFootBox(this StringBuilder stringBuilder) + { + ArgumentNullException.ThrowIfNull(stringBuilder); + + stringBuilder.Append(Constant.Words.Show); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Footbox); + stringBuilder.AppendNewLine(); + } +} diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index f665a6d..e25ec10 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -2059,6 +2059,43 @@ title __Simple__ communication example\non several lines stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#21380379ba44081d"/> + [TestMethod] + public void RemovingFootBoxes() + { + // Arrange + var example = + """ + @startuml + + hide footbox + title Foot Box removed + + Alice -> Bob : Authentication Request + Bob --> Alice : Authentication Response + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.HideFootBox(); + stringBuilder.Title("Foot Box removed"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Alice", "->", "Bob", "Authentication Request"); + stringBuilder.Arrow("Bob", "-->", "Alice", "Authentication Response"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href=""/> [TestMethod] diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/FootBoxTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/FootBoxTests.cs new file mode 100644 index 0000000..78cc5a9 --- /dev/null +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/FootBoxTests.cs @@ -0,0 +1,31 @@ +namespace PlantUml.Builder.SequenceDiagrams.Tests; + +[TestClass] +public class FootBoxTests +{ + [TestMethod] + public void HideFootboxIsRenderedCorrectly() + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.HideFootBox(); + + // Assert + stringBuilder.ToString().Should().Be("hide footbox\n"); + } + + [TestMethod] + public void ShowFootboxIsRenderedCorrectly() + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.ShowFootBox(); + + // Assert + stringBuilder.ToString().Should().Be("show footbox\n"); + } +} diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs index 29394ab..57074d9 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs @@ -52,6 +52,7 @@ private static IEnumerable<object[]> GetStringBuilderExtensionMethods() yield return new object[] { new MethodWithArgumentData("EndLoop") }; yield return new object[] { new MethodWithArgumentData("EndRef") }; yield return new object[] { new MethodWithArgumentData("Entity", AnyString) }; + yield return new object[] { new MethodWithArgumentData("HideFootBox") }; yield return new object[] { new MethodWithArgumentData("GroupEnd") }; yield return new object[] { new MethodWithArgumentData("GroupStart") }; yield return new object[] { new MethodWithArgumentData("IncreaseAutoNumber") }; @@ -64,6 +65,7 @@ private static IEnumerable<object[]> GetStringBuilderExtensionMethods() yield return new object[] { new MethodWithArgumentData("ResumeAutoNumber") }; yield return new object[] { new MethodWithArgumentData("Return") }; yield return new object[] { new MethodWithArgumentData("Return", AnyString) }; + yield return new object[] { new MethodWithArgumentData("ShowFootBox") }; yield return new object[] { new MethodWithArgumentData("Space") }; yield return new object[] { new MethodWithArgumentData("StartLoop") }; yield return new object[] { new MethodWithArgumentData("StartRef", AnyString) }; From b83ba728193a0f4073dc221fc480b550fbcb76a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Tue, 5 Sep 2023 20:50:14 +0200 Subject: [PATCH 07/10] Add more examples --- docs/commands.md | 2 + .../ObjectDiagramExampleTests.cs | 40 ++ .../SequenceDiagramExampleTests.cs | 594 ++++++++++++++++++ 3 files changed, 636 insertions(+) diff --git a/docs/commands.md b/docs/commands.md index 8d98de6..8fecfc9 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -29,6 +29,8 @@ Following the PlantUML source code. | caption \<CAPTION> | no | | | legend [\<ALIGN>] | no | | | endlegend | no | | +| skinparam \<NAME> \<VALUE> | yes | `SkinParam` | +| skinparam \<PREFIX> { | no | | ## Activity Diagrams diff --git a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs index 9c7fedd..44ae1b5 100644 --- a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs @@ -365,4 +365,44 @@ map CapitalCity { // Assert stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + + /// <seealso href="https://plantuml.com/object-diagram#6c738a9019f7ac08"/> + [TestMethod] + public void MapTableOrAssociativeArray06() + { + // Arrange + var example = + """ + @startuml + object Foo + map Bar { + abc=> + def=> + } + object Baz + + Bar::abc --> Baz : Label one + Foo --> Bar::def : Label two + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Object("Foo"); + stringBuilder.MapStart("Bar"); + stringBuilder.InlineClassMember("abc=>"); + stringBuilder.InlineClassMember("def=>"); + stringBuilder.MapEnd(); + stringBuilder.Object("Baz"); + stringBuilder.AppendNewLine(); + stringBuilder.Relationship("Bar::abc", "-->", "Baz", "Label one"); + stringBuilder.Relationship("Foo", "-->", "Bar::def", "Label two"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } } diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index e25ec10..1f78b05 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -2059,6 +2059,102 @@ title __Simple__ communication example\non several lines stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#f52672a8f74a07df"/> + [TestMethod] + public void ParticipantsEncompass01() + { + // Arrange + var example = + """ + @startuml + + box "Internal Service" #LightBlue + participant Bob + participant Alice + end box + participant Other + + Bob -> Alice : hello + Alice -> Other : hello + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.BoxStart("Internal Service", "#LightBlue"); + stringBuilder.Participant("Bob"); + stringBuilder.Participant("Alice"); + stringBuilder.BoxEnd(); + stringBuilder.Participant("Other"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "Other", "hello"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#f52672a8f74a07df"/> + [TestMethod] + public void ParticipantsEncompass02() + { + // Arrange + var example = + """ + @startuml + + !pragma teoz true + box "Internal Service" #LightBlue + participant Bob + box "Subteam" + participant Alice + participant John + end box + + end box + participant Other + + Bob -> Alice : hello + Alice -> John : hello + John -> Other : Hello + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.AppendNewLine(); + stringBuilder.Text("!pragma teoz true"); + stringBuilder.BoxStart("Internal Service", "#LightBlue"); + stringBuilder.Participant("Bob"); + stringBuilder.BoxStart("Subteam"); + stringBuilder.Participant("Alice"); + stringBuilder.Participant("John"); + stringBuilder.BoxEnd(); + stringBuilder.AppendNewLine(); + stringBuilder.BoxEnd(); + stringBuilder.Participant("Other"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "John", "hello"); + stringBuilder.Arrow("John", "->", "Other", "Hello"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + /// <seealso href="https://plantuml.com/sequence-diagram#21380379ba44081d"/> [TestMethod] public void RemovingFootBoxes() @@ -2095,8 +2191,506 @@ title Foot Box removed stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#7aa53dbdfc2137bf"/> + [TestMethod] + public void Skinparam01() + { + // Arrange + var example = + """ + @startuml + skinparam sequenceArrowThickness 2 + skinparam roundcorner 20 + skinparam maxmessagesize 60 + skinparam sequenceParticipant underline + + actor User + participant "First Class" as A + participant "Second Class" as B + participant "Last Class" as C + + User -> A : DoWork + activate A + + A -> B : Create Request + activate B + + B -> C : DoWork + activate C + C --> B : WorkDone + destroy C + + B --> A : Request Created + deactivate B + + A --> User : Done + deactivate A + + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.SkinParameter("sequenceArrowThickness", 2); + stringBuilder.SkinParameter("roundcorner", 20); + stringBuilder.SkinParameter("maxmessagesize", 60); + stringBuilder.SkinParameter("sequenceParticipant", "underline"); + stringBuilder.AppendNewLine(); + stringBuilder.Actor("User"); + stringBuilder.Participant("A", "First Class"); + stringBuilder.Participant("B", "Second Class"); + stringBuilder.Participant("C", "Last Class"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("User", "->", "A", "DoWork"); + stringBuilder.Activate("A"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("A", "->", "B", "Create Request"); + stringBuilder.Activate("B"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("B", "->", "C", "DoWork"); + stringBuilder.Activate("C"); + stringBuilder.Arrow("C", "-->", "B", "WorkDone"); + stringBuilder.Destroy("C"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("B", "-->", "A", "Request Created"); + stringBuilder.Deactivate("B"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("A", "-->", "User", "Done"); + stringBuilder.Deactivate("A"); + stringBuilder.AppendNewLine(); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#33cee7c2521befd3"/> + [TestMethod] + public void ChangingPadding() + { + // Arrange + var example = + """ + @startuml + skinparam ParticipantPadding 20 + skinparam BoxPadding 10 + + box "Foo1" + participant Alice1 + participant Alice2 + end box + box "Foo2" + participant Bob1 + participant Bob2 + end box + Alice1 -> Bob1 : hello + Alice1 -> Out : out + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.SkinParameter(SkinParameter.ParticipantPadding, 20); + stringBuilder.SkinParameter(SkinParameter.BoxPadding, 10); + stringBuilder.AppendNewLine(); + stringBuilder.BoxStart("Foo1"); + stringBuilder.Participant("Alice1"); + stringBuilder.Participant("Alice2"); + stringBuilder.BoxEnd(); + stringBuilder.BoxStart("Foo2"); + stringBuilder.Participant("Bob1"); + stringBuilder.Participant("Bob2"); + stringBuilder.BoxEnd(); + stringBuilder.Arrow("Alice1", "->", "Bob1", "hello"); + stringBuilder.Arrow("Alice1", "->", "Out", "out"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#4764f83f72ed032f"/> + [TestMethod] + public void ExamplesOfAllArrowType_NormalArrow() + { + // Arrange + var example = + """ + @startuml + participant Alice as a + participant Bob as b + a -> b : ""-> "" + a ->> b : ""->> "" + a -\ b : ""-\ "" + a -\\ b : ""-\\\\"" + a -/ b : ""-/ "" + a -// b : ""-// "" + a ->x b : ""->x "" + a x-> b : ""x-> "" + a o-> b : ""o-> "" + a ->o b : ""->o "" + a o->o b : ""o->o "" + a <-> b : ""<-> "" + a o<->o b : ""o<->o"" + a x<->x b : ""x<->x"" + a ->>o b : ""->>o "" + a -\o b : ""-\o "" + a -\\o b : ""-\\\\o"" + a -/o b : ""-/o "" + a -//o b : ""-//o "" + a x->o b : ""x->o "" + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Participant("a", "Alice"); + stringBuilder.Participant("b", "Bob"); + stringBuilder.Arrow("a", Arrow.AsyncRight, "b", "\"\"-> \"\""); + stringBuilder.Arrow("a", Arrow.ThinRight, "b", "\"\"->> \"\""); + stringBuilder.Arrow("a", Arrow.TopRight, "b", "\"\"-\\ \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight, "b", "\"\"-\\\\\\\\\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight, "b", "\"\"-/ \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight, "b", "\"\"-// \"\""); + stringBuilder.Arrow("a", Arrow.Right.Destroy(), "b", "\"\"->x \"\""); + stringBuilder.Arrow("a", "x->", "b", "\"\"x-> \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft(), "b", "\"\"o-> \"\""); + stringBuilder.Arrow("a", Arrow.Right.Lost(), "b", "\"\"->o \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft().LostRight(), "b", "\"\"o->o \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight, "b", "\"\"<-> \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight.LostLeft().LostRight(), "b", "\"\"o<->o\"\""); + stringBuilder.Arrow("a", "x<->x", "b", "\"\"x<->x\"\""); + stringBuilder.Arrow("a", Arrow.ThinRight.Lost(), "b", "\"\"->>o \"\""); + stringBuilder.Arrow("a", Arrow.TopRight.Lost(), "b", "\"\"-\\o \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight.Lost(), "b", "\"\"-\\\\\\\\o\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight.Lost(), "b", "\"\"-/o \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight.Lost(), "b", "\"\"-//o \"\""); + stringBuilder.Arrow("a", "x->o", "b", "\"\"x->o \"\""); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#4764f83f72ed032f"/> + [TestMethod] + public void ExamplesOfAllArrowType_ItselfArrow() + { + // Arrange + var example = + """ + @startuml + participant Alice as a + participant Bob as b + a -> a : ""-> "" + a ->> a : ""->> "" + a -\ a : ""-\ "" + a -\\ a : ""-\\\\"" + a -/ a : ""-/ "" + a -// a : ""-// "" + a ->x a : ""->x "" + a x-> a : ""x-> "" + a o-> a : ""o-> "" + a ->o a : ""->o "" + a o->o a : ""o->o "" + a <-> a : ""<-> "" + a o<->o a : ""o<->o"" + a x<->x a : ""x<->x"" + a ->>o a : ""->>o "" + a -\o a : ""-\o "" + a -\\o a : ""-\\\\o"" + a -/o a : ""-/o "" + a -//o a : ""-//o "" + a x->o a : ""x->o "" + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Participant("a", "Alice"); + stringBuilder.Participant("b", "Bob"); + stringBuilder.Arrow("a", Arrow.AsyncRight, "a", "\"\"-> \"\""); + stringBuilder.Arrow("a", Arrow.ThinRight, "a", "\"\"->> \"\""); + stringBuilder.Arrow("a", Arrow.TopRight, "a", "\"\"-\\ \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight, "a", "\"\"-\\\\\\\\\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight, "a", "\"\"-/ \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight, "a", "\"\"-// \"\""); + stringBuilder.Arrow("a", Arrow.Right.Destroy(), "a", "\"\"->x \"\""); + stringBuilder.Arrow("a", "x->", "a", "\"\"x-> \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft(), "a", "\"\"o-> \"\""); + stringBuilder.Arrow("a", Arrow.Right.Lost(), "a", "\"\"->o \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft().LostRight(), "a", "\"\"o->o \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight, "a", "\"\"<-> \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight.LostLeft().LostRight(), "a", "\"\"o<->o\"\""); + stringBuilder.Arrow("a", "x<->x", "a", "\"\"x<->x\"\""); + stringBuilder.Arrow("a", Arrow.ThinRight.Lost(), "a", "\"\"->>o \"\""); + stringBuilder.Arrow("a", Arrow.TopRight.Lost(), "a", "\"\"-\\o \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight.Lost(), "a", "\"\"-\\\\\\\\o\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight.Lost(), "a", "\"\"-/o \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight.Lost(), "a", "\"\"-//o \"\""); + stringBuilder.Arrow("a", "x->o", "a", "\"\"x->o \"\""); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#4764f83f72ed032f"/> + [TestMethod] + public void ExamplesOfAllArrowType_IncomingMessages() + { + // Arrange + var example = + """ + @startuml + participant Alice as a + participant Bob as b + [-> b : ""[-> "" + [->> b : ""[->> "" + [-\ b : ""[-\ "" + [-\\ b : ""[-\\\\"" + [-/ b : ""[-/ "" + [-// b : ""[-// "" + [->x b : ""[->x "" + [x-> b : ""[x-> "" + [o-> b : ""[o-> "" + [->o b : ""[->o "" + [o->o b : ""[o->o "" + [<-> b : ""[<-> "" + [o<->o b : ""[o<->o"" + [x<->x b : ""[x<->x"" + [->>o b : ""[->>o "" + [-\o b : ""[-\o "" + [-\\o b : ""[-\\\\o"" + [-/o b : ""[-/o "" + [-//o b : ""[-//o "" + [x->o b : ""[x->o "" + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Participant("a", "Alice"); + stringBuilder.Participant("b", "Bob"); + stringBuilder.Arrow(Participant.Outside, Arrow.AsyncRight, "b", "\"\"[-> \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinRight, "b", "\"\"[->> \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.TopRight, "b", "\"\"[-\\ \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinTopRight, "b", "\"\"[-\\\\\\\\\"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.BottomRight, "b", "\"\"[-/ \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinBottomRight, "b", "\"\"[-// \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.Right.Destroy(), "b", "\"\"[->x \"\""); + stringBuilder.Arrow(Participant.Outside, "x->", "b", "\"\"[x-> \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.Right.LostLeft(), "b", "\"\"[o-> \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.Right.Lost(), "b", "\"\"[->o \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.Right.LostLeft().LostRight(), "b", "\"\"[o->o \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.LeftRight, "b", "\"\"[<-> \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.LeftRight.LostLeft().LostRight(), "b", "\"\"[o<->o\"\""); + stringBuilder.Arrow(Participant.Outside, "x<->x", "b", "\"\"[x<->x\"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinRight.Lost(), "b", "\"\"[->>o \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.TopRight.Lost(), "b", "\"\"[-\\o \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinTopRight.Lost(), "b", "\"\"[-\\\\\\\\o\"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.BottomRight.Lost(), "b", "\"\"[-/o \"\""); + stringBuilder.Arrow(Participant.Outside, Arrow.ThinBottomRight.Lost(), "b", "\"\"[-//o \"\""); + stringBuilder.Arrow(Participant.Outside, "x->o", "b", "\"\"[x->o \"\""); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#4764f83f72ed032f"/> + [TestMethod] + public void ExamplesOfAllArrowType_OutgoingMessages() + { + // Arrange + var example = + """ + @startuml + participant Alice as a + participant Bob as b + a ->] : ""->] "" + a ->>] : ""->>] "" + a -\] : ""-\] "" + a -\\] : ""-\\\\]"" + a -/] : ""-/] "" + a -//] : ""-//] "" + a ->x] : ""->x] "" + a x->] : ""x->] "" + a o->] : ""o->] "" + a ->o] : ""->o] "" + a o->o] : ""o->o] "" + a <->] : ""<->] "" + a o<->o] : ""o<->o]"" + a x<->x] : ""x<->x]"" + a ->>o] : ""->>o] "" + a -\o] : ""-\o] "" + a -\\o] : ""-\\\\o]"" + a -/o] : ""-/o] "" + a -//o] : ""-//o] "" + a x->o] : ""x->o] "" + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Participant("a", "Alice"); + stringBuilder.Participant("b", "Bob"); + stringBuilder.Arrow("a", Arrow.AsyncRight, Participant.Outside, "\"\"->] \"\""); + stringBuilder.Arrow("a", Arrow.ThinRight, Participant.Outside, "\"\"->>] \"\""); + stringBuilder.Arrow("a", Arrow.TopRight, Participant.Outside, "\"\"-\\] \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight, Participant.Outside, "\"\"-\\\\\\\\]\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight, Participant.Outside, "\"\"-/] \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight, Participant.Outside, "\"\"-//] \"\""); + stringBuilder.Arrow("a", Arrow.Right.Destroy(), Participant.Outside, "\"\"->x] \"\""); + stringBuilder.Arrow("a", "x->", Participant.Outside, "\"\"x->] \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft(), Participant.Outside, "\"\"o->] \"\""); + stringBuilder.Arrow("a", Arrow.Right.Lost(), Participant.Outside, "\"\"->o] \"\""); + stringBuilder.Arrow("a", Arrow.Right.LostLeft().LostRight(), Participant.Outside, "\"\"o->o] \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight, Participant.Outside, "\"\"<->] \"\""); + stringBuilder.Arrow("a", Arrow.LeftRight.LostLeft().LostRight(), Participant.Outside, "\"\"o<->o]\"\""); + stringBuilder.Arrow("a", "x<->x", Participant.Outside, "\"\"x<->x]\"\""); + stringBuilder.Arrow("a", Arrow.ThinRight.Lost(), Participant.Outside, "\"\"->>o] \"\""); + stringBuilder.Arrow("a", Arrow.TopRight.Lost(), Participant.Outside, "\"\"-\\o] \"\""); + stringBuilder.Arrow("a", Arrow.ThinTopRight.Lost(), Participant.Outside, "\"\"-\\\\\\\\o]\"\""); + stringBuilder.Arrow("a", Arrow.BottomRight.Lost(), Participant.Outside, "\"\"-/o] \"\""); + stringBuilder.Arrow("a", Arrow.ThinBottomRight.Lost(), Participant.Outside, "\"\"-//o] \"\""); + stringBuilder.Arrow("a", "x->o", Participant.Outside, "\"\"x->o] \"\""); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#75b4984abd04b14f"/> + [TestMethod] + public void SpecificSkinParameter_Default() + { + // Arrange + var example = + """ + @startuml + Bob -> Alice : hello + Alice -> Bob : ok + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "Bob", "ok"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#75b4984abd04b14f"/> + [TestMethod] + public void SpecificSkinParameter_LifelineStrategy01() + { + // Arrange + var example = + """ + @startuml + skinparam lifelineStrategy nosolid + Bob -> Alice : hello + Alice -> Bob : ok + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.SkinParameter("lifelineStrategy", "nosolid"); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "Bob", "ok"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#75b4984abd04b14f"/> + [TestMethod] + public void SpecificSkinParameter_LifelineStrategy02() + { + // Arrange + var example = + """ + @startuml + skinparam lifelineStrategy solid + Bob -> Alice : hello + Alice -> Bob : ok + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.SkinParameter("lifelineStrategy", "solid"); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "Bob", "ok"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#75b4984abd04b14f"/> + [TestMethod] + public void SpecificSkinParameter_StyleStrictuml() + { + // Arrange + var example = + """ + @startuml + skinparam style strictuml + Bob -> Alice : hello + Alice -> Bob : ok + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.SkinParameter("style", "strictuml"); + stringBuilder.Arrow("Bob", "->", "Alice", "hello"); + stringBuilder.Arrow("Alice", "->", "Bob", "ok"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + /// <seealso href=""/> [TestMethod] public void Template() From 31b9dedddfdcc27151bd9f01d730d2f294a8ff25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Tue, 5 Sep 2023 21:12:38 +0200 Subject: [PATCH 08/10] Add show/hide unlinked commands --- docs/commands.md | 2 + src/PlantUml.Builder/Constant.cs | 1 + .../StringBuilderExtensions/Unlinked.cs | 32 +++++++++ .../SequenceDiagramExampleTests.cs | 66 +++++++++++++++++++ .../StringBuilderExtensionMethodTests.cs | 2 + .../StringBuilderExtensions/UnlinkedTests.cs | 31 +++++++++ 6 files changed, 134 insertions(+) create mode 100644 src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Unlinked.cs create mode 100644 tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/UnlinkedTests.cs diff --git a/docs/commands.md b/docs/commands.md index 8fecfc9..ae9ba3c 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -106,6 +106,8 @@ Following the PlantUML source code. | divider [\<LABEL>] | yes | `Divider` | | hide footbox | yes | `HideFootBox` | | show footbox | yes | `ShowFootBox` | +| hide unlinked | yes | `HideUnlinked` | +| show unlinked | yes | `ShowUnlinked` | | opt [\<COLOR>] [\<COMMENT>] | no | | | end | yes | `GroupEnd` | | alt [\<COLOR>] [\<COMMENT>] | partial | `AltStart` | diff --git a/src/PlantUml.Builder/Constant.cs b/src/PlantUml.Builder/Constant.cs index 2b276a1..5d331f5 100644 --- a/src/PlantUml.Builder/Constant.cs +++ b/src/PlantUml.Builder/Constant.cs @@ -104,6 +104,7 @@ public static class Words public const string Static = "static"; public const string Stop = "stop"; public const string Title = "title"; + public const string Unlinked = "unlinked"; public const string Uml = "uml"; } diff --git a/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Unlinked.cs b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Unlinked.cs new file mode 100644 index 0000000..0425b48 --- /dev/null +++ b/src/PlantUml.Builder/SequenceDiagrams/StringBuilderExtensions/Unlinked.cs @@ -0,0 +1,32 @@ +namespace PlantUml.Builder.SequenceDiagrams; + +public static partial class StringBuilderExtensions +{ + /// <summary> + /// Renders the hide unlinked command. + /// </summary> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> + public static void HideUnlinked(this StringBuilder stringBuilder) + { + ArgumentNullException.ThrowIfNull(stringBuilder); + + stringBuilder.Append(Constant.Words.Hide); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Unlinked); + stringBuilder.AppendNewLine(); + } + + /// <summary> + /// Renders the show unlinked command. + /// </summary> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> + public static void ShowUnlinked(this StringBuilder stringBuilder) + { + ArgumentNullException.ThrowIfNull(stringBuilder); + + stringBuilder.Append(Constant.Words.Show); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Unlinked); + stringBuilder.AppendNewLine(); + } +} diff --git a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs index 1f78b05..1f25db0 100644 --- a/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/SequenceDiagramExampleTests.cs @@ -2691,6 +2691,72 @@ skinparam style strictuml stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + /// <seealso href="https://plantuml.com/sequence-diagram#fc006eba0d9dcacc"/> + [TestMethod] + public void HideUnlinkedParticipant01() + { + // Arrange + var example = + """ + @startuml + participant Alice + participant Bob + participant Carol + + Alice -> Bob : hello + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.Participant("Alice"); + stringBuilder.Participant("Bob"); + stringBuilder.Participant("Carol"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Alice", "->", "Bob", "hello"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + + /// <seealso href="https://plantuml.com/sequence-diagram#fc006eba0d9dcacc"/> + [TestMethod] + public void HideUnlinkedParticipant02() + { + // Arrange + var example = + """ + @startuml + hide unlinked + participant Alice + participant Bob + participant Carol + + Alice -> Bob : hello + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart(); + stringBuilder.HideUnlinked(); + stringBuilder.Participant("Alice"); + stringBuilder.Participant("Bob"); + stringBuilder.Participant("Carol"); + stringBuilder.AppendNewLine(); + stringBuilder.Arrow("Alice", "->", "Bob", "hello"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } + /// <seealso href=""/> [TestMethod] public void Template() diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs index 57074d9..7a213d0 100644 --- a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/StringBuilderExtensionMethodTests.cs @@ -53,6 +53,7 @@ private static IEnumerable<object[]> GetStringBuilderExtensionMethods() yield return new object[] { new MethodWithArgumentData("EndRef") }; yield return new object[] { new MethodWithArgumentData("Entity", AnyString) }; yield return new object[] { new MethodWithArgumentData("HideFootBox") }; + yield return new object[] { new MethodWithArgumentData("HideUnlinked") }; yield return new object[] { new MethodWithArgumentData("GroupEnd") }; yield return new object[] { new MethodWithArgumentData("GroupStart") }; yield return new object[] { new MethodWithArgumentData("IncreaseAutoNumber") }; @@ -66,6 +67,7 @@ private static IEnumerable<object[]> GetStringBuilderExtensionMethods() yield return new object[] { new MethodWithArgumentData("Return") }; yield return new object[] { new MethodWithArgumentData("Return", AnyString) }; yield return new object[] { new MethodWithArgumentData("ShowFootBox") }; + yield return new object[] { new MethodWithArgumentData("ShowUnlinked") }; yield return new object[] { new MethodWithArgumentData("Space") }; yield return new object[] { new MethodWithArgumentData("StartLoop") }; yield return new object[] { new MethodWithArgumentData("StartRef", AnyString) }; diff --git a/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/UnlinkedTests.cs b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/UnlinkedTests.cs new file mode 100644 index 0000000..cb7f1f2 --- /dev/null +++ b/tests/PlantUml.Builder.Tests/SequenceDiagrams/StringBuilderExtensions/UnlinkedTests.cs @@ -0,0 +1,31 @@ +namespace PlantUml.Builder.SequenceDiagrams.Tests; + +[TestClass] +public class UnlinkedTests +{ + [TestMethod] + public void HideUnlinkedIsRenderedCorrectly() + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.HideUnlinked(); + + // Assert + stringBuilder.ToString().Should().Be("hide unlinked\n"); + } + + [TestMethod] + public void ShowUnlinkedIsRenderedCorrectly() + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.ShowUnlinked(); + + // Assert + stringBuilder.ToString().Should().Be("show unlinked\n"); + } +} From 3b6f6d7321b5fe2e7b5a4cd8e27ed321317bbaca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Tue, 5 Sep 2023 22:12:45 +0200 Subject: [PATCH 09/10] Add direction command --- docs/commands.md | 2 + src/PlantUml.Builder/Constant.cs | 6 ++ src/PlantUml.Builder/DiagramDirection.cs | 19 +++++ .../StringBuilderExtensions/Direction.cs | 37 +++++++++ .../ObjectDiagramExampleTests.cs | 80 +++++++++++++++++++ .../StringBuilderExtensions/DirectionTests.cs | 35 ++++++++ 6 files changed, 179 insertions(+) create mode 100644 src/PlantUml.Builder/DiagramDirection.cs create mode 100644 src/PlantUml.Builder/StringBuilderExtensions/Direction.cs create mode 100644 tests/PlantUml.Builder.Tests/StringBuilderExtensions/DirectionTests.cs diff --git a/docs/commands.md b/docs/commands.md index ae9ba3c..b327fbe 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -31,6 +31,8 @@ Following the PlantUML source code. | endlegend | no | | | skinparam \<NAME> \<VALUE> | yes | `SkinParam` | | skinparam \<PREFIX> { | no | | +| left to right direction | yes | `Direction` | +| top to bottom direction | yes | `Direction` | ## Activity Diagrams diff --git a/src/PlantUml.Builder/Constant.cs b/src/PlantUml.Builder/Constant.cs index 5d331f5..376418a 100644 --- a/src/PlantUml.Builder/Constant.cs +++ b/src/PlantUml.Builder/Constant.cs @@ -64,10 +64,12 @@ public static class Words public const string Alt = "alt"; public const string As = "as"; public const string Auto = "auto"; + public const string Bottom = "bottom"; public const string Box = "box"; public const string Create = "create"; public const string Deactivate = "deactivate"; public const string Destroy = "destroy"; + public const string Direction = "direction"; public const string Else = "else"; public const string Empty = "empty"; public const string End = "end"; @@ -79,6 +81,7 @@ public static class Words public const string Hide = "hide"; public const string Implements = "implements"; public const string Increase = "inc"; + public const string Left = "left"; public const string Loop = "loop"; public const string Map = "map"; public const string Mixing = "mixing"; @@ -96,6 +99,7 @@ public static class Words public const string Ref = "ref"; public const string Resume = "resume"; public const string Return = "return"; + public const string Right = "right"; public const string Separator = "separator"; public const string Set = "set"; public const string Show = "show"; @@ -104,6 +108,8 @@ public static class Words public const string Static = "static"; public const string Stop = "stop"; public const string Title = "title"; + public const string To = "to"; + public const string Top = "top"; public const string Unlinked = "unlinked"; public const string Uml = "uml"; } diff --git a/src/PlantUml.Builder/DiagramDirection.cs b/src/PlantUml.Builder/DiagramDirection.cs new file mode 100644 index 0000000..9a69209 --- /dev/null +++ b/src/PlantUml.Builder/DiagramDirection.cs @@ -0,0 +1,19 @@ +namespace PlantUml.Builder +{ + /// <summary> + /// Represents different directions of the UML diagram. + /// </summary> + public enum DiagramDirection + : byte + { + /// <summary> + /// Represents a left to right direction. + /// </summary> + LeftToRight = 0, + + /// <summary> + /// Represents a top to bottom direction. + /// </summary> + TopToBottom, + } +} diff --git a/src/PlantUml.Builder/StringBuilderExtensions/Direction.cs b/src/PlantUml.Builder/StringBuilderExtensions/Direction.cs new file mode 100644 index 0000000..0dc511f --- /dev/null +++ b/src/PlantUml.Builder/StringBuilderExtensions/Direction.cs @@ -0,0 +1,37 @@ +namespace PlantUml.Builder; + +public static partial class StringBuilderExtensions +{ + /// <summary> + /// Set the direction of the diagram + /// </summary> + /// <exception cref="ArgumentNullException">Thrown when <paramref name="stringBuilder"/> is <see langword="null"/>.</exception> + public static void Direction(this StringBuilder stringBuilder, DiagramDirection direction) + { + ArgumentNullException.ThrowIfNull(stringBuilder); + if (!Enum.IsDefined(direction)) throw new ArgumentOutOfRangeException(nameof(direction), "A defined enum value should be provided"); + + switch (direction) + { + case DiagramDirection.LeftToRight: + stringBuilder.Append(Constant.Words.Left); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.To); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Right); + break; + + case DiagramDirection.TopToBottom: + stringBuilder.Append(Constant.Words.Top); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.To); + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Bottom); + break; + } + + stringBuilder.Append(Constant.Symbols.Space); + stringBuilder.Append(Constant.Words.Direction); + stringBuilder.AppendNewLine(); + } +} diff --git a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs index 44ae1b5..848a61e 100644 --- a/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs +++ b/tests/PlantUml.Builder.Examples/ObjectDiagramExampleTests.cs @@ -405,4 +405,84 @@ object Baz // Assert stringBuilder.ToString().Should().Be(example.Replace("\r", "")); } + + /// <seealso href="https://plantuml.com/object-diagram#d1f08bf69f3d9b45"/> + [TestMethod] + public void ProgramEvaluationAndReviewTechniqueWithMap() + { + // Arrange + var example = + """ + @startuml PERT + left to right direction + ' Horizontal lines: -->, <--, <--> + ' Vertical lines: ->, <-, <-> + title PERT: Project Name + + map Kick.Off { + } + map task.1 { + Start => End + } + map task.2 { + Start => End + } + map task.3 { + Start => End + } + map task.4 { + Start => End + } + map task.5 { + Start => End + } + Kick.Off --> task.1 : Label 1 + Kick.Off --> task.2 : Label 2 + Kick.Off --> task.3 : Label 3 + task.1 --> task.4 + task.2 --> task.4 + task.3 --> task.4 + task.4 --> task.5 : Label 4 + @enduml + + """; + + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.UmlDiagramStart("PERT"); + stringBuilder.Direction(DiagramDirection.LeftToRight); + stringBuilder.Comment("Horizontal lines: -->, <--, <-->"); + stringBuilder.Comment("Vertical lines: ->, <-, <->"); + stringBuilder.Title("PERT: Project Name"); + stringBuilder.AppendNewLine(); + stringBuilder.MapStart("Kick.Off"); + stringBuilder.MapEnd(); + stringBuilder.MapStart("task.1"); + stringBuilder.InlineClassMember("Start => End"); + stringBuilder.MapEnd(); + stringBuilder.MapStart("task.2"); + stringBuilder.InlineClassMember("Start => End"); + stringBuilder.MapEnd(); + stringBuilder.MapStart("task.3"); + stringBuilder.InlineClassMember("Start => End"); + stringBuilder.MapEnd(); + stringBuilder.MapStart("task.4"); + stringBuilder.InlineClassMember("Start => End"); + stringBuilder.MapEnd(); + stringBuilder.MapStart("task.5"); + stringBuilder.InlineClassMember("Start => End"); + stringBuilder.MapEnd(); + stringBuilder.Relationship("Kick.Off", "-->", "task.1", "Label 1"); + stringBuilder.Relationship("Kick.Off", "-->", "task.2", "Label 2"); + stringBuilder.Relationship("Kick.Off", "-->", "task.3", "Label 3"); + stringBuilder.Relationship("task.1", "-->", "task.4"); + stringBuilder.Relationship("task.2", "-->", "task.4"); + stringBuilder.Relationship("task.3", "-->", "task.4"); + stringBuilder.Relationship("task.4", "-->", "task.5", "Label 4"); + stringBuilder.UmlDiagramEnd(); + + // Assert + stringBuilder.ToString().Should().Be(example.Replace("\r", "")); + } } diff --git a/tests/PlantUml.Builder.Tests/StringBuilderExtensions/DirectionTests.cs b/tests/PlantUml.Builder.Tests/StringBuilderExtensions/DirectionTests.cs new file mode 100644 index 0000000..5a51df6 --- /dev/null +++ b/tests/PlantUml.Builder.Tests/StringBuilderExtensions/DirectionTests.cs @@ -0,0 +1,35 @@ +namespace PlantUml.Builder.Tests; + +[TestClass] +public class DirectionTests +{ + [TestMethod] + public void AutoActivateEnumerationValueShouldExist() + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + Action action = () => stringBuilder.Direction((DiagramDirection)byte.MaxValue); + + // Assert + action.Should().ThrowExactly<ArgumentOutOfRangeException>() + .WithMessage("A defined enum value should be provided*") + .WithParameterName("direction"); + } + + [DataRow(DiagramDirection.LeftToRight, "left to right direction", DisplayName = "Direction - With LeftToRight parameter")] + [DataRow(DiagramDirection.TopToBottom, "top to bottom direction", DisplayName = "Direction - With TopToBottom parameter")] + [TestMethod] + public void AutoActivateIsRenderedCorrectly(DiagramDirection direction, string expected) + { + // Arrange + var stringBuilder = new StringBuilder(); + + // Act + stringBuilder.Direction(direction); + + // Assert + stringBuilder.ToString().Should().Be($"{expected}\n"); + } +} From 7b6b4c277f2878be17a9418a72f41c9932867bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Hompus?= <michael@hompus.nl> Date: Tue, 5 Sep 2023 22:25:06 +0200 Subject: [PATCH 10/10] Add dotnet 7.x SDK for building --- .github/workflows/continuous-integration-workflow.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/continuous-integration-workflow.yml b/.github/workflows/continuous-integration-workflow.yml index 9aa3614..04158be 100644 --- a/.github/workflows/continuous-integration-workflow.yml +++ b/.github/workflows/continuous-integration-workflow.yml @@ -29,7 +29,9 @@ jobs: - name: Setup .NET Core uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.x + dotnet-version: | + 6.x + 7.x - name: Install dependencies run: dotnet restore