enhanced_sequence_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package parser
  2. import (
  3. "strings"
  4. "testing"
  5. "mermaid-go/pkg/renderer"
  6. )
  7. func TestSequenceParser_NewBlocks(t *testing.T) {
  8. tests := []struct {
  9. name string
  10. input string
  11. expected string
  12. }{
  13. {
  14. name: "Rect Block",
  15. input: `sequenceDiagram
  16. participant A
  17. participant B
  18. rect rgb(255, 0, 0)
  19. A -> B : message1
  20. B -> A : response1
  21. end
  22. A -> B : message2`,
  23. expected: `sequenceDiagram
  24. participant A
  25. participant B
  26. A -> B : message2
  27. rect rgb(255,0,0)
  28. A -> B : message1
  29. B -> A : response1
  30. end
  31. `,
  32. },
  33. {
  34. name: "Critical Block with Option",
  35. input: `sequenceDiagram
  36. participant A
  37. participant B
  38. critical Critical Section
  39. A -> B : critical message
  40. option Success Path
  41. B --> A : success response
  42. option Failure Path
  43. B --> A : error response
  44. end`,
  45. expected: `sequenceDiagram
  46. participant A
  47. participant B
  48. critical Critical Section
  49. A -> B : critical message
  50. option Success Path
  51. B -> A : success response
  52. option Failure Path
  53. B -> A : error response
  54. end
  55. `,
  56. },
  57. {
  58. name: "Break Block",
  59. input: `sequenceDiagram
  60. participant A
  61. participant B
  62. break Break Condition
  63. A -> B : break message
  64. B --> A : break response
  65. end`,
  66. expected: `sequenceDiagram
  67. participant A
  68. participant B
  69. break Break Condition
  70. A -> B : break message
  71. B -> A : break response
  72. end
  73. `,
  74. },
  75. {
  76. name: "Complex Nested Blocks",
  77. input: `sequenceDiagram
  78. participant A
  79. participant B
  80. participant C
  81. rect rgb(0, 255, 0)
  82. critical Authentication
  83. A -> B : login request
  84. option Valid Credentials
  85. B --> A : auth success
  86. A -> C : access resource
  87. C --> A : resource data
  88. option Invalid Credentials
  89. B --> A : auth failed
  90. end
  91. end`,
  92. expected: `sequenceDiagram
  93. participant A
  94. participant B
  95. participant C
  96. rect rgb(0,255,0)
  97. end
  98. critical Authentication
  99. A -> B : login request
  100. option Valid Credentials
  101. B -> A : auth success
  102. A -> C : access resource
  103. C -> A : resource data
  104. option Invalid Credentials
  105. B -> A : auth failed
  106. end
  107. `,
  108. },
  109. }
  110. for _, tt := range tests {
  111. t.Run(tt.name, func(t *testing.T) {
  112. parser := NewSequenceParser()
  113. diagram, err := parser.Parse(tt.input)
  114. if err != nil {
  115. t.Fatalf("Failed to parse: %v", err)
  116. }
  117. // Test rendering
  118. renderer := renderer.NewSequenceRenderer()
  119. output, err := renderer.Render(diagram)
  120. if err != nil {
  121. t.Fatalf("Failed to render: %v", err)
  122. }
  123. // Normalize whitespace for comparison
  124. expected := strings.TrimSpace(tt.expected)
  125. actual := strings.TrimSpace(output)
  126. if expected != actual {
  127. t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, actual)
  128. }
  129. })
  130. }
  131. }
  132. func TestSequenceParser_RectBlock(t *testing.T) {
  133. input := `sequenceDiagram
  134. participant A
  135. participant B
  136. rect rgb(255, 0, 0)
  137. A -> B : message in rect
  138. end`
  139. parser := NewSequenceParser()
  140. diagram, err := parser.Parse(input)
  141. if err != nil {
  142. t.Fatalf("Failed to parse: %v", err)
  143. }
  144. // Check rect was parsed
  145. if len(diagram.Rects) != 1 {
  146. t.Fatalf("Expected 1 rect, got %d", len(diagram.Rects))
  147. }
  148. rect := diagram.Rects[0]
  149. if rect.Color == nil || *rect.Color != "rgb(255,0,0)" {
  150. if rect.Color == nil {
  151. t.Errorf("Expected color rgb(255,0,0), got nil")
  152. } else {
  153. t.Errorf("Expected color rgb(255,0,0), got %s", *rect.Color)
  154. }
  155. }
  156. if len(rect.Messages) != 1 {
  157. t.Fatalf("Expected 1 message in rect, got %d", len(rect.Messages))
  158. }
  159. message := rect.Messages[0]
  160. if message.From != "A" || message.To != "B" || message.Message != "message in rect" {
  161. t.Errorf("Expected A -> B : message in rect, got %s %s %s : %s", message.From, string(message.Type), message.To, message.Message)
  162. }
  163. }
  164. func TestSequenceParser_CriticalBlock(t *testing.T) {
  165. input := `sequenceDiagram
  166. participant A
  167. participant B
  168. critical Critical Section
  169. A -> B : critical message
  170. option Success
  171. B --> A : success
  172. option Failure
  173. B --> A : failure
  174. end`
  175. parser := NewSequenceParser()
  176. diagram, err := parser.Parse(input)
  177. if err != nil {
  178. t.Fatalf("Failed to parse: %v", err)
  179. }
  180. // Check critical was parsed
  181. if len(diagram.Criticals) != 1 {
  182. t.Fatalf("Expected 1 critical, got %d", len(diagram.Criticals))
  183. }
  184. critical := diagram.Criticals[0]
  185. if critical.Label != "Critical Section" {
  186. t.Errorf("Expected label 'Critical Section', got '%s'", critical.Label)
  187. }
  188. if len(critical.Options) != 2 {
  189. t.Fatalf("Expected 2 options, got %d", len(critical.Options))
  190. }
  191. // Check options
  192. if critical.Options[0].Label != "Success" {
  193. t.Errorf("Expected first option label 'Success', got '%s'", critical.Options[0].Label)
  194. }
  195. if critical.Options[1].Label != "Failure" {
  196. t.Errorf("Expected second option label 'Failure', got '%s'", critical.Options[1].Label)
  197. }
  198. }
  199. func TestSequenceParser_BreakBlock(t *testing.T) {
  200. input := `sequenceDiagram
  201. participant A
  202. participant B
  203. break Break Condition
  204. A -> B : break message
  205. end`
  206. parser := NewSequenceParser()
  207. diagram, err := parser.Parse(input)
  208. if err != nil {
  209. t.Fatalf("Failed to parse: %v", err)
  210. }
  211. // Check break was parsed
  212. if len(diagram.Breaks) != 1 {
  213. t.Fatalf("Expected 1 break, got %d", len(diagram.Breaks))
  214. }
  215. breakBlock := diagram.Breaks[0]
  216. if breakBlock.Label != "Break Condition" {
  217. t.Errorf("Expected label 'Break Condition', got '%s'", breakBlock.Label)
  218. }
  219. if len(breakBlock.Messages) != 1 {
  220. t.Fatalf("Expected 1 message in break, got %d", len(breakBlock.Messages))
  221. }
  222. message := breakBlock.Messages[0]
  223. if message.From != "A" || message.To != "B" || message.Message != "break message" {
  224. t.Errorf("Expected A -> B : break message, got %s %s %s : %s", message.From, string(message.Type), message.To, message.Message)
  225. }
  226. }