diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..608d3c6 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Launch Package", + "type": "go", + "request": "launch", + "mode": "auto", + "program": "${fileDirname}" + } + ] +} \ No newline at end of file diff --git a/bookstore/bookstore.go b/bookstore/bookstore.go new file mode 100644 index 0000000..fd4d797 --- /dev/null +++ b/bookstore/bookstore.go @@ -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 +} \ No newline at end of file diff --git a/bookstore/bookstore_test.go b/bookstore/bookstore_test.go new file mode 100644 index 0000000..851a4d7 --- /dev/null +++ b/bookstore/bookstore_test.go @@ -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") + } +} \ No newline at end of file diff --git a/bookstore/go.mod b/bookstore/go.mod new file mode 100644 index 0000000..47e349a --- /dev/null +++ b/bookstore/go.mod @@ -0,0 +1,5 @@ +module bookstore + +go 1.24.4 + +require github.com/google/go-cmp v0.7.0 diff --git a/bookstore/go.sum b/bookstore/go.sum new file mode 100644 index 0000000..40e761a --- /dev/null +++ b/bookstore/go.sum @@ -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= diff --git a/bookstore/kek.out b/bookstore/kek.out new file mode 100644 index 0000000..d5977ef --- /dev/null +++ b/bookstore/kek.out @@ -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 diff --git a/calculator/calculator.go b/calculator/calculator.go index 067f273..6c5e34d 100755 --- a/calculator/calculator.go +++ b/calculator/calculator.go @@ -1,14 +1,25 @@ // Package calculator does simple calculations. package calculator // Add takes two numbers and returns the result of adding them together. -func Add(a, b float64) float64 { +import ( + "errors" +) + +func Add(a, b int) int { return a + b } -func Subtract(a, b float64) float64 { +func Subtract(a, b int) int { return a - b } -func Multiply(a, b float64) float64 { +func Multiply(a, b int) int { return a * b } + +func Divide(a, b int) (int, error) { + if b == 0 { + return 0, errors.New("division by zero not allowed") + } + return a / b, nil +} \ No newline at end of file diff --git a/calculator/calculator_test.go b/calculator/calculator_test.go index 0ff3a09..ff32c7d 100755 --- a/calculator/calculator_test.go +++ b/calculator/calculator_test.go @@ -7,27 +7,80 @@ import ( func TestAdd(t *testing.T) { t.Parallel() - var want float64 = 4 - got := calculator.Add(2, 2) - if want != got { - t.Errorf("want %f, got %f", want, got) + + type TestCase struct { + a, b int + want int + } + testCases := []TestCase{ + {a: 2, b: 2, want: 4}, + {a: 5, b: 0, want: 5}, + {a: 1, b: 1, want: 2}, + } + for _, tc := range testCases { + got := calculator.Add(tc.a, tc.b) + if tc.want != got { + t.Errorf("Add(%d, %d): want %d, got %d", tc.a, tc.b, tc.want, got) + } } } func TestSubtract(t *testing.T) { t.Parallel() - var want float64 = 2 - got := calculator.Subtract(4, 2) - if want != got { - t.Errorf("want %f, got %f", want, got) + type testCase struct { + a,b int + want int + } + testCases := []testCase { + {a: 5,b: 3,want: 2}, + {a: 4,b: 3,want: 1}, + {a: 10,b: 3,want: 7}, + } + for _,tc := range testCases { + got := calculator.Subtract(tc.a, tc.b) + if tc.want != got { + t.Errorf("Subtract(%d, %d): want %d, got %d", tc.a,tc.b,tc.want, got) + } } } func TestMultiply(t *testing.T) { t.Parallel() - var want float64 = 6 - got := calculator.Multiply(2, 3) - if want != got { - t.Errorf("want %f, got %f", want, got) + type testCase struct { + a,b int + want int + } + testCases := []testCase { + {a: 5,b: 3,want: 15}, + {a: 4,b: 3,want: 12}, + {a: 10,b: 3,want: 30}, + } + for _,tc := range testCases { + got := calculator.Multiply(tc.a,tc.b) + if tc.want != got { + t.Errorf("Multiply(%d, %d): want %d, got %d", tc.a, tc.b, tc.want, got) + } + } +} + +func TestDivide(t *testing.T) { + t.Parallel() + type testCase struct { + a,b int + want int + } + testCases := []testCase { + {a: 6,b: 3,want: 2}, + {a: 12,b: 3,want: 4}, + {a: 10,b: 2,want: 5}, + } + for _,tc := range testCases { + got,err := calculator.Divide(tc.a,tc.b) + if err != nil { + t.Errorf("WTF r u doing?") + } + if tc.want != got { + t.Errorf("Multiply(%d, %d): want %d, got %d", tc.a, tc.b, tc.want, got) + } } } diff --git a/calculator/cmd/calculator/main.go b/calculator/cmd/calculator/main.go new file mode 100644 index 0000000..96790b4 --- /dev/null +++ b/calculator/cmd/calculator/main.go @@ -0,0 +1,11 @@ +package main + +import ( + "calculator" + "fmt" +) + +func main() { + result := calculator.Add(2, 2) + fmt.Println(result) +} diff --git a/calculator/kek b/calculator/kek new file mode 100755 index 0000000..3892994 Binary files /dev/null and b/calculator/kek differ diff --git a/creditcards/creditcards.go b/creditcards/creditcards.go new file mode 100644 index 0000000..b7467b9 --- /dev/null +++ b/creditcards/creditcards.go @@ -0,0 +1,19 @@ +package creditcards + +import "errors" + + +type card struct { + number string +} + +func New(number string) (card,error) { + if number == "" { + return card{}, errors.New("number must not be empty") + } + return card{number},nil +} + +func (c *card) Number() string { + return c.number +} \ No newline at end of file diff --git a/creditcards/creditcards_test.go b/creditcards/creditcards_test.go new file mode 100644 index 0000000..8653814 --- /dev/null +++ b/creditcards/creditcards_test.go @@ -0,0 +1,26 @@ +package creditcards_test + +import ( + "creditcards" + "testing" +) + +func TestNew(t *testing.T) { + t.Parallel() + want := "1234567890" + cc, err := creditcards.New(want) + if err != nil { + t.Fatal(err) + } + got := cc.Number() + if want != got { + t.Errorf("want %q, got %q", want, got) + } +} +func TestNewInvalidReturnsError(t *testing.T) { + t.Parallel() + _, err := creditcards.New("") + if err == nil { + t.Fatal("want error for invalid card number, got nil") + } +} \ No newline at end of file diff --git a/creditcards/go.mod b/creditcards/go.mod new file mode 100644 index 0000000..632cf99 --- /dev/null +++ b/creditcards/go.mod @@ -0,0 +1,3 @@ +module creditcards + +go 1.24.4 diff --git a/diff/_switch/cmd/switch/__debug_bin1699744996 b/diff/_switch/cmd/switch/__debug_bin1699744996 new file mode 100755 index 0000000..e2db847 Binary files /dev/null and b/diff/_switch/cmd/switch/__debug_bin1699744996 differ diff --git a/diff/_switch/cmd/switch/main.go b/diff/_switch/cmd/switch/main.go new file mode 100644 index 0000000..ea11128 --- /dev/null +++ b/diff/_switch/cmd/switch/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "switch/internal/switchpkg" +) + +func main() { + switchpkg.Say("Utii") +} diff --git a/diff/_switch/go.mod b/diff/_switch/go.mod new file mode 100644 index 0000000..e722938 --- /dev/null +++ b/diff/_switch/go.mod @@ -0,0 +1,3 @@ +module switch + +go 1.24.4 diff --git a/diff/_switch/internal/switchpkg/switch.go b/diff/_switch/internal/switchpkg/switch.go new file mode 100644 index 0000000..c076f8a --- /dev/null +++ b/diff/_switch/internal/switchpkg/switch.go @@ -0,0 +1,9 @@ +package switchpkg + +import ( + "fmt" +) + +func Say(name string) { + fmt.Printf("Hello %s",name) +} \ No newline at end of file diff --git a/mytypes/go.mod b/mytypes/go.mod new file mode 100644 index 0000000..e74c47a --- /dev/null +++ b/mytypes/go.mod @@ -0,0 +1,3 @@ +module mytypes + +go 1.24.4 diff --git a/mytypes/mytypes.go b/mytypes/mytypes.go new file mode 100644 index 0000000..d2eb067 --- /dev/null +++ b/mytypes/mytypes.go @@ -0,0 +1,35 @@ +package mytypes + +import "strings" + +type MyInt int +type MyString string +type MyBuilder struct { + Contents strings.Builder +} + +func (i MyInt) Twice() MyInt { + return i * 2 +} + + +func (i MyString) Len() int { + return len(i) +} + +func (s MyBuilder) Hello() string { + return "Hello, Gophers!" +} + +func (s MyBuilder) Uppers(in string) string { + return strings.ToUpper(in) +} + +func Double(input *int) int{ + *input *= 2 + return *input +} + +func (input *MyInt) Double() { + *input *= 2 +} \ No newline at end of file diff --git a/mytypes/mytypes_test.go b/mytypes/mytypes_test.go new file mode 100644 index 0000000..0298fe9 --- /dev/null +++ b/mytypes/mytypes_test.go @@ -0,0 +1,107 @@ +package mytypes_test + +import ( + "mytypes" + "testing" + "strings" +) + +func TestTwice(t *testing.T) { + t.Parallel() + input := mytypes.MyInt(9) + want := mytypes.MyInt(18) + got := input.Twice() + if want != got { + t.Errorf("twice %d: want %d, got %d", input, want, + got) + } +} + +func TestMyStringLen(t *testing.T) { + t.Parallel() + input := mytypes.MyString("lol") + want := 3 + got := input.Len() + if want != got { + t.Errorf("%q: want %d, got %d", input, want, got) + } +} + +func TestStringsBuilder(t *testing.T) { + t.Parallel() + var sb strings.Builder + sb.WriteString("Hello, ") + sb.WriteString("Gophers!") + want := "Hello, Gophers!" + got := sb.String() + if want != got { + t.Errorf("want %q, got %q", want, got) + } + wantLen := 15 + gotLen := sb.Len() + if wantLen != gotLen { + t.Errorf("%q: want len %d, got %d", sb.String(), + wantLen, gotLen) + } +} + +// func TestMyBuilderLen(t *testing.T) { +// t.Parallel() +// var mb mytypes.MyBuilder +// want := 15 +// got := mb.Len() +// if want != got { +// t.Errorf("want %d, got %d", want, got) +// } +// } + +func TestMyBuilderHello(t *testing.T) { + t.Parallel() + var mb mytypes.MyBuilder + want := "Hello, Gophers!" + got := mb.Hello() + if want != got { + t.Errorf("want %q, got %q", want, got) + } +} + +func TestMyBuilder(t *testing.T) { + t.Parallel() + var mb mytypes.MyBuilder + mb.Contents.WriteString("Hello, ") + mb.Contents.WriteString("Gophers!") + want := "Hello, Gophers!" + got := mb.Contents.String() + if want != got { + t.Errorf("want %q, got %q", want, got) + } + wantLen := 15 + gotLen := mb.Contents.Len() + if wantLen != gotLen { + t.Errorf("%q: want len %d, got %d", + mb.Contents.String(), wantLen, gotLen) + } +} + +func TestUpperCase(t *testing.T) { + t.Parallel() + var mb mytypes.MyBuilder + input := "hello" + want := "HELLO" + got := mb.Uppers(input) + if got != want { + t.Errorf("%q: want %s, got %s",input,want,got) + } +} + +func TestDouble(t *testing.T) { + t.Parallel() + x := mytypes.MyInt(12) + want := mytypes.MyInt(24) + p := &x + p.Double() + if want != x { + t.Errorf("want %d, got %d",want,x) + } +} + diff --git a/vars/cmd/vars/main.go b/vars/cmd/vars/main.go new file mode 100644 index 0000000..5e91809 --- /dev/null +++ b/vars/cmd/vars/main.go @@ -0,0 +1,10 @@ +package main + +import ( + "test_vars" +) + +func main() { + title := "lolkek" + test_vars.PrintTitle(title) +} diff --git a/vars/go.mod b/vars/go.mod new file mode 100644 index 0000000..11dbdb9 --- /dev/null +++ b/vars/go.mod @@ -0,0 +1,3 @@ +module test_vars + +go 1.24.4 diff --git a/vars/vars b/vars/vars new file mode 100755 index 0000000..a3815f0 Binary files /dev/null and b/vars/vars differ diff --git a/vars/vars.go b/vars/vars.go new file mode 100644 index 0000000..3250e0f --- /dev/null +++ b/vars/vars.go @@ -0,0 +1,9 @@ +package test_vars + +import ( + "fmt" +) + +func PrintTitle(title string) { + fmt.Printf("Title is %s\n", title) +} \ No newline at end of file