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  }