error_locator_test.go (3549B)
1 // Copyright 2022 The Hugo Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 // http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13
14 // Package herrors contains common Hugo errors and error related utilities.
15 package herrors
16
17 import (
18 "strings"
19 "testing"
20
21 qt "github.com/frankban/quicktest"
22 )
23
24 func TestErrorLocator(t *testing.T) {
25 c := qt.New(t)
26
27 lineMatcher := func(m LineMatcher) int {
28 if strings.Contains(m.Line, "THEONE") {
29 return 1
30 }
31 return -1
32 }
33
34 lines := `LINE 1
35 LINE 2
36 LINE 3
37 LINE 4
38 This is THEONE
39 LINE 6
40 LINE 7
41 LINE 8
42 `
43
44 location := locateErrorInString(lines, lineMatcher)
45 pos := location.Position
46 c.Assert(location.Lines, qt.DeepEquals, []string{"LINE 3", "LINE 4", "This is THEONE", "LINE 6", "LINE 7"})
47
48 c.Assert(pos.LineNumber, qt.Equals, 5)
49 c.Assert(location.LinesPos, qt.Equals, 2)
50
51 locate := func(s string, m LineMatcherFn) *ErrorContext {
52 ctx := locateErrorInString(s, m)
53 return ctx
54 }
55
56 c.Assert(locate(`This is THEONE`, lineMatcher).Lines, qt.DeepEquals, []string{"This is THEONE"})
57
58 location = locateErrorInString(`L1
59 This is THEONE
60 L2
61 `, lineMatcher)
62 pos = location.Position
63 c.Assert(pos.LineNumber, qt.Equals, 2)
64 c.Assert(location.LinesPos, qt.Equals, 1)
65 c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This is THEONE", "L2", ""})
66
67 location = locate(`This is THEONE
68 L2
69 `, lineMatcher)
70 c.Assert(location.LinesPos, qt.Equals, 0)
71 c.Assert(location.Lines, qt.DeepEquals, []string{"This is THEONE", "L2", ""})
72
73 location = locate(`L1
74 This THEONE
75 `, lineMatcher)
76 c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "This THEONE", ""})
77 c.Assert(location.LinesPos, qt.Equals, 1)
78
79 location = locate(`L1
80 L2
81 This THEONE
82 `, lineMatcher)
83 c.Assert(location.Lines, qt.DeepEquals, []string{"L1", "L2", "This THEONE", ""})
84 c.Assert(location.LinesPos, qt.Equals, 2)
85
86 location = locateErrorInString("NO MATCH", lineMatcher)
87 pos = location.Position
88 c.Assert(pos.LineNumber, qt.Equals, 0)
89 c.Assert(location.LinesPos, qt.Equals, -1)
90 c.Assert(len(location.Lines), qt.Equals, 0)
91
92 lineMatcher = func(m LineMatcher) int {
93 if m.LineNumber == 6 {
94 return 1
95 }
96 return -1
97 }
98
99 location = locateErrorInString(`A
100 B
101 C
102 D
103 E
104 F
105 G
106 H
107 I
108 J`, lineMatcher)
109 pos = location.Position
110
111 c.Assert(location.Lines, qt.DeepEquals, []string{"D", "E", "F", "G", "H"})
112 c.Assert(pos.LineNumber, qt.Equals, 6)
113 c.Assert(location.LinesPos, qt.Equals, 2)
114
115 // Test match EOF
116 lineMatcher = func(m LineMatcher) int {
117 if m.LineNumber == 4 {
118 return 1
119 }
120 return -1
121 }
122
123 location = locateErrorInString(`A
124 B
125 C
126 `, lineMatcher)
127
128 pos = location.Position
129
130 c.Assert(location.Lines, qt.DeepEquals, []string{"B", "C", ""})
131 c.Assert(pos.LineNumber, qt.Equals, 4)
132 c.Assert(location.LinesPos, qt.Equals, 2)
133
134 offsetMatcher := func(m LineMatcher) int {
135 if m.Offset == 1 {
136 return 1
137 }
138 return -1
139 }
140
141 location = locateErrorInString(`A
142 B
143 C
144 D
145 E`, offsetMatcher)
146
147 pos = location.Position
148
149 c.Assert(location.Lines, qt.DeepEquals, []string{"A", "B", "C", "D"})
150 c.Assert(pos.LineNumber, qt.Equals, 2)
151 c.Assert(location.LinesPos, qt.Equals, 1)
152 }