proceed to learn go!
This commit is contained in:
@@ -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
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
module bookstore
|
||||
|
||||
go 1.24.4
|
||||
|
||||
require github.com/google/go-cmp v0.7.0
|
||||
@@ -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=
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user