360 lines
7.2 KiB
Go
360 lines
7.2 KiB
Go
package bin
|
||
|
||
import (
|
||
"bytes"
|
||
"fmt"
|
||
"testing"
|
||
)
|
||
|
||
func TestSplitFloat(t *testing.T) {
|
||
f := 650179.6985999999 // округляет вниз .6985
|
||
total := 8.2291999999 // округляет вверх 8.2292
|
||
|
||
n := SplitFloat(f, 4)
|
||
x := SplitFloat(total, 4)
|
||
|
||
fmt.Printf("int: %d, frac: %d\n", n.Int, n.Frac)
|
||
fmt.Printf("total int: %d, frac: %d\n", x.Int, x.Frac)
|
||
}
|
||
|
||
func TestSplitFloat2(t *testing.T) {
|
||
//prev := 65032252.8724999875 // округляет вниз .6985
|
||
//total := 9.2449999973 // округляет вверх 8.2292
|
||
|
||
fracDigits := 4
|
||
|
||
floatPrev := 65000005.499980002
|
||
|
||
floatTotal := 3.5000800019
|
||
|
||
prev := SplitFloat(floatPrev, fracDigits)
|
||
total := SplitFloat(floatTotal, fracDigits)
|
||
|
||
fmt.Printf("prev: i=%d, f=%d\n", prev.Int, prev.Frac)
|
||
fmt.Printf("total i=%d, f=%d\n", total.Int, total.Frac)
|
||
|
||
value := SplitFloat(floatPrev+floatTotal, fracDigits)
|
||
|
||
fmt.Printf("real i=%d, f=%d\n", value.Int, value.Frac)
|
||
|
||
calcInt := prev.Int + total.Int
|
||
calcFrac := prev.Frac + total.Frac
|
||
|
||
if calcFrac >= 10000 {
|
||
calcFrac -= 10000
|
||
calcInt += 1
|
||
}
|
||
|
||
fmt.Printf("calc i=%d, f=%d\n", calcInt, calcFrac)
|
||
|
||
fmt.Printf("\n%.9f\n", 10000000.999999999)
|
||
|
||
}
|
||
|
||
func TestSplitFloat3(t *testing.T) {
|
||
f := 2806262383595.7373 // округляет вниз .6985
|
||
|
||
n := SplitFloat(f, 4)
|
||
|
||
fmt.Printf("int: %d, frac: %d\n", n.Int, n.Frac)
|
||
}
|
||
|
||
func TestBitOps(t *testing.T) {
|
||
var b byte = 255
|
||
|
||
var bitNo byte = 7
|
||
|
||
fmt.Printf("%08b\n", UnsetBit(b, bitNo))
|
||
fmt.Printf("%08b\n", SetBit(UnsetBit(b, bitNo), bitNo))
|
||
}
|
||
|
||
// Тесты массивов (для написания СУБД). Когда в байтовом виде записан массив из N элементов,
|
||
// фиксированного размера (например 4-байтовый uint32 или 2-байтовый uint16). Из массива
|
||
// нужно удалять элементы по индексу, либо в массив вставлять по индексу (чтобы другие
|
||
// элементы "подвинулись").
|
||
|
||
type _DeleteArrElemTestCase struct {
|
||
Arr []byte
|
||
Qty int
|
||
ElemSize int
|
||
Idx int
|
||
Result []byte
|
||
}
|
||
|
||
type _InsertArrElemTestCase struct {
|
||
Arr []byte
|
||
Qty int
|
||
Elem []byte
|
||
Idx int
|
||
Result []byte
|
||
}
|
||
|
||
func TestDeleteArrElem(t *testing.T) {
|
||
originArr := []byte{1, 1, 2, 2, 3, 3, 255, 0, 0, 0}
|
||
|
||
testCases := []_DeleteArrElemTestCase{
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 0,
|
||
Result: []byte{2, 2, 3, 3, 0, 0, 255, 0, 0, 0},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 1,
|
||
Result: []byte{1, 1, 3, 3, 0, 0, 255, 0, 0, 0},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 2,
|
||
Result: []byte{1, 1, 2, 2, 0, 0, 255, 0, 0, 0},
|
||
},
|
||
}
|
||
|
||
for _, testCase := range testCases {
|
||
arrcopy := make([]byte, len(testCase.Arr))
|
||
|
||
copy(arrcopy, testCase.Arr)
|
||
|
||
DeleteArrElem(arrcopy, testCase.Qty, testCase.ElemSize, testCase.Idx)
|
||
|
||
if !bytes.Equal(arrcopy, testCase.Result) {
|
||
t.Fatalf(`
|
||
Source: %v
|
||
Estimate: %v
|
||
Real: %v`,
|
||
testCase.Arr, testCase.Result, arrcopy)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestInsertArrElem(t *testing.T) {
|
||
originArr := []byte{1, 1, 2, 2, 0, 0, 255, 0}
|
||
elem := []byte{7, 7}
|
||
|
||
testCases := []_InsertArrElemTestCase{
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 0,
|
||
Result: []byte{7, 7, 1, 1, 2, 2, 255, 0},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 1,
|
||
Result: []byte{1, 1, 7, 7, 2, 2, 255, 0},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 2,
|
||
Result: []byte{1, 1, 2, 2, 7, 7, 255, 0},
|
||
},
|
||
}
|
||
|
||
for _, testCase := range testCases {
|
||
arrcopy := make([]byte, len(testCase.Arr))
|
||
|
||
copy(arrcopy, testCase.Arr)
|
||
|
||
InsertArrElem(arrcopy, testCase.Qty, testCase.Elem, testCase.Idx)
|
||
|
||
if !bytes.Equal(arrcopy, testCase.Result) {
|
||
t.Fatalf(`
|
||
Source: %v
|
||
Estimate: %v
|
||
Real: %v`,
|
||
testCase.Arr, testCase.Result, arrcopy)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestDeleteReverseArrElem(t *testing.T) {
|
||
originArr := []byte{0, 0, 255, 3, 3, 2, 2, 1, 1}
|
||
|
||
testCases := []_DeleteArrElemTestCase{
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 0,
|
||
Result: []byte{0, 0, 255, 0, 0, 3, 3, 2, 2},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 1,
|
||
Result: []byte{0, 0, 255, 0, 0, 3, 3, 1, 1},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 3,
|
||
ElemSize: 2,
|
||
Idx: 2,
|
||
Result: []byte{0, 0, 255, 0, 0, 2, 2, 1, 1},
|
||
},
|
||
}
|
||
|
||
for _, testCase := range testCases {
|
||
arrcopy := make([]byte, len(testCase.Arr))
|
||
|
||
copy(arrcopy, testCase.Arr)
|
||
|
||
DeleteReverseArrElem(arrcopy, testCase.Qty, testCase.ElemSize, testCase.Idx)
|
||
|
||
if !bytes.Equal(arrcopy, testCase.Result) {
|
||
t.Fatalf(`
|
||
Source: %v
|
||
Estimate: %v
|
||
Real: %v`,
|
||
testCase.Arr, testCase.Result, arrcopy)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestInsertReverseArrElem(t *testing.T) {
|
||
originArr := []byte{0, 255, 0, 0, 2, 2, 1, 1}
|
||
elem := []byte{7, 7}
|
||
|
||
testCases := []_InsertArrElemTestCase{
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 0,
|
||
Result: []byte{0, 255, 2, 2, 1, 1, 7, 7},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 1,
|
||
Result: []byte{0, 255, 2, 2, 7, 7, 1, 1},
|
||
},
|
||
{
|
||
Arr: originArr,
|
||
Qty: 2,
|
||
Elem: elem,
|
||
Idx: 2,
|
||
Result: []byte{0, 255, 7, 7, 2, 2, 1, 1},
|
||
},
|
||
}
|
||
|
||
for _, testCase := range testCases {
|
||
arrcopy := make([]byte, len(testCase.Arr))
|
||
|
||
copy(arrcopy, testCase.Arr)
|
||
|
||
InsertReverseArrElem(arrcopy, testCase.Qty, testCase.Elem, testCase.Idx)
|
||
|
||
if !bytes.Equal(arrcopy, testCase.Result) {
|
||
t.Fatalf(`
|
||
Source: %v
|
||
Estimate: %v
|
||
Real: %v`,
|
||
testCase.Arr, testCase.Result, arrcopy)
|
||
}
|
||
}
|
||
}
|
||
|
||
func TestCompareToArrElem(t *testing.T) {
|
||
arr := []byte{1, 2, 3, 4}
|
||
elem := []byte{5, 2}
|
||
|
||
code := compareToArrElem(arr, elem, 1, HL)
|
||
|
||
fmt.Printf("code: %d\n", code)
|
||
}
|
||
|
||
type _FindArrElemTestCase struct {
|
||
Elem []byte // элемент, который будем искать в массиве
|
||
// Результат поиска - индекс и флаг
|
||
Idx int
|
||
Found bool
|
||
}
|
||
|
||
func TestFindArrElem(t *testing.T) {
|
||
arr := []byte{2, 2, 5, 5, 7, 7, 0, 0}
|
||
|
||
testCases := []_FindArrElemTestCase{
|
||
{
|
||
Elem: []byte{1, 1},
|
||
Idx: 0,
|
||
Found: false,
|
||
},
|
||
{
|
||
Elem: []byte{2, 2},
|
||
Idx: 0,
|
||
Found: true,
|
||
},
|
||
{
|
||
Elem: []byte{3, 3},
|
||
Idx: 1,
|
||
Found: false,
|
||
},
|
||
{
|
||
Elem: []byte{5, 5},
|
||
Idx: 1,
|
||
Found: true,
|
||
},
|
||
{
|
||
Elem: []byte{6, 6},
|
||
Idx: 2,
|
||
Found: false,
|
||
},
|
||
{
|
||
Elem: []byte{7, 7},
|
||
Idx: 2,
|
||
Found: true,
|
||
},
|
||
{
|
||
Elem: []byte{8, 8},
|
||
Idx: 3,
|
||
Found: false,
|
||
},
|
||
}
|
||
|
||
errorPattern := `Case:
|
||
byteOrder: %s
|
||
elem: %v
|
||
idx: %d
|
||
found: %t
|
||
|
||
Result:
|
||
idx: %d
|
||
found: %t
|
||
`
|
||
|
||
var (
|
||
idx int
|
||
found bool
|
||
)
|
||
|
||
for _, testCase := range testCases {
|
||
idx, found = FindArrElem(arr, 3, testCase.Elem, LH)
|
||
if idx != testCase.Idx || found != testCase.Found {
|
||
t.Fatalf(errorPattern,
|
||
LH, testCase.Elem, testCase.Idx, testCase.Found, idx, found)
|
||
}
|
||
|
||
// Тоже самое, но с другим порядком байт
|
||
idx, found = FindArrElem(arr, 3, testCase.Elem, HL)
|
||
if idx != testCase.Idx || found != testCase.Found {
|
||
t.Fatalf(errorPattern,
|
||
HL, testCase.Elem, testCase.Idx, testCase.Found, idx, found)
|
||
}
|
||
}
|
||
|
||
//fmt.Printf("idx: %d, found: %t\n", idx, found)
|
||
}
|