wip
parent
c75bd74823
commit
ce5bf71f6b
|
|
@ -1,6 +1,8 @@
|
||||||
package ledger
|
package ledger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
|
|
@ -20,6 +22,41 @@ func NewFiles(p string, q ...string) (Files, error) {
|
||||||
return f, err
|
return f, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (files Files) TempGetLastNLines(n int) ([]string, error) {
|
||||||
|
p := files.paths()[0]
|
||||||
|
f, err := os.Open(p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
return peekLastNLines(io.Discard, bufio.NewReader(f), n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (files Files) TempSetLastNLines(n int, lines []string) error {
|
||||||
|
panic("e")
|
||||||
|
}
|
||||||
|
|
||||||
|
func peekLastNLines(w io.Writer, r *bufio.Reader, n int) ([]string, error) {
|
||||||
|
lastNLines := make([]string, 0, n)
|
||||||
|
for {
|
||||||
|
line, err := r.ReadBytes('\n')
|
||||||
|
if len(line) > 0 {
|
||||||
|
lastNLines = append(lastNLines, string(bytes.TrimRight(line, "\n")))
|
||||||
|
for i := 0; i < len(lastNLines)-n; i++ {
|
||||||
|
fmt.Fprintln(w, lastNLines[i])
|
||||||
|
}
|
||||||
|
lastNLines = lastNLines[max(0, len(lastNLines)-n):]
|
||||||
|
}
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lastNLines, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (files Files) paths() []string {
|
func (files Files) paths() []string {
|
||||||
result := make([]string, 0, len(files))
|
result := make([]string, 0, len(files))
|
||||||
for i := range files {
|
for i := range files {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package ledger
|
package ledger
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
@ -290,3 +292,83 @@ func TestFilesOfDir(t *testing.T) {
|
||||||
t.Error(paths)
|
t.Error(paths)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestFilesTempGetLastNLines(t *testing.T) {
|
||||||
|
cases := map[string]struct {
|
||||||
|
input string
|
||||||
|
n int
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
"empty": {},
|
||||||
|
"get n lines from empty file": {
|
||||||
|
input: "",
|
||||||
|
n: 5,
|
||||||
|
want: []string{},
|
||||||
|
},
|
||||||
|
"get 0 lines from file": {
|
||||||
|
input: "#a\n#b",
|
||||||
|
n: 0,
|
||||||
|
want: []string{},
|
||||||
|
},
|
||||||
|
"get 3 lines from 2 line file": {
|
||||||
|
input: "#a\n#b",
|
||||||
|
n: 3,
|
||||||
|
want: []string{"#a", "#b"},
|
||||||
|
},
|
||||||
|
"get 2 lines from 3 line file": {
|
||||||
|
input: "#a\n#b\n#c",
|
||||||
|
n: 2,
|
||||||
|
want: []string{"#b", "#c"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, d := range cases {
|
||||||
|
c := d
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
p := path.Join(t.TempDir(), base64.URLEncoding.EncodeToString([]byte(t.Name())))
|
||||||
|
os.WriteFile(p, []byte(c.input), os.ModePerm)
|
||||||
|
files, err := NewFiles(p)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
if got, err := files.TempGetLastNLines(c.n); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
} else if fmt.Sprint(got) != fmt.Sprint(c.want) {
|
||||||
|
for i := range c.want {
|
||||||
|
t.Logf("want[%d] = %q", i, c.want[i])
|
||||||
|
}
|
||||||
|
for i := range got {
|
||||||
|
t.Logf(" got[%d] = %q", i, got[i])
|
||||||
|
}
|
||||||
|
t.Errorf("wanted\n\t%+v, got\n\t%+v", c.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFilesTempSetLastNLines(t *testing.T) {
|
||||||
|
cases := map[string]struct {
|
||||||
|
given string
|
||||||
|
input []string
|
||||||
|
n int
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
"empty": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for name, d := range cases {
|
||||||
|
c := d
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
p := path.Join(t.TempDir(), base64.URLEncoding.EncodeToString([]byte(t.Name())))
|
||||||
|
os.WriteFile(p, []byte(c.given), os.ModePerm)
|
||||||
|
files := Files([]string{p})
|
||||||
|
if err := files.TempSetLastNLines(c.n, c.input); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
got, _ := os.ReadFile(p)
|
||||||
|
if string(got) != c.want {
|
||||||
|
t.Errorf("want\n\t%s, got\n\t%s", c.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue