| 234 | } |
| 235 | |
| 236 | func TestDecodeError_Position(t *testing.T) { |
| 237 | // Test that error positions are correctly reported for various error locations |
| 238 | examples := []struct { |
| 239 | name string |
| 240 | doc string |
| 241 | expectedRow int |
| 242 | minCol int |
| 243 | }{ |
| 244 | { |
| 245 | name: "error on first line", |
| 246 | doc: `a = 1__2`, |
| 247 | expectedRow: 1, |
| 248 | minCol: 5, |
| 249 | }, |
| 250 | { |
| 251 | name: "error on second line", |
| 252 | doc: "a = 1\nb = 2__3", |
| 253 | expectedRow: 2, |
| 254 | minCol: 5, |
| 255 | }, |
| 256 | { |
| 257 | name: "error on third line", |
| 258 | doc: "a = 1\nb = 2\nc = 3__4", |
| 259 | expectedRow: 3, |
| 260 | minCol: 5, |
| 261 | }, |
| 262 | { |
| 263 | name: "missing equals on last line without trailing newline", |
| 264 | doc: "a = 1\nb = 2\nc", |
| 265 | expectedRow: 3, |
| 266 | minCol: 1, |
| 267 | }, |
| 268 | } |
| 269 | |
| 270 | for _, e := range examples { |
| 271 | t.Run(e.name, func(t *testing.T) { |
| 272 | var v map[string]int |
| 273 | err := Unmarshal([]byte(e.doc), &v) |
| 274 | |
| 275 | var derr *DecodeError |
| 276 | if !errors.As(err, &derr) { |
| 277 | t.Fatal("error not in expected format") |
| 278 | } |
| 279 | |
| 280 | row, col := derr.Position() |
| 281 | assert.Equal(t, e.expectedRow, row) |
| 282 | if col < e.minCol { |
| 283 | t.Errorf("expected column >= %d, got %d", e.minCol, col) |
| 284 | } |
| 285 | }) |
| 286 | } |
| 287 | } |
| 288 | |
| 289 | func TestStrictErrorUnwrap(t *testing.T) { |
| 290 | fo := bytes.NewBufferString(` |