github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/pkg/lineio/lineio_test.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package lineio
     6  
     7  import (
     8  	"bytes"
     9  	"io"
    10  	"reflect"
    11  	"regexp"
    12  	"testing"
    13  )
    14  
    15  type lineCase struct {
    16  	line    int64
    17  	bufSize int
    18  	err     error
    19  	data    string
    20  	size    int
    21  }
    22  
    23  type dataCase struct {
    24  	data  string
    25  	tests []lineCase
    26  }
    27  
    28  var cases = []dataCase{
    29  	{
    30  		data: `Hello World!`,
    31  		tests: []lineCase{
    32  			{
    33  				line:    1,
    34  				bufSize: 128,
    35  				err:     io.EOF,
    36  				data:    "Hello World!",
    37  				size:    12,
    38  			},
    39  			{
    40  				line:    2,
    41  				bufSize: 128,
    42  				err:     io.EOF,
    43  				data:    "",
    44  				size:    0,
    45  			},
    46  		},
    47  	},
    48  	{
    49  		data: `Line 1
    50  Line 2
    51  Line 3
    52  Line 4
    53  Line 5
    54  
    55  Line 7
    56  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    57  Line 9`,
    58  		tests: []lineCase{
    59  			{
    60  				line:    1,
    61  				bufSize: 128,
    62  				err:     io.EOF,
    63  				data:    "Line 1",
    64  				size:    6,
    65  			},
    66  			{
    67  				line:    2,
    68  				bufSize: 128,
    69  				err:     io.EOF,
    70  				data:    "Line 2",
    71  				size:    6,
    72  			},
    73  			// Skip some lines before the next one.
    74  			{
    75  				line:    5,
    76  				bufSize: 128,
    77  				err:     io.EOF,
    78  				data:    "Line 5",
    79  				size:    6,
    80  			},
    81  			// Exact size
    82  			{
    83  				line:    1,
    84  				bufSize: 6,
    85  				err:     nil,
    86  				data:    "Line 1",
    87  				size:    6,
    88  			},
    89  			// Less then entire line
    90  			{
    91  				line:    1,
    92  				bufSize: 4,
    93  				err:     nil,
    94  				data:    "Line",
    95  				size:    4,
    96  			},
    97  			// Empty line
    98  			{
    99  				line:    6,
   100  				bufSize: 128,
   101  				err:     io.EOF,
   102  				data:    "",
   103  				size:    0,
   104  			},
   105  			// After empty line
   106  			{
   107  				line:    7,
   108  				bufSize: 128,
   109  				err:     io.EOF,
   110  				data:    "Line 7",
   111  				size:    6,
   112  			},
   113  			// After long line
   114  			{
   115  				line:    9,
   116  				bufSize: 128,
   117  				err:     io.EOF,
   118  				data:    "Line 9",
   119  				size:    6,
   120  			},
   121  		},
   122  	},
   123  }
   124  
   125  func TestReadLine(t *testing.T) {
   126  	for _, c := range cases {
   127  		r := NewLineReader(bytes.NewReader([]byte(c.data)))
   128  
   129  		for _, l := range c.tests {
   130  			buf := make([]byte, l.bufSize)
   131  
   132  			n, err := r.ReadLine(buf, l.line)
   133  			if err != l.err {
   134  				t.Errorf("data: '%s', ReadLine(%d): err got %v want %v", c.data, l.line, err, l.err)
   135  			}
   136  
   137  			if n != l.size {
   138  				t.Errorf("data: '%s', ReadLine(%d): n got %d want %d", c.data, l.line, n, l.size)
   139  			}
   140  
   141  			s := string(buf[:n])
   142  
   143  			if s != l.data {
   144  				t.Errorf("data: '%s', ReadLine(%d): buf got '%s' want '%s'", c.data, l.line, s, l.data)
   145  			}
   146  		}
   147  	}
   148  
   149  }
   150  
   151  func TestLineExists(t *testing.T) {
   152  	input := `Line 1
   153  Line 2
   154  Line 3`
   155  
   156  	r := NewLineReader(bytes.NewReader([]byte(input)))
   157  
   158  	if !r.LineExists(1) {
   159  		t.Errorf("LineExists(1) = false want true")
   160  	}
   161  
   162  	if !r.LineExists(2) {
   163  		t.Errorf("LineExists(2) = false want true")
   164  	}
   165  
   166  	if !r.LineExists(3) {
   167  		t.Errorf("LineExists(3) = false want true")
   168  	}
   169  
   170  	if r.LineExists(4) {
   171  		t.Errorf("LineExists(4) = true want false")
   172  	}
   173  }
   174  
   175  // Newline at the end of a file shouldn't count as a line.
   176  func TestLineExistsNewline(t *testing.T) {
   177  	input := `Line 1
   178  `
   179  
   180  	r := NewLineReader(bytes.NewReader([]byte(input)))
   181  
   182  	if !r.LineExists(1) {
   183  		t.Errorf("LineExists(1) = false want true")
   184  	}
   185  
   186  	if r.LineExists(2) {
   187  		t.Errorf("LineExists(2) = true want false")
   188  	}
   189  }
   190  
   191  func TestSearchLine(t *testing.T) {
   192  	input := `Line 1
   193  aaa bbb ccc
   194  Last line`
   195  
   196  	searchCases := []struct {
   197  		line int64
   198  		reg  *regexp.Regexp
   199  		ret  [][]int
   200  		err  error
   201  	}{
   202  		{
   203  			line: 1,
   204  			reg:  regexp.MustCompile(`Line 1`),
   205  			ret:  [][]int{{0, 6}},
   206  			err:  nil,
   207  		},
   208  		{
   209  			line: 1,
   210  			reg:  regexp.MustCompile(`^Line 1$`),
   211  			ret:  [][]int{{0, 6}},
   212  			err:  nil,
   213  		},
   214  		{
   215  			line: 1,
   216  			reg:  regexp.MustCompile(`\d`),
   217  			ret:  [][]int{{5, 6}},
   218  			err:  nil,
   219  		},
   220  		{
   221  			line: 2,
   222  			reg:  regexp.MustCompile(`[a-z]+`),
   223  			ret:  [][]int{{0, 3}, {4, 7}, {8, 11}},
   224  			err:  nil,
   225  		},
   226  		{
   227  			line: 3,
   228  			reg:  regexp.MustCompile(`^Last line$`),
   229  			ret:  [][]int{{0, 9}},
   230  			err:  nil,
   231  		},
   232  	}
   233  
   234  	for _, c := range searchCases {
   235  		r := NewLineReader(bytes.NewReader([]byte(input)))
   236  
   237  		ret, err := r.SearchLine(c.reg, c.line)
   238  		if err != c.err {
   239  			t.Errorf("SearchLine(%v, %d): err got %v want %v", c.reg, c.line, err, c.err)
   240  		}
   241  
   242  		if !reflect.DeepEqual(ret, c.ret) {
   243  			t.Errorf("SearchLine(%v, %d) = %v want %v", c.reg, c.line, ret, c.ret)
   244  		}
   245  	}
   246  }