github.com/Johnny2210/revive@v1.0.8-0.20210625134200-febf37ccd0f5/testdata/cognitive-complexity.go (about)

     1  // Test of cognitive complexity.
     2  
     3  // Package pkg ...
     4  package pkg
     5  
     6  import (
     7  	"fmt"
     8  	ast "go/ast"
     9  	"log"
    10  	"testing"
    11  
    12  	"k8s.io/klog"
    13  )
    14  
    15  // Test IF and Boolean expr
    16  func f(x int) bool { // MATCH /function f has cognitive complexity 3 (> max enabled 0)/
    17  	if x > 0 && true || false { // +3
    18  		return true
    19  	} else {
    20  		log.Printf("non-positive x: %d", x)
    21  	}
    22  	return false
    23  }
    24  
    25  // Test IF
    26  func g(f func() bool) string { // MATCH /function g has cognitive complexity 1 (> max enabled 0)/
    27  	if ok := f(); ok { // +1
    28  		return "it's okay"
    29  	} else {
    30  		return "it's NOT okay!"
    31  	}
    32  }
    33  
    34  // Test Boolean expr
    35  func h(a, b, c, d, e, f bool) bool { // MATCH /function h has cognitive complexity 3 (> max enabled 0)/
    36  	return a && b && c || d || e && f // +3
    37  }
    38  
    39  func i(a, b, c, d, e, f bool) bool { // MATCH /function i has cognitive complexity 2 (> max enabled 0)/
    40  	result := a && b && c || d || e // +2
    41  	return result
    42  }
    43  
    44  func j(a, b, c, d, e, f bool) bool { // MATCH /function j has cognitive complexity 2 (> max enabled 0)/
    45  	result := z(a && !(b && c)) // +2
    46  	return result
    47  }
    48  
    49  func j1(a, b, c, d, e, f bool) bool { // MATCH /function j1 has cognitive complexity 2 (> max enabled 0)/
    50  	return (a && !(b < 2) || c)
    51  }
    52  
    53  // Test Switch expr
    54  func k(a, b, c, d, e, f bool) bool { // MATCH /function k has cognitive complexity 1 (> max enabled 0)/
    55  	switch expr { // +1
    56  	case cond1:
    57  	case cond2:
    58  	default:
    59  	}
    60  
    61  	return result
    62  }
    63  
    64  // Test nesting FOR expr + nested IF
    65  func l() { // MATCH /function l has cognitive complexity 6 (> max enabled 0)/
    66  	for i := 1; i <= max; i++ { // +1
    67  		for j := 2; j < i; j++ { // +1 +1(nesting)
    68  			if i%j == 0 { // +1 +2(nesting)
    69  				continue
    70  			}
    71  		}
    72  
    73  		total += i
    74  	}
    75  	return total
    76  }
    77  
    78  // Test nesting IF
    79  func m() { // MATCH /function m has cognitive complexity 6 (> max enabled 0)/
    80  	if i <= max { // +1
    81  		if j < i { // +1 +1(nesting)
    82  			if i%j == 0 { // +1 +2(nesting)
    83  				return 0
    84  			}
    85  		}
    86  
    87  		total += i
    88  	}
    89  	return total
    90  }
    91  
    92  // Test nesting IF + nested FOR
    93  func n() { // MATCH /function n has cognitive complexity 6 (> max enabled 0)/
    94  	if i > max { // +1
    95  		for j := 2; j < i; j++ { // +1 +1(nesting)
    96  			if i%j == 0 { // +1 +2(nesting)
    97  				continue
    98  			}
    99  		}
   100  
   101  		total += i
   102  	}
   103  	return total
   104  }
   105  
   106  // Test nesting
   107  func o() { // MATCH /function o has cognitive complexity 12 (> max enabled 0)/
   108  	if i > max { // +1
   109  		if j < i { // +1 +1(nesting)
   110  			if i%j == 0 { // +1 +2(nesting)
   111  				return
   112  			}
   113  		}
   114  
   115  		total += i
   116  	}
   117  
   118  	if i > max { // +1
   119  		if j < i { // +1 +1(nesting)
   120  			if i%j == 0 { // +1 +2(nesting)
   121  				return
   122  			}
   123  		}
   124  
   125  		total += i
   126  	}
   127  }
   128  
   129  // Tests TYPE SWITCH
   130  func p() { // MATCH /function p has cognitive complexity 1 (> max enabled 0)/
   131  	switch n := n.(type) { // +1
   132  	case *ast.IfStmt:
   133  		targets := []ast.Node{n.Cond, n.Body, n.Else}
   134  		v.walk(targets...)
   135  		return nil
   136  	case *ast.ForStmt:
   137  		v.walk(n.Body)
   138  		return nil
   139  	case *ast.TypeSwitchStmt:
   140  		v.walk(n.Body)
   141  		return nil
   142  	case *ast.BinaryExpr:
   143  		v.complexity += v.binExpComplexity(n)
   144  		return nil
   145  	}
   146  }
   147  
   148  // Test RANGE
   149  func q() { // MATCH /function q has cognitive complexity 1 (> max enabled 0)/
   150  	for _, t := range targets { // +1
   151  		ast.Walk(v, t)
   152  	}
   153  }
   154  
   155  // Tests SELECT
   156  func r() { // MATCH /function r has cognitive complexity 1 (> max enabled 0)/
   157  	select { // +1
   158  	case c <- x:
   159  		x, y = y, x+y
   160  	case <-quit:
   161  		fmt.Println("quit")
   162  		return
   163  	}
   164  }
   165  
   166  // Test jump to label
   167  func s() { // MATCH /function s has cognitive complexity 3 (> max enabled 0)/
   168  FirstLoop:
   169  	for i := 0; i < 10; i++ { // +1
   170  		break
   171  	}
   172  	for i := 0; i < 10; i++ { // +1
   173  		break FirstLoop // +1
   174  	}
   175  }
   176  
   177  func t() { // MATCH /function t has cognitive complexity 2 (> max enabled 0)/
   178  FirstLoop:
   179  	for i := 0; i < 10; i++ { // +1
   180  		goto FirstLoop // +1
   181  	}
   182  }
   183  
   184  func u() { // MATCH /function u has cognitive complexity 3 (> max enabled 0)/
   185  FirstLoop:
   186  	for i := 0; i < 10; i++ { // +1
   187  		continue
   188  	}
   189  	for i := 0; i < 10; i++ { // +1
   190  		continue FirstLoop // +1
   191  	}
   192  }
   193  
   194  // Tests FUNC LITERAL
   195  func v() { // MATCH /function v has cognitive complexity 2 (> max enabled 0)/
   196  	myFunc := func(b bool) {
   197  		if b { // +1 +1(nesting)
   198  
   199  		}
   200  	}
   201  }
   202  
   203  func v() {
   204  	t.Run(tc.desc, func(t *testing.T) {})
   205  }
   206  
   207  func w() { // MATCH /function w has cognitive complexity 3 (> max enabled 0)/
   208  	defer func(b bool) {
   209  		if b { // +1 +1(nesting)
   210  
   211  		}
   212  	}(false || true) // +1
   213  }
   214  
   215  // Test from Cognitive Complexity white paper
   216  func sumOfPrimes(max int) int { // MATCH /function sumOfPrimes has cognitive complexity 7 (> max enabled 0)/
   217  	total := 0
   218  OUT:
   219  	for i := 1; i <= max; i++ { // +1
   220  		for j := 2; j < i; j++ { // +1 +1(nesting)
   221  			if i%j == 0 { // +1 +2(nesting)
   222  				continue OUT // +1
   223  			}
   224  		}
   225  
   226  		total += i
   227  	}
   228  	return total
   229  }
   230  
   231  // Test from K8S
   232  func (m *Migrator) MigrateIfNeeded(target *EtcdVersionPair) error { // MATCH /function (*Migrator).MigrateIfNeeded has cognitive complexity 18 (> max enabled 0)/
   233  	klog.Infof("Starting migration to %s", target)
   234  	err := m.dataDirectory.Initialize(target)
   235  	if err != nil { // +1
   236  		return fmt.Errorf("failed to initialize data directory %s: %v", m.dataDirectory.path, err)
   237  	}
   238  
   239  	var current *EtcdVersionPair
   240  	vfExists, err := m.dataDirectory.versionFile.Exists()
   241  	if err != nil { // +1
   242  		return err
   243  	}
   244  	if vfExists { // +1
   245  		current, err = m.dataDirectory.versionFile.Read()
   246  		if err != nil { // +1 +1
   247  			return err
   248  		}
   249  	} else {
   250  		return fmt.Errorf("existing data directory '%s' is missing version.txt file, unable to migrate", m.dataDirectory.path)
   251  	}
   252  
   253  	for { // +1
   254  		klog.Infof("Converging current version '%s' to target version '%s'", current, target)
   255  		currentNextMinorVersion := &EtcdVersion{}
   256  		switch { // +1 +1
   257  		case current.version.MajorMinorEquals(target.version) || currentNextMinorVersion.MajorMinorEquals(target.version): // +1
   258  			klog.Infof("current version '%s' equals or is one minor version previous of target version '%s' - migration complete", current, target)
   259  			err = m.dataDirectory.versionFile.Write(target)
   260  			if err != nil { // +1 +2
   261  				return fmt.Errorf("failed to write version.txt to '%s': %v", m.dataDirectory.path, err)
   262  			}
   263  			return nil
   264  		case current.storageVersion == storageEtcd2 && target.storageVersion == storageEtcd3: // +1
   265  			return fmt.Errorf("upgrading from etcd2 storage to etcd3 storage is not supported")
   266  		case current.version.Major == 3 && target.version.Major == 2: // +1
   267  			return fmt.Errorf("downgrading from etcd 3.x to 2.x is not supported")
   268  		case current.version.Major == target.version.Major && current.version.Minor < target.version.Minor: // +1
   269  			stepVersion := m.cfg.supportedVersions.NextVersionPair(current)
   270  			klog.Infof("upgrading etcd from %s to %s", current, stepVersion)
   271  			current, err = m.minorVersionUpgrade(current, stepVersion)
   272  		case current.version.Major == 3 && target.version.Major == 3 && current.version.Minor > target.version.Minor: // +1
   273  			klog.Infof("rolling etcd back from %s to %s", current, target)
   274  			current, err = m.rollbackEtcd3MinorVersion(current, target)
   275  		}
   276  		if err != nil { // +1 +1
   277  			return err
   278  		}
   279  	}
   280  }
   281  
   282  // no regression test for issue #451
   283  func myFunc()