2015-12-10 17:19:38 -05:00
|
|
|
// Copyright 2015 The Hugo Authors. All rights reserved.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2015-08-15 11:06:39 -04:00
|
|
|
package source
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"testing"
|
2016-07-30 09:14:41 -04:00
|
|
|
|
|
|
|
"github.com/spf13/afero"
|
2015-08-15 11:06:39 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestNewLazyFileReader(t *testing.T) {
|
2016-07-30 09:14:41 -04:00
|
|
|
fs := afero.NewOsFs()
|
2015-08-15 11:06:39 -04:00
|
|
|
filename := "itdoesnotexistfile"
|
2016-07-30 09:14:41 -04:00
|
|
|
_, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err == nil {
|
|
|
|
t.Errorf("NewLazyFileReader %s: error expected but no error is returned", filename)
|
|
|
|
}
|
|
|
|
|
|
|
|
filename = "lazy_file_reader_test.go"
|
2016-07-30 09:14:41 -04:00
|
|
|
_, err = NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("NewLazyFileReader %s: %v", filename, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestFilename(t *testing.T) {
|
2016-07-30 09:14:41 -04:00
|
|
|
fs := afero.NewOsFs()
|
2015-08-15 11:06:39 -04:00
|
|
|
filename := "lazy_file_reader_test.go"
|
2016-07-30 09:14:41 -04:00
|
|
|
rd, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("NewLazyFileReader %s: %v", filename, err)
|
|
|
|
}
|
|
|
|
if rd.Filename() != filename {
|
|
|
|
t.Errorf("Filename: expected filename %q, got %q", filename, rd.Filename())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRead(t *testing.T) {
|
2016-07-30 09:14:41 -04:00
|
|
|
fs := afero.NewOsFs()
|
2015-08-15 11:06:39 -04:00
|
|
|
filename := "lazy_file_reader_test.go"
|
2016-07-30 09:14:41 -04:00
|
|
|
fi, err := fs.Stat(filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("os.Stat: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-07-30 09:14:41 -04:00
|
|
|
b, err := afero.ReadFile(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("ioutil.ReadFile: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-07-30 09:14:41 -04:00
|
|
|
rd, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("NewLazyFileReader %s: %v", filename, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tst := func(testcase string) {
|
|
|
|
p := make([]byte, fi.Size())
|
|
|
|
n, err := rd.Read(p)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Read %s case: %v", testcase, err)
|
|
|
|
}
|
|
|
|
if int64(n) != fi.Size() {
|
|
|
|
t.Errorf("Read %s case: read bytes length expected %d, got %d", testcase, fi.Size(), n)
|
|
|
|
}
|
|
|
|
if !bytes.Equal(b, p) {
|
|
|
|
t.Errorf("Read %s case: read bytes are different from expected", testcase)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tst("No cache")
|
|
|
|
_, err = rd.Seek(0, 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Seek: %v", err)
|
|
|
|
}
|
|
|
|
tst("Cache")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSeek(t *testing.T) {
|
|
|
|
type testcase struct {
|
|
|
|
seek int
|
|
|
|
offset int64
|
|
|
|
length int
|
|
|
|
moveto int64
|
|
|
|
expected []byte
|
|
|
|
}
|
2016-07-30 09:14:41 -04:00
|
|
|
fs := afero.NewOsFs()
|
2015-08-15 11:06:39 -04:00
|
|
|
filename := "lazy_file_reader_test.go"
|
2016-07-30 09:14:41 -04:00
|
|
|
b, err := afero.ReadFile(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("ioutil.ReadFile: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// no cache case
|
|
|
|
for i, this := range []testcase{
|
|
|
|
{seek: os.SEEK_SET, offset: 0, length: 10, moveto: 0, expected: b[:10]},
|
|
|
|
{seek: os.SEEK_SET, offset: 5, length: 10, moveto: 5, expected: b[5:15]},
|
|
|
|
{seek: os.SEEK_CUR, offset: 5, length: 10, moveto: 5, expected: b[5:15]}, // current pos = 0
|
|
|
|
{seek: os.SEEK_END, offset: -1, length: 1, moveto: int64(len(b) - 1), expected: b[len(b)-1:]},
|
|
|
|
{seek: 3, expected: nil},
|
|
|
|
{seek: os.SEEK_SET, offset: -1, expected: nil},
|
|
|
|
} {
|
2016-07-30 09:14:41 -04:00
|
|
|
rd, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Errorf("[%d] NewLazyFileReader %s: %v", i, filename, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
pos, err := rd.Seek(this.offset, this.seek)
|
|
|
|
if this.expected == nil {
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("[%d] Seek didn't return an expected error", i)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("[%d] Seek failed unexpectedly: %v", i, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if pos != this.moveto {
|
|
|
|
t.Errorf("[%d] Seek failed to move the pointer: got %d, expected: %d", i, pos, this.moveto)
|
|
|
|
}
|
|
|
|
|
|
|
|
buf := make([]byte, this.length)
|
|
|
|
n, err := rd.Read(buf)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("[%d] Read failed unexpectedly: %v", i, err)
|
|
|
|
}
|
|
|
|
if !bytes.Equal(this.expected, buf[:n]) {
|
|
|
|
t.Errorf("[%d] Seek and Read got %q but expected %q", i, buf[:n], this.expected)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// cache case
|
2016-07-30 09:14:41 -04:00
|
|
|
rd, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("NewLazyFileReader %s: %v", filename, err)
|
|
|
|
}
|
|
|
|
dummy := make([]byte, len(b))
|
|
|
|
_, err = rd.Read(dummy)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Read failed unexpectedly: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, this := range []testcase{
|
|
|
|
{seek: os.SEEK_SET, offset: 0, length: 10, moveto: 0, expected: b[:10]},
|
|
|
|
{seek: os.SEEK_SET, offset: 5, length: 10, moveto: 5, expected: b[5:15]},
|
|
|
|
{seek: os.SEEK_CUR, offset: 1, length: 10, moveto: 16, expected: b[16:26]}, // current pos = 15
|
|
|
|
{seek: os.SEEK_END, offset: -1, length: 1, moveto: int64(len(b) - 1), expected: b[len(b)-1:]},
|
|
|
|
{seek: 3, expected: nil},
|
|
|
|
{seek: os.SEEK_SET, offset: -1, expected: nil},
|
|
|
|
} {
|
|
|
|
pos, err := rd.Seek(this.offset, this.seek)
|
|
|
|
if this.expected == nil {
|
|
|
|
if err == nil {
|
|
|
|
t.Errorf("[%d] Seek didn't return an expected error", i)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("[%d] Seek failed unexpectedly: %v", i, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if pos != this.moveto {
|
|
|
|
t.Errorf("[%d] Seek failed to move the pointer: got %d, expected: %d", i, pos, this.moveto)
|
|
|
|
}
|
|
|
|
|
|
|
|
buf := make([]byte, this.length)
|
|
|
|
n, err := rd.Read(buf)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("[%d] Read failed unexpectedly: %v", i, err)
|
|
|
|
}
|
|
|
|
if !bytes.Equal(this.expected, buf[:n]) {
|
|
|
|
t.Errorf("[%d] Seek and Read got %q but expected %q", i, buf[:n], this.expected)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestWriteTo(t *testing.T) {
|
2016-07-30 09:14:41 -04:00
|
|
|
fs := afero.NewOsFs()
|
2015-08-15 11:06:39 -04:00
|
|
|
filename := "lazy_file_reader_test.go"
|
|
|
|
fi, err := os.Stat(filename)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("os.Stat: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
b, err := ioutil.ReadFile(filename)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("ioutil.ReadFile: %v", err)
|
|
|
|
}
|
|
|
|
|
2016-07-30 09:14:41 -04:00
|
|
|
rd, err := NewLazyFileReader(fs, filename)
|
2015-08-15 11:06:39 -04:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("NewLazyFileReader %s: %v", filename, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tst := func(testcase string, expectedSize int64, checkEqual bool) {
|
|
|
|
buf := bytes.NewBuffer(make([]byte, 0, bytes.MinRead))
|
|
|
|
n, err := rd.WriteTo(buf)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("WriteTo %s case: %v", testcase, err)
|
|
|
|
}
|
|
|
|
if n != expectedSize {
|
|
|
|
t.Errorf("WriteTo %s case: written bytes length expected %d, got %d", testcase, expectedSize, n)
|
|
|
|
}
|
|
|
|
if checkEqual && !bytes.Equal(b, buf.Bytes()) {
|
|
|
|
t.Errorf("WriteTo %s case: written bytes are different from expected", testcase)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
tst("No cache", fi.Size(), true)
|
|
|
|
tst("No cache 2nd", 0, false)
|
|
|
|
|
|
|
|
p := make([]byte, fi.Size())
|
|
|
|
_, err = rd.Read(p)
|
|
|
|
if err != nil && err != io.EOF {
|
|
|
|
t.Fatalf("Read: %v", err)
|
|
|
|
}
|
|
|
|
_, err = rd.Seek(0, 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Seek: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tst("Cache", fi.Size(), true)
|
|
|
|
}
|