Improving LSP
This commit is contained in:
@@ -79,11 +79,6 @@ func TestLSPAppTestRepro(t *testing.T) {
|
||||
t.Error("LSP missing unresolved variable error")
|
||||
}
|
||||
|
||||
// Check INOUT consumed but not produced
|
||||
if !strings.Contains(output, "consumed by GAM '+FnA'") {
|
||||
t.Error("LSP missing consumed but not produced error")
|
||||
}
|
||||
|
||||
if t.Failed() {
|
||||
t.Log(output)
|
||||
}
|
||||
|
||||
@@ -92,13 +92,7 @@ func TestLSPDiagnosticsAppTest(t *testing.T) {
|
||||
t.Error("Missing diagnostic for unresolved variable '@Value'")
|
||||
}
|
||||
|
||||
// 2. Check INOUT Ordering Error (Signal A consumed but not produced)
|
||||
// Message format: INOUT Signal 'A' (DS '+DDB') is consumed by GAM '+FnA' ... before being produced ...
|
||||
if !strings.Contains(output, "INOUT Signal 'A'") || !strings.Contains(output, "before being produced") {
|
||||
t.Error("Missing diagnostic for INOUT ordering error (Signal A)")
|
||||
}
|
||||
|
||||
// 3. Check INOUT Unused Warning (Signal B produced but not consumed)
|
||||
// 2. Check INOUT Unused Warning (Signal B produced but not consumed)
|
||||
// Message format: INOUT Signal 'B' ... produced ... but never consumed ...
|
||||
if !strings.Contains(output, "INOUT Signal 'B'") || !strings.Contains(output, "never consumed") {
|
||||
t.Error("Missing diagnostic for unused INOUT signal (Signal B)")
|
||||
|
||||
44
test/lsp_value_validation_test.go
Normal file
44
test/lsp_value_validation_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/marte-community/marte-dev-tools/internal/index"
|
||||
"github.com/marte-community/marte-dev-tools/internal/lsp"
|
||||
"github.com/marte-community/marte-dev-tools/internal/schema"
|
||||
)
|
||||
|
||||
func TestLSPValueValidation(t *testing.T) {
|
||||
lsp.Tree = index.NewProjectTree()
|
||||
lsp.Documents = make(map[string]string)
|
||||
lsp.GlobalSchema = schema.LoadFullSchema(".")
|
||||
|
||||
var buf bytes.Buffer
|
||||
lsp.Output = &buf
|
||||
|
||||
content := `
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
+DS = { Class = GAMDataSource Signals = { S = { Type = uint8 } } }
|
||||
}
|
||||
+GAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
S = { DataSource = DS Type = uint8 Value = 1024 }
|
||||
}
|
||||
}
|
||||
+App = { Class = RealTimeApplication +States = { Class = ReferenceContainer +S = { Class = RealTimeState Threads = { +T = { Class = RealTimeThread Functions = { GAM } } } } } }
|
||||
`
|
||||
uri := "file://value.marte"
|
||||
lsp.HandleDidOpen(lsp.DidOpenTextDocumentParams{
|
||||
TextDocument: lsp.TextDocumentItem{URI: uri, Text: content},
|
||||
})
|
||||
|
||||
output := buf.String()
|
||||
if !strings.Contains(output, "Value initialization mismatch") {
|
||||
t.Error("LSP did not report value validation error")
|
||||
t.Log(output)
|
||||
}
|
||||
}
|
||||
101
test/validator_inout_value_test.go
Normal file
101
test/validator_inout_value_test.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"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 TestINOUTValueInitialization(t *testing.T) {
|
||||
content := `
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
+MyDS = {
|
||||
Class = GAMDataSource
|
||||
#meta = { multithreaded = false }
|
||||
Signals = { Sig1 = { Type = uint32 } }
|
||||
}
|
||||
}
|
||||
+GAM1 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Sig1 = {
|
||||
DataSource = MyDS
|
||||
Type = uint32
|
||||
Value = 10 // Initialization
|
||||
}
|
||||
}
|
||||
}
|
||||
+GAM2 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
Sig1 = { DataSource = MyDS Type = uint32 } // Consumes initialized signal
|
||||
}
|
||||
}
|
||||
+App = {
|
||||
Class = RealTimeApplication
|
||||
+States = {
|
||||
Class = ReferenceContainer
|
||||
+State1 = {
|
||||
Class = RealTimeState
|
||||
+Thread1 = {
|
||||
Class = RealTimeThread
|
||||
Functions = { GAM1, GAM2 } // Should Pass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
pt := index.NewProjectTree()
|
||||
p := parser.NewParser(content)
|
||||
cfg, err := p.Parse()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pt.AddFile("main.marte", cfg)
|
||||
|
||||
v := validator.NewValidator(pt, ".")
|
||||
v.ValidateProject()
|
||||
|
||||
for _, d := range v.Diagnostics {
|
||||
if strings.Contains(d.Message, "before being produced") {
|
||||
t.Errorf("Unexpected error: %s", d.Message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestINOUTValueTypeMismatch(t *testing.T) {
|
||||
content := `
|
||||
+Data = { Class = ReferenceContainer +DS = { Class = GAMDataSource #meta = { multithreaded = false } Signals = { S = { Type = uint8 } } } }
|
||||
+GAM1 = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
S = { DataSource = DS Type = uint8 Value = 1024 }
|
||||
}
|
||||
}
|
||||
+App = { Class = RealTimeApplication +States = { Class = ReferenceContainer +S = { Class = RealTimeState Threads = { +T = { Class = RealTimeThread Functions = { GAM1 } } } } } }
|
||||
`
|
||||
pt := index.NewProjectTree()
|
||||
p := parser.NewParser(content)
|
||||
cfg, err := p.Parse()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pt.AddFile("fail.marte", cfg)
|
||||
|
||||
v := validator.NewValidator(pt, ".")
|
||||
v.ValidateProject()
|
||||
|
||||
found := false
|
||||
for _, d := range v.Diagnostics {
|
||||
if strings.Contains(d.Message, "Value initialization mismatch") {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Error("Expected Value initialization mismatch error")
|
||||
}
|
||||
}
|
||||
46
test/validator_unused_value_test.go
Normal file
46
test/validator_unused_value_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package integration
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"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 TestUnusedGAMValueValidation(t *testing.T) {
|
||||
content := `
|
||||
+Data = {
|
||||
Class = ReferenceContainer
|
||||
+DS = { Class = GAMDataSource Signals = { S = { Type = uint8 } } }
|
||||
}
|
||||
+UnusedGAM = {
|
||||
Class = IOGAM
|
||||
InputSignals = {
|
||||
S = { DataSource = DS Type = uint8 Value = 1024 }
|
||||
}
|
||||
}
|
||||
+App = { Class = RealTimeApplication }
|
||||
`
|
||||
pt := index.NewProjectTree()
|
||||
p := parser.NewParser(content)
|
||||
cfg, err := p.Parse()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pt.AddFile("unused.marte", cfg)
|
||||
|
||||
v := validator.NewValidator(pt, ".")
|
||||
v.ValidateProject()
|
||||
|
||||
found := false
|
||||
for _, d := range v.Diagnostics {
|
||||
if strings.Contains(d.Message, "Value initialization mismatch") {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
t.Error("Expected Value initialization mismatch error for unused GAM")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user