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 }