github.com/jhump/golang-x-tools@v0.0.0-20220218190644-4958d6d39439/go/analysis/validate_test.go (about)

     1  // Copyright 2020 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  package analysis
     6  
     7  import (
     8  	"strings"
     9  	"testing"
    10  )
    11  
    12  func TestValidate(t *testing.T) {
    13  	var (
    14  		dependsOnSelf = &Analyzer{
    15  			Name: "dependsOnSelf",
    16  			Doc:  "this analyzer depends on itself",
    17  		}
    18  		inCycleA = &Analyzer{
    19  			Name: "inCycleA",
    20  			Doc:  "this analyzer depends on inCycleB",
    21  		}
    22  		inCycleB = &Analyzer{
    23  			Name: "inCycleB",
    24  			Doc:  "this analyzer depends on inCycleA and notInCycleA",
    25  		}
    26  		pointsToCycle = &Analyzer{
    27  			Name: "pointsToCycle",
    28  			Doc:  "this analyzer depends on inCycleA",
    29  		}
    30  		notInCycleA = &Analyzer{
    31  			Name: "notInCycleA",
    32  			Doc:  "this analyzer depends on notInCycleB and notInCycleC",
    33  		}
    34  		notInCycleB = &Analyzer{
    35  			Name: "notInCycleB",
    36  			Doc:  "this analyzer depends on notInCycleC",
    37  		}
    38  		notInCycleC = &Analyzer{
    39  			Name: "notInCycleC",
    40  			Doc:  "this analyzer has no dependencies",
    41  		}
    42  	)
    43  
    44  	dependsOnSelf.Requires = append(dependsOnSelf.Requires, dependsOnSelf)
    45  	inCycleA.Requires = append(inCycleA.Requires, inCycleB)
    46  	inCycleB.Requires = append(inCycleB.Requires, inCycleA, notInCycleA)
    47  	pointsToCycle.Requires = append(pointsToCycle.Requires, inCycleA)
    48  	notInCycleA.Requires = append(notInCycleA.Requires, notInCycleB, notInCycleC)
    49  	notInCycleB.Requires = append(notInCycleB.Requires, notInCycleC)
    50  	notInCycleC.Requires = []*Analyzer{}
    51  
    52  	cases := []struct {
    53  		analyzers        []*Analyzer
    54  		wantErr          bool
    55  		analyzersInCycle map[string]bool
    56  	}{
    57  		{
    58  			[]*Analyzer{dependsOnSelf},
    59  			true,
    60  			map[string]bool{"dependsOnSelf": true},
    61  		},
    62  		{
    63  			[]*Analyzer{inCycleA, inCycleB},
    64  			true,
    65  			map[string]bool{"inCycleA": true, "inCycleB": true},
    66  		},
    67  		{
    68  			[]*Analyzer{pointsToCycle},
    69  			true,
    70  			map[string]bool{"inCycleA": true, "inCycleB": true},
    71  		},
    72  		{
    73  			[]*Analyzer{notInCycleA},
    74  			false,
    75  			map[string]bool{},
    76  		},
    77  	}
    78  
    79  	for _, c := range cases {
    80  		got := Validate(c.analyzers)
    81  
    82  		if !c.wantErr {
    83  			if got == nil {
    84  				continue
    85  			}
    86  			t.Errorf("got unexpected error while validating analyzers %v: %v", c.analyzers, got)
    87  		}
    88  
    89  		if got == nil {
    90  			t.Errorf("expected error while validating analyzers %v, but got nil", c.analyzers)
    91  		}
    92  
    93  		err, ok := got.(*CycleInRequiresGraphError)
    94  		if !ok {
    95  			t.Errorf("want CycleInRequiresGraphError, got %T", err)
    96  		}
    97  
    98  		for a := range c.analyzersInCycle {
    99  			if !err.AnalyzerNames[a] {
   100  				t.Errorf("analyzer %s should be in cycle", a)
   101  			}
   102  		}
   103  		for a := range err.AnalyzerNames {
   104  			if !c.analyzersInCycle[a] {
   105  				t.Errorf("analyzer %s should not be in cycle", a)
   106  			}
   107  		}
   108  	}
   109  }
   110  
   111  func TestCycleInRequiresGraphErrorMessage(t *testing.T) {
   112  	err := CycleInRequiresGraphError{}
   113  	errMsg := err.Error()
   114  	wantSubstring := "cycle detected"
   115  	if !strings.Contains(errMsg, wantSubstring) {
   116  		t.Errorf("error string %s does not contain expected substring %q", errMsg, wantSubstring)
   117  	}
   118  }