github.com/hashicorp/hcl/v2@v2.20.0/pos_scanner_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package hcl 5 6 import ( 7 "bufio" 8 "reflect" 9 "testing" 10 11 "github.com/davecgh/go-spew/spew" 12 ) 13 14 func TestPosScanner(t *testing.T) { 15 tests := map[string]struct { 16 Input string 17 Want []Range 18 WantToks [][]byte 19 }{ 20 "empty": { 21 "", 22 []Range{}, 23 [][]byte{}, 24 }, 25 "single line": { 26 "hello", 27 []Range{ 28 { 29 Start: Pos{Byte: 0, Line: 1, Column: 1}, 30 End: Pos{Byte: 5, Line: 1, Column: 6}, 31 }, 32 }, 33 [][]byte{ 34 []byte("hello"), 35 }, 36 }, 37 "single line with trailing UNIX newline": { 38 "hello\n", 39 []Range{ 40 { 41 Start: Pos{Byte: 0, Line: 1, Column: 1}, 42 End: Pos{Byte: 5, Line: 1, Column: 6}, 43 }, 44 }, 45 [][]byte{ 46 []byte("hello"), 47 }, 48 }, 49 "single line with trailing Windows newline": { 50 "hello\r\n", 51 []Range{ 52 { 53 Start: Pos{Byte: 0, Line: 1, Column: 1}, 54 End: Pos{Byte: 5, Line: 1, Column: 6}, 55 }, 56 }, 57 [][]byte{ 58 []byte("hello"), 59 }, 60 }, 61 "two lines with UNIX newline": { 62 "hello\nworld", 63 []Range{ 64 { 65 Start: Pos{Byte: 0, Line: 1, Column: 1}, 66 End: Pos{Byte: 5, Line: 1, Column: 6}, 67 }, 68 { 69 Start: Pos{Byte: 6, Line: 2, Column: 1}, 70 End: Pos{Byte: 11, Line: 2, Column: 6}, 71 }, 72 }, 73 [][]byte{ 74 []byte("hello"), 75 []byte("world"), 76 }, 77 }, 78 "two lines with Windows newline": { 79 "hello\r\nworld", 80 []Range{ 81 { 82 Start: Pos{Byte: 0, Line: 1, Column: 1}, 83 End: Pos{Byte: 5, Line: 1, Column: 6}, 84 }, 85 { 86 Start: Pos{Byte: 7, Line: 2, Column: 1}, 87 End: Pos{Byte: 12, Line: 2, Column: 6}, 88 }, 89 }, 90 [][]byte{ 91 []byte("hello"), 92 []byte("world"), 93 }, 94 }, 95 "blank line with UNIX newlines": { 96 "hello\n\nworld", 97 []Range{ 98 { 99 Start: Pos{Byte: 0, Line: 1, Column: 1}, 100 End: Pos{Byte: 5, Line: 1, Column: 6}, 101 }, 102 { 103 Start: Pos{Byte: 6, Line: 2, Column: 1}, 104 End: Pos{Byte: 6, Line: 2, Column: 1}, 105 }, 106 { 107 Start: Pos{Byte: 7, Line: 3, Column: 1}, 108 End: Pos{Byte: 12, Line: 3, Column: 6}, 109 }, 110 }, 111 [][]byte{ 112 []byte("hello"), 113 []byte(""), 114 []byte("world"), 115 }, 116 }, 117 "blank line with Windows newlines": { 118 "hello\r\n\r\nworld", 119 []Range{ 120 { 121 Start: Pos{Byte: 0, Line: 1, Column: 1}, 122 End: Pos{Byte: 5, Line: 1, Column: 6}, 123 }, 124 { 125 Start: Pos{Byte: 7, Line: 2, Column: 1}, 126 End: Pos{Byte: 7, Line: 2, Column: 1}, 127 }, 128 { 129 Start: Pos{Byte: 9, Line: 3, Column: 1}, 130 End: Pos{Byte: 14, Line: 3, Column: 6}, 131 }, 132 }, 133 [][]byte{ 134 []byte("hello"), 135 []byte(""), 136 []byte("world"), 137 }, 138 }, 139 "two lines with combiner and UNIX newline": { 140 "foo \U0001f469\U0001f3ff bar\nbaz", 141 []Range{ 142 { 143 Start: Pos{Byte: 0, Line: 1, Column: 1}, 144 End: Pos{Byte: 16, Line: 1, Column: 10}, 145 }, 146 { 147 Start: Pos{Byte: 17, Line: 2, Column: 1}, 148 End: Pos{Byte: 20, Line: 2, Column: 4}, 149 }, 150 }, 151 [][]byte{ 152 []byte("foo \U0001f469\U0001f3ff bar"), 153 []byte("baz"), 154 }, 155 }, 156 "two lines with combiner and Windows newline": { 157 "foo \U0001f469\U0001f3ff bar\r\nbaz", 158 []Range{ 159 { 160 Start: Pos{Byte: 0, Line: 1, Column: 1}, 161 End: Pos{Byte: 16, Line: 1, Column: 10}, 162 }, 163 { 164 Start: Pos{Byte: 18, Line: 2, Column: 1}, 165 End: Pos{Byte: 21, Line: 2, Column: 4}, 166 }, 167 }, 168 [][]byte{ 169 []byte("foo \U0001f469\U0001f3ff bar"), 170 []byte("baz"), 171 }, 172 }, 173 } 174 175 for name, test := range tests { 176 t.Run(name, func(t *testing.T) { 177 src := []byte(test.Input) 178 sc := NewRangeScanner(src, "", bufio.ScanLines) 179 got := make([]Range, 0) 180 gotToks := make([][]byte, 0) 181 for sc.Scan() { 182 got = append(got, sc.Range()) 183 gotToks = append(gotToks, sc.Bytes()) 184 } 185 if sc.Err() != nil { 186 t.Fatalf("unexpected error: %s", sc.Err()) 187 } 188 if !reflect.DeepEqual(got, test.Want) { 189 t.Errorf("incorrect ranges\ngot: %swant: %s", spew.Sdump(got), spew.Sdump(test.Want)) 190 } 191 if !reflect.DeepEqual(gotToks, test.WantToks) { 192 t.Errorf("incorrect tokens\ngot: %swant: %s", spew.Sdump(gotToks), spew.Sdump(test.WantToks)) 193 } 194 }) 195 } 196 }