1// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package lzma 6 7import ( 8 "bytes" 9 "fmt" 10 "testing" 11) 12 13func TestChunkTypeString(t *testing.T) { 14 tests := [...]struct { 15 c chunkType 16 s string 17 }{ 18 {cEOS, "EOS"}, 19 {cUD, "UD"}, 20 {cU, "U"}, 21 {cL, "L"}, 22 {cLR, "LR"}, 23 {cLRN, "LRN"}, 24 {cLRND, "LRND"}, 25 } 26 for _, c := range tests { 27 s := fmt.Sprintf("%v", c.c) 28 if s != c.s { 29 t.Errorf("got %s; want %s", s, c.s) 30 } 31 } 32} 33 34func TestHeaderChunkType(t *testing.T) { 35 tests := []struct { 36 h byte 37 c chunkType 38 }{ 39 {h: 0, c: cEOS}, 40 {h: 1, c: cUD}, 41 {h: 2, c: cU}, 42 {h: 1<<7 | 0x1f, c: cL}, 43 {h: 1<<7 | 1<<5 | 0x1f, c: cLR}, 44 {h: 1<<7 | 1<<6 | 0x1f, c: cLRN}, 45 {h: 1<<7 | 1<<6 | 1<<5 | 0x1f, c: cLRND}, 46 {h: 1<<7 | 1<<6 | 1<<5, c: cLRND}, 47 } 48 if _, err := headerChunkType(3); err == nil { 49 t.Fatalf("headerChunkType(%d) got %v; want %v", 50 3, err, errHeaderByte) 51 } 52 for _, tc := range tests { 53 c, err := headerChunkType(tc.h) 54 if err != nil { 55 t.Fatalf("headerChunkType error %s", err) 56 } 57 if c != tc.c { 58 t.Errorf("got %s; want %s", c, tc.c) 59 } 60 } 61} 62 63func TestHeaderLen(t *testing.T) { 64 tests := []struct { 65 c chunkType 66 n int 67 }{ 68 {cEOS, 1}, {cU, 3}, {cUD, 3}, {cL, 5}, {cLR, 5}, {cLRN, 6}, 69 {cLRND, 6}, 70 } 71 for _, tc := range tests { 72 n := headerLen(tc.c) 73 if n != tc.n { 74 t.Errorf("header length for %s %d; want %d", 75 tc.c, n, tc.n) 76 } 77 } 78} 79 80func chunkHeaderSamples(t *testing.T) []chunkHeader { 81 props := Properties{LC: 3, LP: 0, PB: 2} 82 headers := make([]chunkHeader, 0, 12) 83 for c := cEOS; c <= cLRND; c++ { 84 var h chunkHeader 85 h.ctype = c 86 if c >= cUD { 87 h.uncompressed = 0x0304 88 } 89 if c >= cL { 90 h.compressed = 0x0201 91 } 92 if c >= cLRN { 93 h.props = props 94 } 95 headers = append(headers, h) 96 } 97 return headers 98} 99 100func TestChunkHeaderMarshalling(t *testing.T) { 101 for _, h := range chunkHeaderSamples(t) { 102 data, err := h.MarshalBinary() 103 if err != nil { 104 t.Fatalf("MarshalBinary for %v error %s", h, err) 105 } 106 var g chunkHeader 107 if err = g.UnmarshalBinary(data); err != nil { 108 t.Fatalf("UnmarshalBinary error %s", err) 109 } 110 if g != h { 111 t.Fatalf("got %v; want %v", g, h) 112 } 113 } 114} 115 116func TestReadChunkHeader(t *testing.T) { 117 for _, h := range chunkHeaderSamples(t) { 118 data, err := h.MarshalBinary() 119 if err != nil { 120 t.Fatalf("MarshalBinary for %v error %s", h, err) 121 } 122 r := bytes.NewReader(data) 123 g, err := readChunkHeader(r) 124 if err != nil { 125 t.Fatalf("readChunkHeader for %v error %s", h, err) 126 } 127 if *g != h { 128 t.Fatalf("got %v; want %v", g, h) 129 } 130 } 131} 132 133func TestReadEOS(t *testing.T) { 134 var b [1]byte 135 r := bytes.NewReader(b[:]) 136 h, err := readChunkHeader(r) 137 if err != nil { 138 t.Fatalf("readChunkHeader error %s", err) 139 } 140 if h.ctype != cEOS { 141 t.Errorf("ctype got %s; want %s", h.ctype, cEOS) 142 } 143 if h.compressed != 0 { 144 t.Errorf("compressed got %d; want %d", h.compressed, 0) 145 } 146 if h.uncompressed != 0 { 147 t.Errorf("uncompressed got %d; want %d", h.uncompressed, 0) 148 } 149 wantProps := Properties{} 150 if h.props != wantProps { 151 t.Errorf("props got %v; want %v", h.props, wantProps) 152 } 153} 154