package little import ( "bytes" "fmt" "math" "math/rand" "testing" ) func TestContants(t *testing.T) { fmt.Println(MinInt24 == -8388608) fmt.Println(MaxInt24 == 8388607) fmt.Println(MinInt48 == -140737488355328) fmt.Println(MaxInt48 == 140737488355327) fmt.Println(MaxUint24 == 16777215) fmt.Println(MaxUint48 == 281474976710655) } // PUT/GET INT func TestPutGetInt16(t *testing.T) { nums := []int16{ math.MinInt16, 0, math.MaxInt16, } for _, num := range nums { a := make([]byte, 2) PutInt16(a, num) decoded, err := GetInt16(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetInt24(t *testing.T) { nums := []int32{ MinInt24, 0, MaxInt24, } for _, num := range nums { a := make([]byte, 3) PutInt24(a, num) decoded, err := GetInt24(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetInt32(t *testing.T) { nums := []int32{ math.MinInt32, 0, math.MaxInt32, } for _, num := range nums { a := make([]byte, 4) PutInt32(a, num) decoded, err := GetInt32(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetInt48(t *testing.T) { nums := []int64{ MinInt48, 0, MaxInt48, } for _, num := range nums { a := make([]byte, 6) PutInt48(a, num) decoded, err := GetInt48(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetInt64(t *testing.T) { nums := []int64{ math.MinInt64, 0, math.MaxInt64, } for _, num := range nums { a := make([]byte, 8) PutInt64(a, num) decoded, err := GetInt64(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } // PUT/GET UINT func TestPutGetUint16(t *testing.T) { nums := []uint16{ 0, math.MaxUint16, } for _, num := range nums { a := make([]byte, 2) PutUint16(a, num) decoded, err := GetUint16(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetUint24(t *testing.T) { nums := []uint32{ 0, MaxUint24, } for _, num := range nums { a := make([]byte, 3) PutUint24(a, num) decoded, err := GetUint24(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetUint32(t *testing.T) { nums := []uint32{ 0, math.MaxUint32, } for _, num := range nums { a := make([]byte, 4) PutUint32(a, num) decoded, err := GetUint32(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetUint48(t *testing.T) { nums := []uint64{ 0, MaxUint48, } for _, num := range nums { a := make([]byte, 6) PutUint48(a, num) decoded, err := GetUint48(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestPutGetUint64(t *testing.T) { nums := []uint64{ 0, math.MaxUint64, } for _, num := range nums { a := make([]byte, 8) PutUint64(a, num) decoded, err := GetUint64(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } // PUT/GET FLOAT func TestPutGetFloat32(t *testing.T) { nums := []float32{ -math.SmallestNonzeroFloat32, math.SmallestNonzeroFloat32, -1, 0, 1, -math.MaxFloat32, math.MaxFloat32, } for _, num := range nums { a := make([]byte, 4) PutFloat32(a, num) decoded, err := GetFloat32(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %v not equal decoded %v", num, decoded) } } } func TestPutGetFloat64(t *testing.T) { nums := []float64{ -math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64, -1, 0, 1, -math.MaxFloat64, math.MaxFloat64, } for _, num := range nums { a := make([]byte, 8) PutFloat64(a, num) decoded, err := GetFloat64(a) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %v not equal decoded %v", num, decoded) } } } // PUT/GET STRING func TestPutGetString8(t *testing.T) { pSize := 1 // размер префикса, в котором закодирована длина строки items := []string{ "", RandString(60), RandString(150), RandString(math.MaxUint8), } for _, origin := range items { a := make([]byte, pSize+len(origin)) err := PutString8(a, origin) if err != nil { t.Fatal(err) } decoded, err := GetString8(a) if err != nil { t.Fatal(err) } if decoded != origin { t.Fatalf("origin %q not equal decoded %q", origin, decoded) } } // запись слишком большой строки tooLongStr := RandString(math.MaxUint8 + 1) a := make([]byte, pSize+len(tooLongStr)) err := PutString8(a, tooLongStr) if err != ErrTooLong { t.Fatal("too long string put did not return ErrTooLong") } // запись, когда в массиве недостаточно места someStr := RandString(10) a = make([]byte, 10) err = PutString8(a, someStr) if err != ErrNoSpace { t.Fatal("put string longer then slice did not return ErrNoSpace") } } func TestPutGetString16(t *testing.T) { pSize := 2 // размер префикса, в котором закодирована длина строки items := []string{ "", RandString(255), RandString(256), RandString(math.MaxUint16), } for _, origin := range items { a := make([]byte, pSize+len(origin)) err := PutString16(a, origin) if err != nil { t.Fatal(err) } decoded, err := GetString16(a) if err != nil { t.Fatal(err) } if decoded != origin { t.Fatalf("origin %q not equal decoded %q", origin, decoded) } } // запись слишком большой строки tooLongStr := RandString(math.MaxUint16 + 1) a := make([]byte, pSize+len(tooLongStr)) err := PutString16(a, tooLongStr) if err != ErrTooLong { t.Fatal("too long string put did not return ErrTooLong") } // запись, когда в массиве недостаточно места someStr := RandString(10) a = make([]byte, 11) err = PutString16(a, someStr) if err != ErrNoSpace { t.Fatal("put string longer then slice did not return ErrNoSpace") } } // PUT/GET BOOL func TestPutGetBool(t *testing.T) { flags := []bool{ true, false, } for _, flag := range flags { a := make([]byte, 1) PutBool(a, flag) decoded, err := GetBool(a) if err != nil { t.Fatal(err) } if decoded != flag { t.Fatalf("flag %t not equal decoded %t", flag, decoded) } } } // WRITE/READ INT func TestWriteReadInt16(t *testing.T) { nums := []int16{ math.MinInt16, 0, math.MaxInt16, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteInt16(w, num) if err != nil { return } decoded, err := ReadInt16(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadInt24(t *testing.T) { nums := []int32{ MinInt24, 0, MaxInt24, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteInt24(w, num) if err != nil { return } decoded, err := ReadInt24(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadInt32(t *testing.T) { nums := []int32{ math.MinInt32, 0, math.MaxInt32, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteInt32(w, num) if err != nil { return } decoded, err := ReadInt32(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadInt48(t *testing.T) { nums := []int64{ MinInt48, 0, MaxInt48, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteInt48(w, num) if err != nil { return } decoded, err := ReadInt48(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadInt64(t *testing.T) { nums := []int64{ math.MinInt64, 0, math.MaxInt64, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteInt64(w, num) if err != nil { return } decoded, err := ReadInt64(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } // WRITE/READ UINT func TestWriteReadUint16(t *testing.T) { nums := []uint16{ 0, math.MaxUint16, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteUint16(w, num) if err != nil { return } decoded, err := ReadUint16(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadUint24(t *testing.T) { nums := []uint32{ 0, MaxUint24, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteUint24(w, num) if err != nil { return } decoded, err := ReadUint24(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadUint32(t *testing.T) { nums := []uint32{ 0, math.MaxUint32, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteUint32(w, num) if err != nil { return } decoded, err := ReadUint32(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadUint48(t *testing.T) { nums := []uint64{ 0, MaxUint48, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteUint48(w, num) if err != nil { return } decoded, err := ReadUint48(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } func TestWriteReadUint64(t *testing.T) { nums := []uint64{ 0, math.MaxUint64, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteUint64(w, num) if err != nil { return } decoded, err := ReadUint64(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %d not equal decoded %d", num, decoded) } } } // WRITE/READ FLOAT func TestWriteReadFloat32(t *testing.T) { nums := []float32{ -math.SmallestNonzeroFloat32, math.SmallestNonzeroFloat32, -1, 0, 1, -math.MaxFloat32, math.MaxFloat32, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteFloat32(w, num) if err != nil { return } decoded, err := ReadFloat32(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %v not equal decoded %v", num, decoded) } } } func TestWriteReadFloat64(t *testing.T) { nums := []float64{ -math.SmallestNonzeroFloat64, math.SmallestNonzeroFloat64, -1, 0, 1, -math.MaxFloat64, math.MaxFloat64, } for _, num := range nums { w := bytes.NewBuffer(nil) err := WriteFloat64(w, num) if err != nil { return } decoded, err := ReadFloat64(w) if err != nil { t.Fatal(err) } if decoded != num { t.Fatalf("num %v not equal decoded %v", num, decoded) } } } // WRITE/READ STRING func TestWriteReadString8(t *testing.T) { items := []string{ "", RandString(60), RandString(150), RandString(255), } for _, origin := range items { w := bytes.NewBuffer(nil) err := WriteString8(w, origin) if err != nil { return } decoded, err := ReadString8(w) if err != nil { t.Fatal(err) } if decoded != origin { t.Fatalf("origin %q not equal decoded %q", origin, decoded) } } // запись слишком большой строки w := bytes.NewBuffer(nil) err := WriteString8(w, RandString(256)) if err != ErrTooLong { t.Fatal("too long string write did not return ErrTooLong") } } func TestWriteReadString16(t *testing.T) { items := []string{ "", RandString(255), RandString(256), RandString(math.MaxUint16), } for _, origin := range items { w := bytes.NewBuffer(nil) err := WriteString16(w, origin) if err != nil { return } decoded, err := ReadString16(w) if err != nil { t.Fatal(err) } if decoded != origin { t.Fatalf("origin %q not equal decoded %q", origin, decoded) } } // запись слишком большой строки w := bytes.NewBuffer(nil) err := WriteString8(w, RandString(math.MaxUint16+1)) if err != ErrTooLong { t.Fatal("too long string write did not return ErrTooLong") } } // WRITE/READ BOOL func TestWriteReadBool(t *testing.T) { flags := []bool{ true, false, } for _, flag := range flags { w := bytes.NewBuffer(nil) err := WriteBool(w, flag) if err != nil { return } decoded, err := ReadBool(w) if err != nil { t.Fatal(err) } if decoded != flag { t.Fatalf("flag %t not equal decoded %t", flag, decoded) } } } // VAR SIZE COUNT func TestCountVarUint32(t *testing.T) { var testCases = []struct { Num uint32 Count int }{ {Num: (1 << 7) - 1, Count: 1}, {Num: (1 << 7), Count: 2}, {Num: (1 << 14) - 1, Count: 2}, {Num: (1 << 14), Count: 3}, {Num: (1 << 21) - 1, Count: 3}, {Num: (1 << 21), Count: 4}, {Num: (1 << 28) - 1, Count: 4}, {Num: (1 << 28), Count: 5}, {Num: (1 << 32) - 1, Count: 5}, } for _, testCase := range testCases { count := CountVarUint32(testCase.Num) if count != testCase.Count { t.Fatalf("calculated count %d is not equal %d for num %d\n", count, testCase.Count, testCase.Num) } } } func TestCountVarUint64(t *testing.T) { var testCases = []struct { Num uint64 Count int }{ {Num: (1 << 7) - 1, Count: 1}, {Num: (1 << 7), Count: 2}, {Num: (1 << 14) - 1, Count: 2}, {Num: (1 << 14), Count: 3}, {Num: (1 << 21) - 1, Count: 3}, {Num: (1 << 21), Count: 4}, {Num: (1 << 28) - 1, Count: 4}, {Num: (1 << 28), Count: 5}, {Num: (1 << 35) - 1, Count: 5}, {Num: (1 << 35), Count: 6}, {Num: (1 << 42) - 1, Count: 6}, {Num: (1 << 42), Count: 7}, {Num: (1 << 49) - 1, Count: 7}, {Num: (1 << 49), Count: 8}, {Num: (1 << 56) - 1, Count: 8}, {Num: (1 << 56), Count: 9}, {Num: (1 << 64) - 1, Count: 9}, } for _, testCase := range testCases { count := CountVarUint64(testCase.Num) if count != testCase.Count { t.Fatalf("calculated count %d is not equal %d for num %d\n", count, testCase.Count, testCase.Num) } } } func TestCountVarSize(t *testing.T) { var testCases = []struct { Num int Count int }{ {Num: (1 << 7) - 1, Count: 1}, {Num: (1 << 7), Count: 2}, {Num: (1 << 14) - 1, Count: 2}, {Num: (1 << 14), Count: 3}, {Num: (1 << 21) - 1, Count: 3}, {Num: (1 << 21), Count: 4}, {Num: (1 << 28) - 1, Count: 4}, {Num: (1 << 28), Count: 5}, {Num: (1 << 35) - 1, Count: 5}, {Num: (1 << 35), Count: 6}, {Num: (1 << 42) - 1, Count: 6}, {Num: (1 << 42), Count: 7}, {Num: (1 << 49) - 1, Count: 7}, {Num: (1 << 49), Count: 8}, {Num: (1 << 56) - 1, Count: 8}, {Num: (1 << 56), Count: 9}, {Num: (1 << 63) - 1, Count: 9}, } for _, testCase := range testCases { count := CountVarSize(testCase.Num) if count != testCase.Count { t.Fatalf("calculated count %d is not equal %d for num %d\n", count, testCase.Count, testCase.Num) } } } // HELPERS const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" func RandString(n int) string { b := make([]byte, n) for i := range b { b[i] = letters[rand.Intn(len(letters))] } return string(b) }