...

Source file src/github.com/pelletier/go-toml/v2/errors_test.go

Documentation: github.com/pelletier/go-toml/v2

     1  package toml
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"fmt"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/pelletier/go-toml/v2/unstable"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  //nolint:funlen
    15  func TestDecodeError(t *testing.T) {
    16  
    17  	examples := []struct {
    18  		desc     string
    19  		doc      [3]string
    20  		msg      string
    21  		expected string
    22  	}{
    23  		{
    24  			desc: "no context",
    25  			doc:  [3]string{"", "morning", ""},
    26  			msg:  "this is wrong",
    27  			expected: `
    28  1| morning
    29   | ~~~~~~~ this is wrong`,
    30  		},
    31  		{
    32  			desc: "one line",
    33  			doc:  [3]string{"good ", "morning", " everyone"},
    34  			msg:  "this is wrong",
    35  			expected: `
    36  1| good morning everyone
    37   |      ~~~~~~~ this is wrong`,
    38  		},
    39  		{
    40  			desc: "exactly 3 lines",
    41  			doc: [3]string{`line1
    42  line2
    43  line3
    44  before `, "highlighted", ` after
    45  post line 1
    46  post line 2
    47  post line 3`},
    48  			msg: "this is wrong",
    49  			expected: `
    50  1| line1
    51  2| line2
    52  3| line3
    53  4| before highlighted after
    54   |        ~~~~~~~~~~~ this is wrong
    55  5| post line 1
    56  6| post line 2
    57  7| post line 3`,
    58  		},
    59  		{
    60  			desc: "more than 3 lines",
    61  			doc: [3]string{`should not be seen1
    62  should not be seen2
    63  line1
    64  line2
    65  line3
    66  before `, "highlighted", ` after
    67  post line 1
    68  post line 2
    69  post line 3
    70  should not be seen3
    71  should not be seen4`},
    72  			msg: "this is wrong",
    73  			expected: `
    74  3| line1
    75  4| line2
    76  5| line3
    77  6| before highlighted after
    78   |        ~~~~~~~~~~~ this is wrong
    79  7| post line 1
    80  8| post line 2
    81  9| post line 3`,
    82  		},
    83  		{
    84  			desc: "more than 10 total lines",
    85  			doc: [3]string{`should not be seen 0
    86  should not be seen1
    87  should not be seen2
    88  should not be seen3
    89  line1
    90  line2
    91  line3
    92  before `, "highlighted", ` after
    93  post line 1
    94  post line 2
    95  post line 3
    96  should not be seen3
    97  should not be seen4`},
    98  			msg: "this is wrong",
    99  			expected: `
   100   5| line1
   101   6| line2
   102   7| line3
   103   8| before highlighted after
   104    |        ~~~~~~~~~~~ this is wrong
   105   9| post line 1
   106  10| post line 2
   107  11| post line 3`,
   108  		},
   109  		{
   110  			desc: "last line of more than 10",
   111  			doc: [3]string{`should not be seen
   112  should not be seen
   113  should not be seen
   114  should not be seen
   115  should not be seen
   116  should not be seen
   117  should not be seen
   118  line1
   119  line2
   120  line3
   121  before `, "highlighted", ``},
   122  			msg: "this is wrong",
   123  			expected: `
   124   8| line1
   125   9| line2
   126  10| line3
   127  11| before highlighted
   128    |        ~~~~~~~~~~~ this is wrong
   129  `,
   130  		},
   131  		{
   132  			desc: "handle empty lines in the before/after blocks",
   133  			doc: [3]string{
   134  				`line1
   135  
   136  line 2
   137  before `, "highlighted", ` after
   138  line 3
   139  
   140  line 4
   141  line 5`,
   142  			},
   143  			expected: `1| line1
   144  2|
   145  3| line 2
   146  4| before highlighted after
   147   |        ~~~~~~~~~~~
   148  5| line 3
   149  6|
   150  7| line 4`,
   151  		},
   152  		{
   153  			desc: "handle remainder of the error line when there is only one line",
   154  			doc:  [3]string{`P=`, `[`, `#`},
   155  			msg:  "array is incomplete",
   156  			expected: `1| P=[#
   157   |   ~ array is incomplete`,
   158  		},
   159  	}
   160  
   161  	for _, e := range examples {
   162  		e := e
   163  		t.Run(e.desc, func(t *testing.T) {
   164  
   165  			b := bytes.Buffer{}
   166  			b.Write([]byte(e.doc[0]))
   167  			start := b.Len()
   168  			b.Write([]byte(e.doc[1]))
   169  			end := b.Len()
   170  			b.Write([]byte(e.doc[2]))
   171  			doc := b.Bytes()
   172  			hl := doc[start:end]
   173  
   174  			err := wrapDecodeError(doc, &unstable.ParserError{
   175  				Highlight: hl,
   176  				Message:   e.msg,
   177  			})
   178  
   179  			var derr *DecodeError
   180  			if !errors.As(err, &derr) {
   181  				t.Errorf("error not in expected format")
   182  
   183  				return
   184  			}
   185  
   186  			assert.Equal(t, strings.Trim(e.expected, "\n"), derr.String())
   187  		})
   188  	}
   189  }
   190  
   191  func TestDecodeError_Accessors(t *testing.T) {
   192  
   193  	e := DecodeError{
   194  		message: "foo",
   195  		line:    1,
   196  		column:  2,
   197  		key:     []string{"one", "two"},
   198  		human:   "bar",
   199  	}
   200  	assert.Equal(t, "toml: foo", e.Error())
   201  	r, c := e.Position()
   202  	assert.Equal(t, 1, r)
   203  	assert.Equal(t, 2, c)
   204  	assert.Equal(t, Key{"one", "two"}, e.Key())
   205  	assert.Equal(t, "bar", e.String())
   206  }
   207  
   208  func ExampleDecodeError() {
   209  	doc := `name = 123__456`
   210  
   211  	s := map[string]interface{}{}
   212  	err := Unmarshal([]byte(doc), &s)
   213  
   214  	fmt.Println(err)
   215  
   216  	var derr *DecodeError
   217  	if errors.As(err, &derr) {
   218  		fmt.Println(derr.String())
   219  		row, col := derr.Position()
   220  		fmt.Println("error occurred at row", row, "column", col)
   221  	}
   222  	// Output:
   223  	// toml: number must have at least one digit between underscores
   224  	// 1| name = 123__456
   225  	//  |           ~~ number must have at least one digit between underscores
   226  	// error occurred at row 1 column 11
   227  }
   228  

View as plain text