Skip to content

Instantly share code, notes, and snippets.

@igorzakhar
Last active December 3, 2019 05:24
Show Gist options
  • Save igorzakhar/787c2c4a9f6dbcbc090cbfb3b168fabb to your computer and use it in GitHub Desktop.
Save igorzakhar/787c2c4a9f6dbcbc090cbfb3b168fabb to your computer and use it in GitHub Desktop.
package main
import (
"errors"
"fmt"
"strconv"
"strings"
)
// CheckCommission проверяет значение комиссии.
// Возвращает значение комиссии типа uint64 и nil или 0 и error если произошла ошибка.
func CheckCommission(number string) (uint64, error) {
inputValue := normalizeInputValue(number)
// Проверка возможности преобразования полученной строки в допустимое значение с плавающей запятой.
floatValue, err := strconv.ParseFloat(inputValue, 64)
if err != nil {
err = fmt.Errorf("Введено не число: %s", number)
return 0, err
}
if floatValue < 0 {
err = fmt.Errorf("Размер комиссии не может быть меньше 0: %s", number)
return 0, err
}
result, err := ConvertCommisionToUint(inputValue)
if err != nil {
return 0, err
}
if result > 9999 {
err = fmt.Errorf("Размер комиссии не может быть больше 99.99: %s", number)
return 0, err
}
return result, nil
}
// ConvertCommisionToUint принимает размер комиссии в виде строки и конвертирует ее в uint64
func ConvertCommisionToUint(input string) (uint64, error) {
groups := strings.Split(input, ".")
integerPart := groups[0]
fractionalPart := ""
// Обработка дробной части полученного значения
if len(groups) == 2 {
if len(groups[1]) > 2 {
err := errors.New("Максимальное количество знаков после запятой: 2")
return 0, err
}
fractionalPart = groups[1]
}
for len(fractionalPart) < 2 {
fractionalPart += "0"
}
integerPart += fractionalPart
return strconv.ParseUint(integerPart, 10, 64)
}
// normalizeInputValue нормализует полученную строку перед тем как передать её в функцию strconv.ParseFloat()
// путем замены символа "," на символ "." и удаления лишних пробелов в начале и конце строки.
func normalizeInputValue(input string) string {
normalizedValue := strings.Replace(strings.TrimSpace(input), ",", ".", 1)
return normalizedValue
}
func main() {
testValues := []string{"0.01", "79.35", "9.20", "99.99", "1.5", "55", " 5,12 ", "\t12,34\n", "неЧисло", "100,199.99", "100", "-1.5"}
for _, input := range testValues {
fmt.Printf("\nВводимое значение: %q\n", input)
if commisionValue, err := CheckCommission(input); err == nil {
fmt.Println("Преобразованное значение:", commisionValue)
} else {
fmt.Println("Ошибка:", err)
}
}
}
package main
import (
"testing"
)
func TestCheckCommission(t *testing.T) {
tests := []struct {
name string
value string
want uint64
wantErr bool
}{
// "0.01", "79.35", "9.20", "99.99", "1.5", "55", " 5,12 ", "\t12,34\n", "неЧисло", "100,199.99", "100", "-1.5"
{"Значение:\"0.01\"", "0.01", 1, false},
{"Значение:\"79.35\"", "79.35", 7935, false},
{"Значение:\"9.20\"", "9.20", 920, false},
{"Значение:\"99.99\"", "99.99", 9999, false},
{"Значение:\"1.5\"", "1.5", 150, false},
{"Значение:\"55\"", "55", 5500, false},
{"Значение:\" 5,12 \"", " 5,12 ", 512, false},
{"Значение:\"\t12,34\n\"", "\t12,34\n", 1234, false},
{"Значение:\"неЧисло\"", "неЧисло", 0, true},
{"Значение:\"100,199.99\"", "100,199.99", 0, true},
{"Значение:\"100\"", "100", 0, true},
{"Значение:\"-1.5\"", "-1.5", 0, true},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := CheckCommission(test.value)
if (err != nil) != test.wantErr {
t.Errorf("CheckCommission() error = %v, wantErr %v", err, test.wantErr)
return
}
if got != test.want {
t.Errorf("CheckCommission() = %v, want %v", got, test.want)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment