github.com/terraform-linters/tflint@v0.51.2-0.20240520175844-3750771571b6/integrationtest/langserver/workspace_did_change_watched_files_test.go (about)

     1  package main
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	lsp "github.com/sourcegraph/go-lsp"
    13  )
    14  
    15  func Test_workspaceDidChangeWatchedFiles(t *testing.T) {
    16  	withinTempDir(t, func(dir string) {
    17  		content := `resource "aws_instance" "foo" {
    18      instance_type = "t1.2xlarge"
    19  }`
    20  
    21  		config := `
    22  plugin "testing" {
    23      enabled = true
    24  }`
    25  
    26  		changedConfig := `
    27  plugin "testing" {
    28      enabled = true
    29  }
    30  
    31  rule "aws_instance_example_type" {
    32      enabled = false
    33  }`
    34  
    35  		if err := os.WriteFile(dir+"/main.tf", []byte(content), os.ModePerm); err != nil {
    36  			t.Fatal(err)
    37  		}
    38  		if err := os.WriteFile(dir+"/.tflint.hcl", []byte(config), os.ModePerm); err != nil {
    39  			t.Fatal(err)
    40  		}
    41  		uri := pathToURI(dir + "/main.tf")
    42  
    43  		stdin, stdout, plugin := startServer(t, dir+"/.tflint.hcl")
    44  		defer plugin.Clean()
    45  
    46  		req, err := json.Marshal(jsonrpcMessage{
    47  			ID:     0,
    48  			Method: "workspace/didChangeWatchedFiles",
    49  			Params: lsp.DidChangeWatchedFilesParams{
    50  				Changes: []lsp.FileEvent{
    51  					{
    52  						URI:  lsp.DocumentURI(dir + "/.tflint.hcl"),
    53  						Type: int(lsp.Created),
    54  					},
    55  				},
    56  			},
    57  			JSONRPC: "2.0",
    58  		})
    59  		if err != nil {
    60  			t.Fatal(err)
    61  		}
    62  
    63  		go func() {
    64  			fmt.Fprint(stdin, initializeRequest())
    65  			fmt.Fprint(stdin, didOpenRequest(uri, content, t))
    66  			// Change config file from outside of LSP
    67  			_ = os.WriteFile(dir+"/.tflint.hcl", []byte(changedConfig), os.ModePerm)
    68  			fmt.Fprint(stdin, toJSONRPC2(string(req)))
    69  			fmt.Fprint(stdin, shutdownRequest())
    70  			fmt.Fprint(stdin, exitRequest())
    71  		}()
    72  
    73  		buf := new(bytes.Buffer)
    74  		if _, err := buf.ReadFrom(stdout); err != nil {
    75  			t.Fatal(err)
    76  		}
    77  
    78  		expected := initializeResponse() + didOpenResponse(uri, t) + noDiagnosticsResponse(uri, t) + emptyResponse()
    79  		if !cmp.Equal(expected, buf.String()) {
    80  			t.Fatalf("Diff: %s", cmp.Diff(expected, buf.String()))
    81  		}
    82  	})
    83  }
    84  
    85  func Test_workspaceDidChangeWatchedFiles_withDeletedFile(t *testing.T) {
    86  	withinTempDir(t, func(dir string) {
    87  		content := `
    88  resource "aws_instance" "foo" {
    89      instance_type = var.instance_type
    90  }
    91  variable "instance_type" {}
    92  `
    93  
    94  		if err := os.WriteFile(dir+"/main.tf", []byte(content), os.ModePerm); err != nil {
    95  			t.Fatal(err)
    96  		}
    97  		uri := pathToURI(dir + "/main.tf")
    98  
    99  		valueFile := `
   100  instance_type = "t1.2xlarge"
   101  `
   102  		if err := os.WriteFile(dir+"/terraform.tfvars", []byte(valueFile), os.ModePerm); err != nil {
   103  			t.Fatal(err)
   104  		}
   105  
   106  		config := `
   107  plugin "testing" {
   108      enabled = true
   109  }`
   110  		if err := os.WriteFile(dir+"/.tflint.hcl", []byte(config), os.ModePerm); err != nil {
   111  			t.Fatal(err)
   112  		}
   113  
   114  		stdin, stdout, plugin := startServer(t, dir+"/.tflint.hcl")
   115  		defer plugin.Clean()
   116  
   117  		req, err := json.Marshal(jsonrpcMessage{
   118  			ID:     0,
   119  			Method: "workspace/didChangeWatchedFiles",
   120  			Params: lsp.DidChangeWatchedFilesParams{
   121  				Changes: []lsp.FileEvent{
   122  					{
   123  						URI:  lsp.DocumentURI(dir + "/terraform.tfvars"),
   124  						Type: int(lsp.Deleted),
   125  					},
   126  				},
   127  			},
   128  			JSONRPC: "2.0",
   129  		})
   130  		if err != nil {
   131  			t.Fatal(err)
   132  		}
   133  
   134  		go func() {
   135  			fmt.Fprint(stdin, initializeRequest())
   136  			fmt.Fprint(stdin, didOpenRequest(uri, content, t))
   137  			// Wait didOpen inspection
   138  			time.Sleep(100 * time.Millisecond)
   139  			// Remove values file from outside of LSP
   140  			os.Remove(dir + "/terraform.tfvars")
   141  			fmt.Fprint(stdin, toJSONRPC2(string(req)))
   142  			fmt.Fprint(stdin, shutdownRequest())
   143  			fmt.Fprint(stdin, exitRequest())
   144  		}()
   145  
   146  		buf := new(bytes.Buffer)
   147  		if _, err := buf.ReadFrom(stdout); err != nil {
   148  			t.Fatal(err)
   149  		}
   150  
   151  		didOpenResponse, err := json.Marshal(jsonrpcMessage{
   152  			Method: "textDocument/publishDiagnostics",
   153  			Params: lsp.PublishDiagnosticsParams{
   154  				URI: uri,
   155  				Diagnostics: []lsp.Diagnostic{
   156  					{
   157  						Message:  `instance type is t1.2xlarge`,
   158  						Severity: lsp.Error,
   159  						Range: lsp.Range{
   160  							Start: lsp.Position{Line: 2, Character: 20},
   161  							End:   lsp.Position{Line: 2, Character: 37},
   162  						},
   163  					},
   164  				},
   165  			},
   166  			JSONRPC: "2.0",
   167  		})
   168  		if err != nil {
   169  			t.Fatal(err)
   170  		}
   171  
   172  		expected := initializeResponse() + toJSONRPC2(string(didOpenResponse)) + noDiagnosticsResponse(uri, t) + emptyResponse()
   173  		if !cmp.Equal(expected, buf.String()) {
   174  			t.Fatalf("Diff: %s", cmp.Diff(expected, buf.String()))
   175  		}
   176  	})
   177  }