package predictor
import (
diff "0dev.org/diff"
"bytes"
"fmt"
"io/ioutil"
"testing"
)
// Sample input from RFC1978 - PPP Predictor Compression Protocol
var input = []byte{0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0a,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0a,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0a,
0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0a,
0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x41, 0x0a,
0x42, 0x41, 0x42, 0x41, 0x42, 0x41, 0x42, 0x0a,
0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x0a}
// Sample output from RFC1978 - PPP Predictor Compression Protocol
var output = []byte{0x60, 0x41, 0x41, 0x41, 0x41, 0x41, 0x0a, 0x60,
0x41, 0x41, 0x41, 0x41, 0x41, 0x0a, 0x6f, 0x41,
0x0a, 0x6f, 0x41, 0x0a, 0x41, 0x42, 0x41, 0x42,
0x41, 0x42, 0x0a, 0x60, 0x42, 0x41, 0x42, 0x41,
0x42, 0x0a, 0x60, 0x78, 0x78, 0x78, 0x78, 0x78, 0x0a}
func TestCompressorSample(t *testing.T) {
var (
buf bytes.Buffer
err error
)
out := Compressor(&buf)
err = out(input)
if err != nil {
t.Error(err)
}
err = out(nil)
if err != nil {
t.Error(err)
}
result := buf.Bytes()
delta := diff.Diff(diff.D{len(result), len(output), func(i, j int) bool { return result[i] == output[j] }})
if len(delta.Added) > 0 || len(delta.Removed) > 0 {
t.Error("Unexpected compressed output", delta)
}
}
func TestDecompressorSample(t *testing.T) {
in := Decompressor(bytes.NewReader(output))
result, err := ioutil.ReadAll(in)
if err != nil {
t.Error("Unexpected error while decompressing", err)
}
delta := diff.Diff(diff.D{len(result), len(input),
func(i, j int) bool { return result[i] == input[j] }})
if len(delta.Added) > 0 || len(delta.Removed) > 0 {
t.Error("Unexpected decompressed output", delta)
}
}
func TestEmptyCycle(t *testing.T) {
var input []byte = []byte{}
if err := cycle(input); err != nil {
t.Error(err)
}
}
func TestPartialCycle(t *testing.T) {
var input []byte = []byte{0, 1, 2, 3}
if err := cycle(input); err != nil {
t.Error(err)
}
}
func TestBlockCycle(t *testing.T) {
var input []byte = []byte{0, 1, 2, 3, 4, 5, 6, 7}
if err := cycle(input); err != nil {
t.Error(err)
}
}
func TestBlockPartialCycle(t *testing.T) {
var input []byte = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}
if err := cycle(input); err != nil {
t.Error(err)
}
}
func TestDualBlockCycle(t *testing.T) {
var input []byte = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
if err := cycle(input); err != nil {
t.Error(err)
}
}
func cycle(input []byte) error {
var (
buf bytes.Buffer
err error
)
// Create a compressor and write the given data
compressor := Compressor(&buf)
err = compressor(input)
if err != nil {
return err
}
// Flush the compressor
err = compressor(nil)
if err != nil {
return err
}
// Attempt to decompress the data
compressed := buf.Bytes()
decompressed, err := ioutil.ReadAll(Decompressor(bytes.NewReader(compressed)))
if err != nil {
return err
}
// Diff the result against the initial input
delta := diff.Diff(diff.D{len(input), len(decompressed),
func(i, j int) bool { return input[i] == decompressed[j] }})
// Return a well-formated error if any differences are found
if len(delta.Added) > 0 || len(delta.Removed) > 0 {
return fmt.Errorf("Unexpected decompressed output %v\ninput: %#x\noutput: %#x\n",
delta, input, decompressed)
}
// All is good :)
return nil
}