Better formatting and expression handling

This commit is contained in:
Martino Ferrari
2026-02-02 17:22:39 +01:00
parent 12615aa6d2
commit 749eab0a32
14 changed files with 735 additions and 67 deletions

125
test/let_macro_test.go Normal file
View File

@@ -0,0 +1,125 @@
package integration
import (
"os"
"strings"
"testing"
"github.com/marte-community/marte-dev-tools/internal/builder"
"github.com/marte-community/marte-dev-tools/internal/index"
"github.com/marte-community/marte-dev-tools/internal/parser"
"github.com/marte-community/marte-dev-tools/internal/validator"
)
func TestLetMacroFull(t *testing.T) {
content := `
//# My documentation
#let MyConst: uint32 = 10 + 20
+Obj = {
Value = @MyConst
}
`
tmpFile, _ := os.CreateTemp("", "let_*.marte")
defer os.Remove(tmpFile.Name())
os.WriteFile(tmpFile.Name(), []byte(content), 0644)
// 1. Test Parsing & Indexing
p := parser.NewParser(content)
cfg, err := p.Parse()
if err != nil {
t.Fatalf("Parse failed: %v", err)
}
tree := index.NewProjectTree()
tree.AddFile(tmpFile.Name(), cfg)
vars := tree.Root.Variables
if iso, ok := tree.IsolatedFiles[tmpFile.Name()]; ok {
vars = iso.Variables
}
info, ok := vars["MyConst"]
if !ok || !info.Def.IsConst {
t.Fatal("#let variable not indexed correctly as Const")
}
if info.Doc != "My documentation" {
t.Errorf("Expected doc 'My documentation', got '%s'", info.Doc)
}
// 2. Test Builder Evaluation
out, _ := os.CreateTemp("", "let_out.cfg")
defer os.Remove(out.Name())
b := builder.NewBuilder([]string{tmpFile.Name()}, nil)
if err := b.Build(out); err != nil {
t.Fatalf("Build failed: %v", err)
}
outContent, _ := os.ReadFile(out.Name())
if !strings.Contains(string(outContent), "Value = 30") {
t.Errorf("Expected Value = 30 (evaluated @MyConst), got:\n%s", string(outContent))
}
// 3. Test Override Protection
out2, _ := os.CreateTemp("", "let_out2.cfg")
defer os.Remove(out2.Name())
b2 := builder.NewBuilder([]string{tmpFile.Name()}, map[string]string{"MyConst": "100"})
if err := b2.Build(out2); err != nil {
t.Fatalf("Build failed: %v", err)
}
outContent2, _ := os.ReadFile(out2.Name())
if !strings.Contains(string(outContent2), "Value = 30") {
t.Errorf("Constant was overridden! Expected 30, got:\n%s", string(outContent2))
}
// 4. Test Validator (Mandatory Value)
contentErr := "#let BadConst: uint32"
p2 := parser.NewParser(contentErr)
cfg2, err2 := p2.Parse()
// Parser might fail if = is missing?
// parseLet expects =.
if err2 == nil {
// If parser didn't fail (maybe it was partial), validator should catch it
tree2 := index.NewProjectTree()
tree2.AddFile("err.marte", cfg2)
v := validator.NewValidator(tree2, ".")
v.ValidateProject()
found := false
for _, d := range v.Diagnostics {
if strings.Contains(d.Message, "must have an initial value") {
found = true
break
}
}
if !found && cfg2 != nil {
// If p2.Parse() failed and added error to p2.errors, it's also fine.
// But check if it reached validator.
}
}
// 5. Test Duplicate Detection
contentDup := `
#let MyConst: uint32 = 10
#var MyConst: uint32 = 20
`
p3 := parser.NewParser(contentDup)
cfg3, _ := p3.Parse()
tree3 := index.NewProjectTree()
tree3.AddFile("dup.marte", cfg3)
v3 := validator.NewValidator(tree3, ".")
v3.ValidateProject()
foundDup := false
for _, d := range v3.Diagnostics {
if strings.Contains(d.Message, "Duplicate variable definition") {
foundDup = true
break
}
}
if !foundDup {
t.Error("Expected duplicate variable definition error")
}
}