Skip to content

Commit a566061

Browse files
gandarezalecthomas
authored andcommitted
Add set text analyser for MySQL lexer
1 parent d964e7c commit a566061

File tree

4 files changed

+83
-1
lines changed

4 files changed

+83
-1
lines changed

Diff for: lexers/lexers_test.go

+55
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"io/ioutil"
66
"os"
77
"path/filepath"
8+
"strconv"
89
"strings"
910
"testing"
1011

@@ -79,6 +80,11 @@ func TestLexers(t *testing.T) {
7980
assert.NoError(t, err)
8081

8182
for _, file := range files {
83+
// skip text analysis test files
84+
if file.Name() == "analysis" {
85+
continue
86+
}
87+
8288
if file.IsDir() {
8389
dirname := filepath.Join("testdata", file.Name())
8490
lexer := lexers.Get(file.Name())
@@ -117,3 +123,52 @@ func TestLexers(t *testing.T) {
117123
}
118124
}
119125
}
126+
127+
func FileTestAnalysis(t *testing.T, lexer chroma.Lexer, actualFilepath, expectedFilepath string) {
128+
t.Helper()
129+
t.Run(lexer.Config().Name+"/"+actualFilepath, func(t *testing.T) {
130+
expectedData, err := ioutil.ReadFile(expectedFilepath)
131+
assert.NoError(t, err)
132+
133+
analyser, ok := lexer.(chroma.Analyser)
134+
assert.True(t, ok, "lexer %q does not set analyser", lexer.Config().Name)
135+
136+
data, err := ioutil.ReadFile(actualFilepath)
137+
assert.NoError(t, err)
138+
139+
actual := analyser.AnalyseText(string(data))
140+
141+
if os.Getenv("RECORD") == "true" {
142+
// Update the expected file with the generated output of this lexer
143+
f, err := os.Create(expectedFilepath)
144+
defer f.Close() // nolint: gosec
145+
assert.NoError(t, err)
146+
147+
_, err = f.WriteString(strconv.FormatFloat(float64(actual), 'f', -1, 32))
148+
assert.NoError(t, err)
149+
} else {
150+
expected, err := strconv.ParseFloat(strings.TrimSpace(string(expectedData)), 32)
151+
assert.NoError(t, err)
152+
153+
assert.Equal(t, float32(expected), actual)
154+
}
155+
})
156+
}
157+
158+
func TestLexersTextAnalyser(t *testing.T) {
159+
files, err := filepath.Glob("testdata/analysis/*.actual")
160+
assert.NoError(t, err)
161+
162+
for _, actualFilepath := range files {
163+
filename := filepath.Base(actualFilepath)
164+
baseFilename := strings.TrimSuffix(filename, filepath.Ext(filename))
165+
lexerName := strings.Split(baseFilename, ".")[0]
166+
167+
lexer := lexers.Get(lexerName)
168+
assert.NotNil(t, lexer, "no lexer found for name %q", lexerName)
169+
170+
expectedFilepath := "testdata/analysis/" + baseFilename + ".expected"
171+
172+
FileTestAnalysis(t, lexer, actualFilepath, expectedFilepath)
173+
}
174+
}

Diff for: lexers/m/mysql.go

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package m
22

33
import (
4+
"regexp"
5+
46
. "github.com/alecthomas/chroma" // nolint
57
"github.com/alecthomas/chroma/lexers/internal"
68
)
79

10+
var (
11+
mysqlAnalyserNameBetweenBacktickRe = regexp.MustCompile("`[a-zA-Z_]\\w*`")
12+
mysqlAnalyserNameBetweenBracketRe = regexp.MustCompile(`\[[a-zA-Z_]\w*\]`)
13+
)
14+
815
// MySQL lexer.
916
var MySQL = internal.Register(MustNewLazyLexer(
1017
&Config{
@@ -16,7 +23,25 @@ var MySQL = internal.Register(MustNewLazyLexer(
1623
CaseInsensitive: true,
1724
},
1825
mySQLRules,
19-
))
26+
).SetAnalyser(func(text string) float32 {
27+
nameBetweenBacktickCount := len(mysqlAnalyserNameBetweenBacktickRe.FindAllString(text, -1))
28+
nameBetweenBracketCount := len(mysqlAnalyserNameBetweenBracketRe.FindAllString(text, -1))
29+
30+
var result float32
31+
32+
// Same logic as above in the TSQL analysis.
33+
dialectNameCount := nameBetweenBacktickCount + nameBetweenBracketCount
34+
if dialectNameCount >= 1 && nameBetweenBacktickCount >= (2*nameBetweenBracketCount) {
35+
// Found at least twice as many `name` as [name].
36+
result += 0.5
37+
} else if nameBetweenBacktickCount > nameBetweenBracketCount {
38+
result += 0.2
39+
} else if nameBetweenBacktickCount > 0 {
40+
result += 0.1
41+
}
42+
43+
return result
44+
}))
2045

2146
func mySQLRules() Rules {
2247
return Rules{

Diff for: lexers/testdata/analysis/mysql.backtick.actual

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CREATE TABLE `my_table` (id INT);

Diff for: lexers/testdata/analysis/mysql.backtick.expected

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0.5

0 commit comments

Comments
 (0)