golang.org/x/tools/gopls@v0.15.3/internal/protocol/generate/main_test.go (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build go1.19
     6  // +build go1.19
     7  
     8  package main
     9  
    10  import (
    11  	"encoding/json"
    12  	"fmt"
    13  	"log"
    14  	"os"
    15  	"testing"
    16  )
    17  
    18  // These tests require the result of
    19  //"git clone https://github.com/microsoft/vscode-languageserver-node" in the HOME directory
    20  
    21  // this is not a test, but a way to get code coverage,
    22  // (in vscode, just run the test with  "go.coverOnSingleTest": true)
    23  func TestAll(t *testing.T) {
    24  	t.Skip("needs vscode-languageserver-node repository")
    25  	*lineNumbers = true
    26  	log.SetFlags(log.Lshortfile)
    27  	main()
    28  }
    29  
    30  // check that the parsed file includes all the information
    31  // from the json file. This test will fail if the spec
    32  // introduces new fields. (one can test this test by
    33  // commenting out the version field in Model.)
    34  func TestParseContents(t *testing.T) {
    35  	t.Skip("needs vscode-languageserver-node repository")
    36  	log.SetFlags(log.Lshortfile)
    37  
    38  	// compute our parse of the specification
    39  	dir := os.Getenv("HOME") + "/vscode-languageserver-node"
    40  	fname := dir + "/protocol/metaModel.json"
    41  	v := parse(fname)
    42  	out, err := json.Marshal(v)
    43  	if err != nil {
    44  		t.Fatal(err)
    45  	}
    46  	var our interface{}
    47  	if err := json.Unmarshal(out, &our); err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	// process the json file
    52  	buf, err := os.ReadFile(fname)
    53  	if err != nil {
    54  		t.Fatalf("could not read metaModel.json: %v", err)
    55  	}
    56  	var raw interface{}
    57  	if err := json.Unmarshal(buf, &raw); err != nil {
    58  		t.Fatal(err)
    59  	}
    60  
    61  	// convert to strings showing the fields
    62  	them := flatten(raw)
    63  	us := flatten(our)
    64  
    65  	// everything in them should be in us
    66  	lesser := make(sortedMap[bool])
    67  	for _, s := range them {
    68  		lesser[s] = true
    69  	}
    70  	greater := make(sortedMap[bool]) // set of fields we have
    71  	for _, s := range us {
    72  		greater[s] = true
    73  	}
    74  	for _, k := range lesser.keys() { // set if fields they have
    75  		if !greater[k] {
    76  			t.Errorf("missing %s", k)
    77  		}
    78  	}
    79  }
    80  
    81  // flatten(nil) = "nil"
    82  // flatten(v string) = fmt.Sprintf("%q", v)
    83  // flatten(v float64)= fmt.Sprintf("%g", v)
    84  // flatten(v bool) = fmt.Sprintf("%v", v)
    85  // flatten(v []any) = []string{"[0]"flatten(v[0]), "[1]"flatten(v[1]), ...}
    86  // flatten(v map[string]any) = {"key1": flatten(v["key1"]), "key2": flatten(v["key2"]), ...}
    87  func flatten(x any) []string {
    88  	switch v := x.(type) {
    89  	case nil:
    90  		return []string{"nil"}
    91  	case string:
    92  		return []string{fmt.Sprintf("%q", v)}
    93  	case float64:
    94  		return []string{fmt.Sprintf("%g", v)}
    95  	case bool:
    96  		return []string{fmt.Sprintf("%v", v)}
    97  	case []any:
    98  		var ans []string
    99  		for i, x := range v {
   100  			idx := fmt.Sprintf("[%.3d]", i)
   101  			for _, s := range flatten(x) {
   102  				ans = append(ans, idx+s)
   103  			}
   104  		}
   105  		return ans
   106  	case map[string]any:
   107  		var ans []string
   108  		for k, x := range v {
   109  			idx := fmt.Sprintf("%q:", k)
   110  			for _, s := range flatten(x) {
   111  				ans = append(ans, idx+s)
   112  			}
   113  		}
   114  		return ans
   115  	default:
   116  		log.Fatalf("unexpected type %T", x)
   117  		return nil
   118  	}
   119  }