lordwelch f56ee42b79 Change signatures to constant strings
Fix issues from golangci-lint

Add sublime project file
2021-01-11 01:24:36 -08:00

159 lines
2.8 KiB
Go

package lz4block
import (
"bytes"
"strings"
"testing"
)
func TestBlockDecode(t *testing.T) {
appendLen := func(p []byte, size int) []byte {
for size > 0xFF {
p = append(p, 0xFF)
size -= 0xFF
}
p = append(p, byte(size))
return p
}
emitSeq := func(lit string, offset uint16, matchLen int) []byte {
var b byte
litLen := len(lit)
if litLen < 15 {
b = byte(litLen << 4)
litLen = -1
} else {
b = 0xF0
litLen -= 15
}
if matchLen < 4 || offset == 0 {
out := []byte{b}
if litLen >= 0 {
out = appendLen(out, litLen)
}
return append(out, lit...)
}
matchLen -= 4
if matchLen < 15 {
b |= byte(matchLen)
matchLen = -1
} else {
b |= 0x0F
matchLen -= 15
}
out := []byte{b}
if litLen >= 0 {
out = appendLen(out, litLen)
}
if len(lit) > 0 {
out = append(out, lit...)
}
out = append(out, byte(offset), byte(offset>>8))
if matchLen >= 0 {
out = appendLen(out, matchLen)
}
return out
}
concat := func(in ...[]byte) []byte {
var p []byte
for _, b := range in {
p = append(p, b...)
}
return p
}
tests := []struct {
name string
src []byte
exp []byte
}{
{
"empty_input",
[]byte{0},
[]byte{},
},
{
"literal_only_short",
emitSeq("hello", 0, 0),
[]byte("hello"),
},
{
"literal_only_long",
emitSeq(strings.Repeat("A", 15+255+255+1), 0, 0),
bytes.Repeat([]byte("A"), 15+255+255+1),
},
{
"literal_only_long_1",
emitSeq(strings.Repeat("A", 15), 0, 0),
bytes.Repeat([]byte("A"), 15),
},
{
"repeat_match_len",
emitSeq("a", 1, 4),
[]byte("aaaaa"),
},
{
"repeat_match_len_2_seq",
concat(emitSeq("a", 1, 4), emitSeq("B", 1, 4)),
[]byte("aaaaaBBBBB"),
},
{
"long_match",
emitSeq("A", 1, 16),
bytes.Repeat([]byte("A"), 17),
},
{
"repeat_match_log_len_2_seq",
concat(emitSeq("a", 1, 15), emitSeq("B", 1, 15), emitSeq("end", 0, 0)),
[]byte(strings.Repeat("a", 16) + strings.Repeat("B", 16) + "end"),
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
buf := make([]byte, len(test.exp))
n := decodeBlock(buf, test.src)
if n <= 0 {
t.Log(-n)
}
if !bytes.Equal(buf, test.exp) {
t.Fatalf("expected %q got %q", test.exp, buf)
}
})
}
}
func TestDecodeBlockInvalid(t *testing.T) {
t.Parallel()
dst := make([]byte, 100)
for _, test := range []struct {
name string
src string
}{
{
"empty_input",
"",
},
{
"final_lit_too_short",
"\x20a", // litlen = 2 but only a single-byte literal
},
} {
r := decodeBlock(dst, []byte(test.src))
if r >= 0 {
t.Errorf("no error for %s", test.name)
}
}
}