proceed to learn go!

This commit is contained in:
a.pivkin
2025-06-30 06:58:29 +03:00
parent 498d83835a
commit 6f809ab005
24 changed files with 567 additions and 15 deletions
+81
View File
@@ -0,0 +1,81 @@
package bookstore
import (
"errors"
"fmt"
)
type Category int
const (
CategoryAutobiography Category = iota
CategoryLargePrintRomance
CategoryParticlePhysics
)
var validCategory = map[Category]bool{
CategoryAutobiography: true,
CategoryLargePrintRomance: true,
CategoryParticlePhysics: true,
}
type Book struct {
Title string
Author string
Copies int
ID int
PriceCents int
DiscountPercents int
category Category
}
type Catalog map[int]Book
func Buy(b Book) (Book, error) {
if b.Copies == 0 {
return Book{}, errors.New("no copies left")
}
b.Copies --
return b, nil
}
func (c Catalog) GetAllBooks() []Book {
result := []Book{}
for _,b := range c {
result = append(result, b)
}
return result
}
func (c Catalog) GetBook(ID int) (Book, error) {
b, ok := c[ID]
if !ok {
return Book{}, fmt.Errorf("book with ID %d not found", ID)
}
return b, nil
}
func (b Book) NetPriceCents() int{
saving := b.PriceCents * b.DiscountPercents/100
return b.PriceCents - saving
}
func (b *Book) SetPriceCents(price int) (error) {
if price < 0 {
return fmt.Errorf("negative price %d", price)
}
b.PriceCents = price
return nil
}
func (b *Book) SetCategory(category Category) error {
if !validCategory[category] {
return fmt.Errorf("unknown category %q", category)
}
b.category = category
return nil
}
func (b Book) Category() Category {
return b.category
}
+134
View File
@@ -0,0 +1,134 @@
package bookstore_test
import (
"bookstore"
"testing"
"sort"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
)
func TestBuy(t *testing.T) {
t.Parallel()
b := bookstore.Book{
Title: "Lol",
Author: "KEK",
Copies: 2,
}
want := 1
result,err := bookstore.Buy(b)
if err != nil {
t.Fatal(err)
}
got := result.Copies
if want != got {
t.Errorf("Want %d but got %d", want,got)
}
}
func TestBuyOutOfStock(t *testing.T) {
t.Parallel()
b := bookstore.Book{
Title: "Lol",
Author: "KEK",
Copies: 0,
}
_,err := bookstore.Buy(b)
if err == nil {
t.Error("Book is out of stock")
}
}
func TestGetAllBooks(t *testing.T) {
t.Parallel()
catalog := bookstore.Catalog{
1: {ID: 1, Title: "For the Love of Go"},
2: {ID: 2, Title: "The Power of Go: Tools"},
}
want := []bookstore.Book{
{ID: 1, Title: "For the Love of Go"},
{ID: 2, Title: "The Power of Go: Tools"},
}
got := catalog.GetAllBooks()
sort.Slice(got, func(i, j int) bool {
return got[i].ID < got[j].ID
})
if !cmp.Equal(want, got,cmpopts.IgnoreUnexported(bookstore.Book{})) {
t.Error(cmp.Diff(want, got,))
}
}
func TestGetBook(t *testing.T) {
t.Parallel()
catalog := bookstore.Catalog{
1: {ID: 1, Title: "For the Love of Go"},
2: {ID: 2, Title: "The Power of Go: Tools"},
}
// want := bookstore.Book{ID: 2, Title: "The Power of Go: Tools"}
_, err := catalog.GetBook(2)
if err != nil {
t.Fatal("want error for non-existent ID, got nil")
}
}
func TestNetPriceCents(t *testing.T) {
t.Parallel()
b := bookstore.Book {
Title: "For the love of Go",
PriceCents: 4000,
DiscountPercents: 25,
}
want := 3000
got := b.NetPriceCents()
if want != got {
t.Errorf("want %d, got %d",want,got)
}
}
func TestSetPriceCents(t *testing.T) {
t.Parallel()
b := bookstore.Book{
Title: "For the Love of Go",
PriceCents: 4000,
}
want := 3000
err := b.SetPriceCents(want)
if err != nil {
t.Fatal(err)
}
got := b.PriceCents
if want != got {
t.Errorf("want updated price %d, got %d", want, got)
}
}
func TestSetCategory(t *testing.T) {
t.Parallel()
b := bookstore.Book{
Title: "For the Love of Go",
}
cats := []bookstore.Category {
bookstore.CategoryAutobiography,
bookstore.CategoryLargePrintRomance,
bookstore.CategoryParticlePhysics,
}
for _, cat := range cats {
err := b.SetCategory(cat)
if err != nil {
t.Fatal(err)
}
got := b.Category()
if cat != got {
t.Errorf("want category %q, got %q", cat, got)
}
}
}
func TestSetCategoryInvalid(t *testing.T) {
t.Parallel()
b := bookstore.Book{
Title: "For the Love of Go",
}
err := b.SetCategory(999)
if err == nil {
t.Fatal("want error for invalid category, got nil")
}
}
+5
View File
@@ -0,0 +1,5 @@
module bookstore
go 1.24.4
require github.com/google/go-cmp v0.7.0
+2
View File
@@ -0,0 +1,2 @@
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
+4
View File
@@ -0,0 +1,4 @@
mode: set
bookstore/bookstore.go:13.32,14.19 1 1
bookstore/bookstore.go:14.19,16.3 1 1
bookstore/bookstore.go:17.2,18.15 2 1