github.com/getgauge/gauge@v1.6.9/api/lang/diagnostics_test.go (about)

     1  /*----------------------------------------------------------------
     2   *  Copyright (c) ThoughtWorks, Inc.
     3   *  Licensed under the Apache License, Version 2.0
     4   *  See LICENSE in the project root for license information.
     5   *----------------------------------------------------------------*/
     6  
     7  package lang
     8  
     9  import (
    10  	"os"
    11  	"testing"
    12  	"time"
    13  
    14  	"reflect"
    15  
    16  	"strings"
    17  
    18  	"github.com/getgauge/gauge-proto/go/gauge_messages"
    19  	"github.com/getgauge/gauge/runner"
    20  	"github.com/getgauge/gauge/util"
    21  	"github.com/sourcegraph/go-langserver/pkg/lsp"
    22  )
    23  
    24  var conceptFile = "foo.cpt"
    25  var specFile = "foo.spec"
    26  
    27  func TestMain(m *testing.M) {
    28  	exitCode := m.Run()
    29  	tearDown()
    30  	os.Exit(exitCode)
    31  }
    32  
    33  func setup() {
    34  	openFilesCache = &files{cache: make(map[lsp.DocumentURI][]string)}
    35  	openFilesCache.add(util.ConvertPathToURI(conceptFile), "")
    36  	openFilesCache.add(util.ConvertPathToURI(specFile), "")
    37  	responses := map[gauge_messages.Message_MessageType]interface{}{}
    38  	responses[gauge_messages.Message_StepValidateResponse] = &gauge_messages.StepValidateResponse{IsValid: true}
    39  	lRunner.runner = &runner.GrpcRunner{LegacyClient: &mockClient{responses: responses}, Timeout: time.Second * 30}
    40  
    41  	util.GetConceptFiles = func() []string {
    42  		return []string{conceptFile}
    43  	}
    44  
    45  	util.GetSpecFiles = func(paths []string) []string {
    46  		return []string{specFile}
    47  	}
    48  }
    49  func tearDown() {
    50  	lRunner.runner = nil
    51  }
    52  
    53  func TestDiagnosticWithParseErrorsInSpec(t *testing.T) {
    54  	setup()
    55  	specText := `Specification Heading
    56  =====================
    57  
    58  Scenario Heading
    59  ================
    60  
    61  * Step text`
    62  
    63  	uri := util.ConvertPathToURI(specFile)
    64  	openFilesCache.add(uri, specText)
    65  
    66  	want := []lsp.Diagnostic{
    67  		{
    68  			Range: lsp.Range{
    69  				Start: lsp.Position{Line: 0, Character: 0},
    70  				End:   lsp.Position{Line: 1, Character: 21},
    71  			},
    72  			Message:  "Spec should have atleast one scenario",
    73  			Severity: 1,
    74  		},
    75  		{
    76  			Range: lsp.Range{
    77  				Start: lsp.Position{Line: 3, Character: 0},
    78  				End:   lsp.Position{Line: 4, Character: 16},
    79  			},
    80  			Message:  "Multiple spec headings found in same file",
    81  			Severity: 1,
    82  		},
    83  	}
    84  
    85  	diagnostics, err := getDiagnostics()
    86  	if err != nil {
    87  		t.Errorf("Expected no error, got : %s", err.Error())
    88  	}
    89  
    90  	got := diagnostics[uri]
    91  	if !reflect.DeepEqual(got, want) {
    92  		t.Errorf("want: `%+v`,\n got: `%+v`", want, got)
    93  	}
    94  }
    95  
    96  func TestDiagnosticWithNoErrors(t *testing.T) {
    97  	setup()
    98  	specText := `Specification Heading
    99  =====================
   100  
   101  Scenario Heading
   102  ----------------
   103  
   104  * Step text
   105  `
   106  	uri := util.ConvertPathToURI(specFile)
   107  	openFilesCache.add(uri, specText)
   108  	d, err := getDiagnostics()
   109  	if err != nil {
   110  		t.Errorf("expected no error.\n Got: %s", err.Error())
   111  	}
   112  	if len(d[uri]) > 0 {
   113  		t.Errorf("expected no error.\n Got: %+v", d)
   114  	}
   115  }
   116  
   117  func TestParseConcept(t *testing.T) {
   118  	setup()
   119  	cptText := `# concept
   120  * foo
   121  `
   122  	uri := util.ConvertPathToURI(conceptFile)
   123  	openFilesCache.add(uri, cptText)
   124  
   125  	diagnostics := make(map[lsp.DocumentURI][]lsp.Diagnostic)
   126  
   127  	dictionary, err := validateConcepts(diagnostics)
   128  	if err != nil {
   129  		t.Errorf("expected no error.\n Got: %s", err.Error())
   130  	}
   131  
   132  	if len(dictionary.ConceptsMap) == 0 {
   133  		t.Errorf("Concept dictionary is empty")
   134  	}
   135  
   136  	if len(diagnostics[uri]) > 0 {
   137  		t.Errorf("Parsing failed, got : %+v", diagnostics)
   138  	}
   139  }
   140  
   141  func TestDiagnosticsForConceptParseErrors(t *testing.T) {
   142  	setup()
   143  	cptText := `# concept`
   144  
   145  	uri := util.ConvertPathToURI(conceptFile)
   146  
   147  	openFilesCache.add(uri, cptText)
   148  
   149  	diagnostics := make(map[lsp.DocumentURI][]lsp.Diagnostic)
   150  
   151  	_, err := validateConcepts(diagnostics)
   152  
   153  	if err != nil {
   154  		t.Error(err)
   155  	}
   156  	if len(diagnostics[uri]) <= 0 {
   157  		t.Errorf("expected parse errors")
   158  	}
   159  
   160  	want := []lsp.Diagnostic{
   161  		{
   162  			Range: lsp.Range{
   163  				Start: lsp.Position{Line: 0, Character: 0},
   164  				End:   lsp.Position{Line: 0, Character: 9},
   165  			},
   166  			Message:  "Concept should have atleast one step",
   167  			Severity: 1,
   168  		},
   169  	}
   170  
   171  	if !reflect.DeepEqual(want, diagnostics[uri]) {
   172  		t.Errorf("want: `%v`,\n got: `%v`", want, diagnostics[uri])
   173  	}
   174  }
   175  
   176  func TestDiagnosticOfConceptsWithCircularReference(t *testing.T) {
   177  	setup()
   178  	cptText := `# concept
   179  * concept
   180  `
   181  	uri := util.ConvertPathToURI(conceptFile)
   182  	openFilesCache.add(uri, cptText)
   183  
   184  	diagnostics, err := getDiagnostics()
   185  	if err != nil {
   186  		t.Errorf("expected no error.\n Got: %s", err.Error())
   187  	}
   188  
   189  	got := diagnostics[uri]
   190  	containsDiagnostics(got, 1, 0, "Circular reference found in concept.", t)
   191  }
   192  
   193  var containsDiagnostics = func(diagnostics []lsp.Diagnostic, line1, line2 int, startMessage string, t *testing.T) {
   194  	for _, diagnostic := range diagnostics {
   195  		if !strings.Contains(diagnostic.Message, startMessage) {
   196  			t.Errorf("Invalid error message, got : %s : ", diagnostic.Message)
   197  		}
   198  		if (diagnostic.Range.Start.Line != line1 || diagnostic.Range.Start.Line != line2) && diagnostic.Range.Start.Character != 0 {
   199  			t.Errorf("Invalid start in range, got : %+v : ", diagnostic.Range.Start)
   200  		}
   201  		if (diagnostic.Range.End.Line != line1 || diagnostic.Range.End.Line != line2) && diagnostic.Range.End.Character != 9 {
   202  			t.Errorf("Invalid end in range, got : %+v : ", diagnostic.Range.End)
   203  		}
   204  		if diagnostic.Severity != 1 {
   205  			t.Errorf("Invalid diagnostic severity, want : 1, got : %d : ", diagnostic.Severity)
   206  		}
   207  	}
   208  }