Compare commits
3 Commits
fed39467fd
...
6781d50ee4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6781d50ee4 | ||
|
|
1d7dc665d6 | ||
|
|
4ea406a17b |
10
Makefile
10
Makefile
@@ -1,9 +1,9 @@
|
|||||||
BINARY_NAME=mdt
|
BINARY_NAME=mdt
|
||||||
BUILD_DIR=build
|
BUILD_DIR=build
|
||||||
|
|
||||||
.PHONY: all build test coverage clean install
|
.PHONY: all build test coverage clean install vet fmt
|
||||||
|
|
||||||
all: test build
|
all: vet test build
|
||||||
|
|
||||||
build:
|
build:
|
||||||
mkdir -p $(BUILD_DIR)
|
mkdir -p $(BUILD_DIR)
|
||||||
@@ -16,6 +16,12 @@ coverage:
|
|||||||
go test -cover -coverprofile=coverage.out ./test/... -coverpkg=./internal/...
|
go test -cover -coverprofile=coverage.out ./test/... -coverpkg=./internal/...
|
||||||
go tool cover -func=coverage.out
|
go tool cover -func=coverage.out
|
||||||
|
|
||||||
|
vet:
|
||||||
|
go vet ./...
|
||||||
|
|
||||||
|
fmt:
|
||||||
|
go fmt ./...
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf $(BUILD_DIR)
|
rm -rf $(BUILD_DIR)
|
||||||
rm -f coverage.out
|
rm -f coverage.out
|
||||||
|
|||||||
@@ -45,6 +45,8 @@ type Subnode struct {
|
|||||||
Definitions []Definition
|
Definitions []Definition
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Subnode) Pos() Position { return s.Position }
|
||||||
|
|
||||||
type Value interface {
|
type Value interface {
|
||||||
Node
|
Node
|
||||||
isValue()
|
isValue()
|
||||||
@@ -115,7 +117,11 @@ type Comment struct {
|
|||||||
Doc bool // true if starts with //#
|
Doc bool // true if starts with //#
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Comment) Pos() Position { return c.Position }
|
||||||
|
|
||||||
type Pragma struct {
|
type Pragma struct {
|
||||||
Position Position
|
Position Position
|
||||||
Text string
|
Text string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Pragma) Pos() Position { return p.Position }
|
||||||
|
|||||||
@@ -10,9 +10,6 @@ func TestASTCoverage(t *testing.T) {
|
|||||||
pos := parser.Position{Line: 1, Column: 1}
|
pos := parser.Position{Line: 1, Column: 1}
|
||||||
|
|
||||||
var n parser.Node
|
var n parser.Node
|
||||||
// var d parser.Definition // Definition has unexported method, can't assign?
|
|
||||||
// Yes I can assign if I am using the interface type exported by parser.
|
|
||||||
// But I cannot call the method.
|
|
||||||
var d parser.Definition
|
var d parser.Definition
|
||||||
var v parser.Value
|
var v parser.Value
|
||||||
|
|
||||||
@@ -84,11 +81,29 @@ func TestASTCoverage(t *testing.T) {
|
|||||||
|
|
||||||
// Package
|
// Package
|
||||||
pkg := &parser.Package{Position: pos}
|
pkg := &parser.Package{Position: pos}
|
||||||
// Package implements Node?
|
|
||||||
// ast.go: func (p *Package) Pos() Position { return p.Position }
|
|
||||||
// Yes.
|
|
||||||
n = pkg
|
n = pkg
|
||||||
if n.Pos() != pos {
|
if n.Pos() != pos {
|
||||||
t.Error("Package.Pos failed")
|
t.Error("Package.Pos failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Subnode
|
||||||
|
sn := &parser.Subnode{Position: pos}
|
||||||
|
n = sn
|
||||||
|
if n.Pos() != pos {
|
||||||
|
t.Error("Subnode.Pos failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comment
|
||||||
|
cmt := &parser.Comment{Position: pos}
|
||||||
|
n = cmt
|
||||||
|
if n.Pos() != pos {
|
||||||
|
t.Error("Comment.Pos failed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pragma
|
||||||
|
prg := &parser.Pragma{Position: pos}
|
||||||
|
n = prg
|
||||||
|
if n.Pos() != pos {
|
||||||
|
t.Error("Pragma.Pos failed")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
59
test/logger_test.go
Normal file
59
test/logger_test.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/logger"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLoggerPrint(t *testing.T) {
|
||||||
|
if os.Getenv("TEST_LOGGER_PRINT") == "1" {
|
||||||
|
logger.Printf("Test Printf %d", 123)
|
||||||
|
logger.Println("Test Println")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd := exec.Command(os.Args[0], "-test.run=TestLoggerPrint")
|
||||||
|
cmd.Env = append(os.Environ(), "TEST_LOGGER_PRINT=1")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("process failed: %v", err)
|
||||||
|
}
|
||||||
|
output := string(out)
|
||||||
|
if !strings.Contains(output, "Test Printf 123") {
|
||||||
|
t.Error("Printf output missing")
|
||||||
|
}
|
||||||
|
if !strings.Contains(output, "Test Println") {
|
||||||
|
t.Error("Println output missing")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggerFatal(t *testing.T) {
|
||||||
|
if os.Getenv("TEST_LOGGER_FATAL") == "1" {
|
||||||
|
logger.Fatal("Test Fatal")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd := exec.Command(os.Args[0], "-test.run=TestLoggerFatal")
|
||||||
|
cmd.Env = append(os.Environ(), "TEST_LOGGER_FATAL=1")
|
||||||
|
err := cmd.Run()
|
||||||
|
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||||
|
return // Success (exit code non-zero)
|
||||||
|
}
|
||||||
|
t.Fatalf("process ran with err %v, want exit status 1", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoggerFatalf(t *testing.T) {
|
||||||
|
if os.Getenv("TEST_LOGGER_FATALF") == "1" {
|
||||||
|
logger.Fatalf("Test Fatalf %d", 456)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd := exec.Command(os.Args[0], "-test.run=TestLoggerFatalf")
|
||||||
|
cmd.Env = append(os.Environ(), "TEST_LOGGER_FATALF=1")
|
||||||
|
err := cmd.Run()
|
||||||
|
if e, ok := err.(*exec.ExitError); ok && !e.Success() {
|
||||||
|
return // Success
|
||||||
|
}
|
||||||
|
t.Fatalf("process ran with err %v, want exit status 1", err)
|
||||||
|
}
|
||||||
110
test/lsp_coverage_test.go
Normal file
110
test/lsp_coverage_test.go
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package integration
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/marte-community/marte-dev-tools/internal/lsp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestLSPIncrementalSync(t *testing.T) {
|
||||||
|
lsp.Documents = make(map[string]string)
|
||||||
|
var buf bytes.Buffer
|
||||||
|
lsp.Output = &buf
|
||||||
|
|
||||||
|
content := "Line1\nLine2\nLine3"
|
||||||
|
uri := "file://inc.marte"
|
||||||
|
lsp.Documents[uri] = content
|
||||||
|
|
||||||
|
// Replace "Line2" (Line 1, 0-5) with "Modified"
|
||||||
|
change := lsp.TextDocumentContentChangeEvent{
|
||||||
|
Range: &lsp.Range{
|
||||||
|
Start: lsp.Position{Line: 1, Character: 0},
|
||||||
|
End: lsp.Position{Line: 1, Character: 5},
|
||||||
|
},
|
||||||
|
Text: "Modified",
|
||||||
|
}
|
||||||
|
|
||||||
|
params := lsp.DidChangeTextDocumentParams{
|
||||||
|
TextDocument: lsp.VersionedTextDocumentIdentifier{URI: uri, Version: 2},
|
||||||
|
ContentChanges: []lsp.TextDocumentContentChangeEvent{change},
|
||||||
|
}
|
||||||
|
|
||||||
|
lsp.HandleDidChange(params)
|
||||||
|
|
||||||
|
expected := "Line1\nModified\nLine3"
|
||||||
|
if lsp.Documents[uri] != expected {
|
||||||
|
t.Errorf("Incremental update failed. Got:\n%q\nWant:\n%q", lsp.Documents[uri], expected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert at end
|
||||||
|
change2 := lsp.TextDocumentContentChangeEvent{
|
||||||
|
Range: &lsp.Range{
|
||||||
|
Start: lsp.Position{Line: 2, Character: 5},
|
||||||
|
End: lsp.Position{Line: 2, Character: 5},
|
||||||
|
},
|
||||||
|
Text: "\nLine4",
|
||||||
|
}
|
||||||
|
params2 := lsp.DidChangeTextDocumentParams{
|
||||||
|
TextDocument: lsp.VersionedTextDocumentIdentifier{URI: uri, Version: 3},
|
||||||
|
ContentChanges: []lsp.TextDocumentContentChangeEvent{change2},
|
||||||
|
}
|
||||||
|
lsp.HandleDidChange(params2)
|
||||||
|
|
||||||
|
expected2 := "Line1\nModified\nLine3\nLine4"
|
||||||
|
if lsp.Documents[uri] != expected2 {
|
||||||
|
t.Errorf("Incremental insert failed. Got:\n%q\nWant:\n%q", lsp.Documents[uri], expected2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLSPLifecycle(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
lsp.Output = &buf
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
msgShutdown := &lsp.JsonRpcMessage{
|
||||||
|
Method: "shutdown",
|
||||||
|
ID: 1,
|
||||||
|
}
|
||||||
|
lsp.HandleMessage(msgShutdown)
|
||||||
|
|
||||||
|
if !strings.Contains(buf.String(), `"result":null`) {
|
||||||
|
t.Error("Shutdown response incorrect")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exit
|
||||||
|
if os.Getenv("TEST_LSP_EXIT") == "1" {
|
||||||
|
msgExit := &lsp.JsonRpcMessage{Method: "exit"}
|
||||||
|
lsp.HandleMessage(msgExit)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cmd := exec.Command(os.Args[0], "-test.run=TestLSPLifecycle")
|
||||||
|
cmd.Env = append(os.Environ(), "TEST_LSP_EXIT=1")
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Exit failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLSPMalformedParams(t *testing.T) {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
lsp.Output = &buf
|
||||||
|
|
||||||
|
// Malformed Hover
|
||||||
|
msg := &lsp.JsonRpcMessage{
|
||||||
|
Method: "textDocument/hover",
|
||||||
|
ID: 2,
|
||||||
|
Params: json.RawMessage(`{invalid`),
|
||||||
|
}
|
||||||
|
lsp.HandleMessage(msg)
|
||||||
|
|
||||||
|
output := buf.String()
|
||||||
|
// Should respond with nil result
|
||||||
|
if !strings.Contains(output, `"result":null`) {
|
||||||
|
t.Errorf("Expected nil result for malformed params, got: %s", output)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user