/ tools / linters / ll_test.go
ll_test.go
  1  package linters
  2  
  3  import (
  4  	"os"
  5  	"regexp"
  6  	"strings"
  7  	"testing"
  8  
  9  	"github.com/stretchr/testify/require"
 10  )
 11  
 12  // TestGetLLLIssuesForFile tests the line-too-long linter.
 13  //
 14  //nolint:ll
 15  func TestGetLLLIssuesForFile(t *testing.T) {
 16  	// Test data
 17  	testCases := []struct {
 18  		name          string
 19  		content       string
 20  		logRegex      string
 21  		expectedIssue []string
 22  	}{
 23  		{
 24  			name: "Single long line",
 25  			content: `
 26  				fmt.Println("This is a very long line that exceeds the maximum length and should be flagged by the linter.")`,
 27  			logRegex: defaultLogRegex,
 28  			expectedIssue: []string{
 29  				"the line is 140 characters long, which " +
 30  					"exceeds the maximum of 80 characters.",
 31  			},
 32  		},
 33  		{
 34  			name: "Multiple long lines",
 35  			content: `
 36  				fmt.Println("This is a very long line that exceeds the maximum length and should be flagged by the linter.")
 37  				fmt.Println("This is a another very long line that exceeds the maximum length and should be flagged by the linter.")`,
 38  			logRegex: defaultLogRegex,
 39  			expectedIssue: []string{
 40  				"the line is 140 characters long, which " +
 41  					"exceeds the maximum of 80 characters.",
 42  				"the line is 148 characters long, which " +
 43  					"exceeds the maximum of 80 characters.",
 44  			},
 45  		},
 46  		{
 47  			name:     "Short lines",
 48  			logRegex: defaultLogRegex,
 49  			content: `
 50  				fmt.Println("Short line")`,
 51  		},
 52  		{
 53  			name:     "Directive ignored",
 54  			logRegex: defaultLogRegex,
 55  			content:  `//go:generate something very very very very very very very very very long and complex here wowowow`,
 56  		},
 57  		{
 58  			name:     "Long single line import",
 59  			logRegex: defaultLogRegex,
 60  			content:  `import "github.com/lightningnetwork/lnd/lnrpc/walletrpc/more/more/more/more/more/more/ok/that/is/enough"`,
 61  		},
 62  		{
 63  			name:     "Multi-line import",
 64  			logRegex: defaultLogRegex,
 65  			content: `
 66  			import (
 67  				"os"
 68  				"fmt"
 69  				"github.com/lightningnetwork/lnd/lnrpc/walletrpc/more/ok/that/is/enough"
 70  			)`,
 71  		},
 72  		{
 73  			name:     "Long single line log",
 74  			logRegex: defaultLogRegex,
 75  			content: `
 76  			log.Infof("This is a very long log line but since it is a log line, it should be skipped by the linter."),
 77  			rpcLog.Info("Another long log line with a slightly different name and should still be skipped")`,
 78  		},
 79  		{
 80  			name:     "Long single line log followed by a non-log line",
 81  			logRegex: defaultLogRegex,
 82  			content: `
 83  				log.Infof("This is a very long log line but since it is a log line, it should be skipped by the linter.")
 84  				fmt.Println("This is a very long line that exceeds the maximum length and should be flagged by the linter.")`,
 85  			expectedIssue: []string{
 86  				"the line is 140 characters long, which " +
 87  					"exceeds the maximum of 80 characters.",
 88  			},
 89  		},
 90  		{
 91  			name:     "Multi-line log",
 92  			logRegex: defaultLogRegex,
 93  			content: `
 94  				log.Infof("This is a very long log line but 
 95  						since it is a log line, it 
 96  						should be skipped by the linter.")`,
 97  		},
 98  		{
 99  			name:     "Multi-line log followed by a non-log line",
100  			logRegex: defaultLogRegex,
101  			content: `
102  				log.Infof("This is a very long log line but 
103  						since it is a log line, it 
104  						should be skipped by the linter.")
105  				fmt.Println("This is a very long line that 
106  						exceeds the maximum length and 
107  						should be flagged by the linter.")`,
108  			expectedIssue: []string{
109  				"the line is 82 characters long, which " +
110  					"exceeds the maximum of 80 characters.",
111  			},
112  		},
113  		{
114  			name:     "Only skip 'S' logs",
115  			logRegex: `^\s*.*(L|l)og\.(Info|Debug|Trace|Warn|Error|Critical)S\(`,
116  			content: `
117  				log.Infof("A long log line but it is not an S log and so should be caught")
118  				log.InfoS("This is a very long log line but 
119  						since it is an 'S' log line, it 
120  						should be skipped by the linter.")
121  				log.TraceS("Another S log that should be skipped by the linter")`,
122  			expectedIssue: []string{
123  				"the line is 107 characters long, which " +
124  					"exceeds the maximum of 80 characters.",
125  			},
126  		},
127  	}
128  
129  	tabSpaces := strings.Repeat(" ", defaultTabWidthInSpaces)
130  
131  	for _, tc := range testCases {
132  		t.Run(tc.name, func(t *testing.T) {
133  			logRegex := regexp.MustCompile(tc.logRegex)
134  
135  			// Write content to a temporary file.
136  			tmpFile := t.TempDir() + "/test.go"
137  			err := os.WriteFile(tmpFile, []byte(tc.content), 0644)
138  			require.NoError(t, err)
139  
140  			// Run the linter on the file.
141  			issues, err := getLLLIssuesForFile(
142  				tmpFile, defaultMaxLineLen, tabSpaces, logRegex,
143  			)
144  			require.NoError(t, err)
145  
146  			require.Len(t, issues, len(tc.expectedIssue))
147  
148  			for i, issue := range issues {
149  				require.Equal(
150  					t, tc.expectedIssue[i], issue.text,
151  				)
152  			}
153  		})
154  	}
155  }