zombiezen.com/go/lua@v0.0.0-20231013005828-290725fb9140/internal/bufseek/bufseek_test.go (about)

     1  // Copyright 2023 Ross Light
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy of
     4  // this software and associated documentation files (the “Software”), to deal in
     5  // the Software without restriction, including without limitation the rights to
     6  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
     7  // the Software, and to permit persons to whom the Software is furnished to do so,
     8  // subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in all
    11  // copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
    15  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
    16  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
    17  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    18  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    19  //
    20  // SPDX-License-Identifier: MIT
    21  
    22  package bufseek
    23  
    24  import (
    25  	"bytes"
    26  	"io"
    27  	"os"
    28  	"path/filepath"
    29  	"testing"
    30  	"testing/iotest"
    31  )
    32  
    33  var _ interface {
    34  	io.Reader
    35  	io.ByteReader
    36  	io.Seeker
    37  } = (*Reader)(nil)
    38  
    39  var _ interface {
    40  	io.Reader
    41  	io.Writer
    42  	io.ByteReader
    43  	io.Seeker
    44  } = (*ReadWriter)(nil)
    45  
    46  func TestRead(t *testing.T) {
    47  	want := bytes.Repeat([]byte{
    48  		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    49  		0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00,
    50  	}, 4096/16)
    51  	rd := NewReaderSize(bytes.NewReader(want), 20)
    52  	if err := iotest.TestReader(rd, want); err != nil {
    53  		t.Error(err)
    54  	}
    55  }
    56  
    57  func TestReadByte(t *testing.T) {
    58  	want := bytes.Repeat([]byte{
    59  		0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
    60  		0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe, 0x00, 0x00,
    61  	}, 4096/16)
    62  	rd := NewReaderSize(bytes.NewReader(want), 20)
    63  
    64  	for i, want := range want {
    65  		c, err := rd.ReadByte()
    66  		if err != nil {
    67  			t.Fatal(err)
    68  		}
    69  		if c != want {
    70  			t.Errorf("at offset %d, ReadByte() = %#02x, <nil>; want %#02x, <nil>", i, c, want)
    71  		}
    72  	}
    73  }
    74  
    75  func TestReadWriter(t *testing.T) {
    76  	dir := t.TempDir()
    77  	f, err := os.Create(filepath.Join(dir, "foo.txt"))
    78  	if err != nil {
    79  		t.Fatal(err)
    80  	}
    81  	defer f.Close()
    82  	b := NewReadWriter(f)
    83  
    84  	const line1 = "Hello, World!\n"
    85  	const line2 = "second line\n"
    86  	if n, err := io.WriteString(b, line1+line2); n != len(line1+line2) || err != nil {
    87  		t.Errorf("io.WriteString(b, %q) = %d, %v; want %d, <nil>",
    88  			line1+line2, n, err, len(line1+line2))
    89  	}
    90  	if pos, err := b.Seek(0, io.SeekStart); pos != 0 || err != nil {
    91  		t.Errorf("b.Seek(0, io.SeekStart) = %d, %v; want 0, <nil>", pos, err)
    92  	}
    93  	buf := make([]byte, 2)
    94  	if n, err := io.ReadFull(b, buf); n != len(buf) || err != nil {
    95  		t.Errorf("io.ReadFull(...) = %d, %v; want %d, <nil>", n, err, len(buf))
    96  	}
    97  	if want := line1[:len(buf)]; string(buf) != want {
    98  		t.Errorf("after io.ReadFull, buf = %q; want %q", buf, want)
    99  	}
   100  	offset := int64(len(line1) - len(buf))
   101  	pos, err := b.Seek(offset, io.SeekCurrent)
   102  	if pos != int64(len(line1)) || err != nil {
   103  		t.Errorf("b.Seek(%d, io.SeekStart) = %d, %v; want %d, <nil>",
   104  			offset, pos, err, len(line1))
   105  	}
   106  	const newLine2 = "this is a really long line that replaces the old one\n"
   107  	if n, err := io.WriteString(b, newLine2); n != len(newLine2) || err != nil {
   108  		t.Errorf("io.WriteString(b, %q) = %d, %v; want %d, <nil>",
   109  			newLine2, n, err, len(newLine2))
   110  	}
   111  
   112  	if _, err := f.Seek(0, io.SeekStart); err != nil {
   113  		t.Fatal(err)
   114  	}
   115  	got, err := io.ReadAll(f)
   116  	if want := line1 + newLine2; string(got) != want || err != nil {
   117  		t.Errorf("final contents = %q, %v; want %q, <nil>", got, err, want)
   118  	}
   119  }