package parser import ( "strings" "testing" "mermaid-go/pkg/renderer" ) func TestSequenceParser_NewBlocks(t *testing.T) { tests := []struct { name string input string expected string }{ { name: "Rect Block", input: `sequenceDiagram participant A participant B rect rgb(255, 0, 0) A -> B : message1 B -> A : response1 end A -> B : message2`, expected: `sequenceDiagram participant A participant B A -> B : message2 rect rgb(255,0,0) A -> B : message1 B -> A : response1 end `, }, { name: "Critical Block with Option", input: `sequenceDiagram participant A participant B critical Critical Section A -> B : critical message option Success Path B --> A : success response option Failure Path B --> A : error response end`, expected: `sequenceDiagram participant A participant B critical Critical Section A -> B : critical message option Success Path B -> A : success response option Failure Path B -> A : error response end `, }, { name: "Break Block", input: `sequenceDiagram participant A participant B break Break Condition A -> B : break message B --> A : break response end`, expected: `sequenceDiagram participant A participant B break Break Condition A -> B : break message B -> A : break response end `, }, { name: "Complex Nested Blocks", input: `sequenceDiagram participant A participant B participant C rect rgb(0, 255, 0) critical Authentication A -> B : login request option Valid Credentials B --> A : auth success A -> C : access resource C --> A : resource data option Invalid Credentials B --> A : auth failed end end`, expected: `sequenceDiagram participant A participant B participant C rect rgb(0,255,0) end critical Authentication A -> B : login request option Valid Credentials B -> A : auth success A -> C : access resource C -> A : resource data option Invalid Credentials B -> A : auth failed end `, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { parser := NewSequenceParser() diagram, err := parser.Parse(tt.input) if err != nil { t.Fatalf("Failed to parse: %v", err) } // Test rendering renderer := renderer.NewSequenceRenderer() output, err := renderer.Render(diagram) if err != nil { t.Fatalf("Failed to render: %v", err) } // Normalize whitespace for comparison expected := strings.TrimSpace(tt.expected) actual := strings.TrimSpace(output) if expected != actual { t.Errorf("Expected:\n%s\n\nGot:\n%s", expected, actual) } }) } } func TestSequenceParser_RectBlock(t *testing.T) { input := `sequenceDiagram participant A participant B rect rgb(255, 0, 0) A -> B : message in rect end` parser := NewSequenceParser() diagram, err := parser.Parse(input) if err != nil { t.Fatalf("Failed to parse: %v", err) } // Check rect was parsed if len(diagram.Rects) != 1 { t.Fatalf("Expected 1 rect, got %d", len(diagram.Rects)) } rect := diagram.Rects[0] if rect.Color == nil || *rect.Color != "rgb(255,0,0)" { if rect.Color == nil { t.Errorf("Expected color rgb(255,0,0), got nil") } else { t.Errorf("Expected color rgb(255,0,0), got %s", *rect.Color) } } if len(rect.Messages) != 1 { t.Fatalf("Expected 1 message in rect, got %d", len(rect.Messages)) } message := rect.Messages[0] if message.From != "A" || message.To != "B" || message.Message != "message in rect" { t.Errorf("Expected A -> B : message in rect, got %s %s %s : %s", message.From, string(message.Type), message.To, message.Message) } } func TestSequenceParser_CriticalBlock(t *testing.T) { input := `sequenceDiagram participant A participant B critical Critical Section A -> B : critical message option Success B --> A : success option Failure B --> A : failure end` parser := NewSequenceParser() diagram, err := parser.Parse(input) if err != nil { t.Fatalf("Failed to parse: %v", err) } // Check critical was parsed if len(diagram.Criticals) != 1 { t.Fatalf("Expected 1 critical, got %d", len(diagram.Criticals)) } critical := diagram.Criticals[0] if critical.Label != "Critical Section" { t.Errorf("Expected label 'Critical Section', got '%s'", critical.Label) } if len(critical.Options) != 2 { t.Fatalf("Expected 2 options, got %d", len(critical.Options)) } // Check options if critical.Options[0].Label != "Success" { t.Errorf("Expected first option label 'Success', got '%s'", critical.Options[0].Label) } if critical.Options[1].Label != "Failure" { t.Errorf("Expected second option label 'Failure', got '%s'", critical.Options[1].Label) } } func TestSequenceParser_BreakBlock(t *testing.T) { input := `sequenceDiagram participant A participant B break Break Condition A -> B : break message end` parser := NewSequenceParser() diagram, err := parser.Parse(input) if err != nil { t.Fatalf("Failed to parse: %v", err) } // Check break was parsed if len(diagram.Breaks) != 1 { t.Fatalf("Expected 1 break, got %d", len(diagram.Breaks)) } breakBlock := diagram.Breaks[0] if breakBlock.Label != "Break Condition" { t.Errorf("Expected label 'Break Condition', got '%s'", breakBlock.Label) } if len(breakBlock.Messages) != 1 { t.Fatalf("Expected 1 message in break, got %d", len(breakBlock.Messages)) } message := breakBlock.Messages[0] if message.From != "A" || message.To != "B" || message.Message != "break message" { t.Errorf("Expected A -> B : break message, got %s %s %s : %s", message.From, string(message.Type), message.To, message.Message) } }