Исходники и презентации

This commit is contained in:
2025-05-23 07:26:39 +03:00
parent aa948179d5
commit 02d8430a3a
514 changed files with 13773 additions and 0 deletions

View File

@ -0,0 +1,49 @@
package main
import (
"reflect"
"testing"
"unsafe"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
func Defragment(memory []byte, pointers []unsafe.Pointer) {
// need to implement
}
func TestDefragmentation(t *testing.T) {
var fragmentedMemory = []byte{
0xFF, 0x00, 0x00, 0x00,
0x00, 0xFF, 0x00, 0x00,
0x00, 0x00, 0xFF, 0x00,
0x00, 0x00, 0x00, 0xFF,
}
var fragmentedPointers = []unsafe.Pointer{
unsafe.Pointer(&fragmentedMemory[0]),
unsafe.Pointer(&fragmentedMemory[5]),
unsafe.Pointer(&fragmentedMemory[10]),
unsafe.Pointer(&fragmentedMemory[15]),
}
var defragmentedPointers = []unsafe.Pointer{
unsafe.Pointer(&fragmentedMemory[0]),
unsafe.Pointer(&fragmentedMemory[1]),
unsafe.Pointer(&fragmentedMemory[2]),
unsafe.Pointer(&fragmentedMemory[3]),
}
var defragmentedMemory = []byte{
0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
}
Defragment(fragmentedMemory, fragmentedPointers)
assert.True(t, reflect.DeepEqual(defragmentedMemory, fragmentedMemory))
assert.True(t, reflect.DeepEqual(defragmentedPointers, fragmentedPointers))
}

View File

@ -0,0 +1,58 @@
package main
import (
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type WorkerPool struct {
// need to implement
}
func NewWorkerPool(workersNumber int) *WorkerPool {
// need to implement
return &WorkerPool{}
}
// Return an error if the pool is full
func (wp *WorkerPool) AddTask(task func()) error {
// need to implement
return nil
}
// Shutdown all workers and wait for all
// tasks in the pool to complete
func (wp *WorkerPool) Shutdown() {
// need to implement
}
func TestWorkerPool(t *testing.T) {
var counter atomic.Int32
task := func() {
time.Sleep(time.Millisecond * 500)
counter.Add(1)
}
pool := NewWorkerPool(2)
_ = pool.AddTask(task)
_ = pool.AddTask(task)
_ = pool.AddTask(task)
time.Sleep(time.Millisecond * 600)
assert.Equal(t, int32(2), counter.Load())
time.Sleep(time.Millisecond * 600)
assert.Equal(t, int32(3), counter.Load())
_ = pool.AddTask(task)
_ = pool.AddTask(task)
_ = pool.AddTask(task)
pool.Shutdown() // wait tasks
assert.Equal(t, int32(6), counter.Load())
}

View File

@ -0,0 +1,74 @@
package main
import (
"context"
"errors"
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type Group struct {
// need to implement
}
func NewErrGroup(ctx context.Context) (*Group, context.Context) {
// need to implement
return &Group{}, ctx
}
func (g *Group) Go(action func() error) {
// need to implement
}
func (g *Group) Wait() error {
// need to implement
return nil
}
func TestErrGroupWithoutError(t *testing.T) {
var counter atomic.Int32
group, _ := NewErrGroup(context.Background())
for i := 0; i < 5; i++ {
group.Go(func() error {
time.Sleep(time.Second)
counter.Add(1)
return nil
})
}
err := group.Wait()
assert.Equal(t, int32(5), counter.Load())
assert.NoError(t, err)
}
func TestErrGroupWithError(t *testing.T) {
var counter atomic.Int32
group, ctx := NewErrGroup(context.Background())
for i := 0; i < 5; i++ {
group.Go(func() error {
timer := time.NewTimer(time.Second)
defer timer.Stop()
select {
case <-ctx.Done():
return ctx.Err()
case <-timer.C:
counter.Add(1)
return nil
}
})
}
group.Go(func() error {
return errors.New("error")
})
err := group.Wait()
assert.Equal(t, int32(0), counter.Load())
assert.Error(t, err)
}

View File

@ -0,0 +1,48 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
func ToLittleEndian(number uint32) uint32 {
return 0 // need to implement
}
func TestСonversion(t *testing.T) {
tests := map[string]struct {
number uint32
result uint32
}{
"test case #1": {
number: 0x00000000,
result: 0x00000000,
},
"test case #2": {
number: 0xFFFFFFFF,
result: 0xFFFFFFFF,
},
"test case #3": {
number: 0x00FF00FF,
result: 0xFF00FF00,
},
"test case #4": {
number: 0x0000FFFF,
result: 0xFFFF0000,
},
"test case #5": {
number: 0x01020304,
result: 0x04030201,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
result := ToLittleEndian(test.number)
assert.Equal(t, test.result, result)
})
}
}

View File

@ -0,0 +1,33 @@
package main
import (
"errors"
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type MultiError struct {
// need to implement
}
func (e *MultiError) Error() string {
// need to implement
return ""
}
func Append(err error, errs ...error) *MultiError {
// need to implement
return nil
}
func TestMultiError(t *testing.T) {
var err error
err = Append(err, errors.New("error 1"))
err = Append(err, errors.New("error 2"))
expectedMessage := "2 errors occured:\n\t* error 1\t* error 2\n"
assert.EqualError(t, err, expectedMessage)
}

View File

@ -0,0 +1,150 @@
package main
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
func Map(data []int, action func(int) int) []int {
// need to implement
return nil
}
func Filter(data []int, action func(int) bool) []int {
// need to implement
return nil
}
func Reduce(data []int, initial int, action func(int, int) int) int {
// need to implement
return 0
}
func TestMap(t *testing.T) {
tests := map[string]struct {
data []int
action func(int) int
result []int
}{
"nil numbers": {
action: func(number int) int {
return -number
},
},
"empty numbers": {
data: []int{},
action: func(number int) int {
return -number
},
result: []int{},
},
"inc numbers": {
data: []int{1, 2, 3, 4, 5},
action: func(number int) int {
return number + 1
},
result: []int{2, 3, 4, 5, 6},
},
"double numbers": {
data: []int{1, 2, 3, 4, 5},
action: func(number int) int {
return number * number
},
result: []int{1, 4, 9, 16, 25},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
result := Map(test.data, test.action)
assert.True(t, reflect.DeepEqual(test.result, result))
})
}
}
func TestFilter(t *testing.T) {
tests := map[string]struct {
data []int
action func(int) bool
result []int
}{
"nil numbers": {
action: func(number int) bool {
return number == 0
},
},
"empty numbers": {
data: []int{},
action: func(number int) bool {
return number == 1
},
result: []int{},
},
"even numbers": {
data: []int{1, 2, 3, 4, 5},
action: func(number int) bool {
return number%2 == 0
},
result: []int{2, 4},
},
"positive numbers": {
data: []int{-1, -2, 1, 2},
action: func(number int) bool {
return number > 0
},
result: []int{1, 2},
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
result := Filter(test.data, test.action)
assert.True(t, reflect.DeepEqual(test.result, result))
})
}
}
func TestReduce(t *testing.T) {
tests := map[string]struct {
initial int
data []int
action func(int, int) int
result int
}{
"nil numbers": {
action: func(lhs, rhs int) int {
return 0
},
},
"empty numbers": {
data: []int{},
action: func(lhs, rhs int) int {
return 0
},
},
"sum of numbers": {
data: []int{1, 2, 3, 4, 5},
action: func(lhs, rhs int) int {
return lhs + rhs
},
result: 15,
},
"sum of numbers with initial value": {
initial: 10,
data: []int{1, 2, 3, 4, 5},
action: func(lhs, rhs int) int {
return lhs + rhs
},
result: 25,
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
result := Reduce(test.data, test.initial, test.action)
assert.Equal(t, test.result, result)
})
}
}

View File

@ -0,0 +1,62 @@
package main
import (
"reflect"
"testing"
"unsafe"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
func Trace(stacks [][]uintptr) []uintptr {
// need to implement
return nil
}
func TestTrace(t *testing.T) {
var heapObjects = []int{
0x00, 0x00, 0x00, 0x00, 0x00,
}
var heapPointer1 *int = &heapObjects[1]
var heapPointer2 *int = &heapObjects[2]
var heapPointer3 *int = nil
var heapPointer4 **int = &heapPointer3
var stacks = [][]uintptr{
{
uintptr(unsafe.Pointer(&heapPointer1)), 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, uintptr(unsafe.Pointer(&heapObjects[0])),
0x00, 0x00, 0x00, 0x00,
},
{
uintptr(unsafe.Pointer(&heapPointer2)), 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, uintptr(unsafe.Pointer(&heapObjects[1])),
0x00, 0x00, 0x00, uintptr(unsafe.Pointer(&heapObjects[2])),
uintptr(unsafe.Pointer(&heapPointer4)), 0x00, 0x00, 0x00,
},
{
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, uintptr(unsafe.Pointer(&heapObjects[3])),
},
}
pointers := Trace(stacks)
expectedPointers := []uintptr{
uintptr(unsafe.Pointer(&heapPointer1)),
uintptr(unsafe.Pointer(&heapObjects[0])),
uintptr(unsafe.Pointer(&heapPointer2)),
uintptr(unsafe.Pointer(&heapObjects[1])),
uintptr(unsafe.Pointer(&heapObjects[2])),
uintptr(unsafe.Pointer(&heapPointer4)),
uintptr(unsafe.Pointer(&heapPointer3)),
uintptr(unsafe.Pointer(&heapObjects[3])),
}
assert.True(t, reflect.DeepEqual(expectedPointers, pointers))
}

View File

@ -0,0 +1,56 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type Person struct {
Name string `properties:"name"`
Address string `properties:"address,omitempty"`
Age int `properties:"age"`
Married bool `properties:"married"`
}
func Serialize(person Person) string {
// need to implement
return ""
}
func TestSerialization(t *testing.T) {
tests := map[string]struct {
person Person
result string
}{
"test case with empty fields": {
result: "name=\nage=0\nmarried=false",
},
"test case with fields": {
person: Person{
Name: "John Doe",
Age: 30,
Married: true,
},
result: "name=John Doe\nage=30\nmarried=true",
},
"test case with omitempty field": {
person: Person{
Name: "John Doe",
Age: 30,
Married: true,
Address: "Paris",
},
result: "name=John Doe\naddress=Paris\nage=30\nmarried=true",
},
}
for name, test := range tests {
t.Run(name, func(t *testing.T) {
result := Serialize(test.person)
assert.Equal(t, test.result, result)
})
}
}

View File

@ -0,0 +1,63 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
type Task struct {
Identifier int
Priority int
}
type Scheduler struct {
// need to implement
}
func NewScheduler() Scheduler {
// need to implement
return Scheduler{}
}
func (s *Scheduler) AddTask(task Task) {
// need to implement
}
func (s *Scheduler) ChangeTaskPriority(taskID int, newPriority int) {
// need to implement
}
func (s *Scheduler) GetTask() Task {
// need to implement
return Task{}
}
func TestTrace(t *testing.T) {
task1 := Task{Identifier: 1, Priority: 10}
task2 := Task{Identifier: 2, Priority: 20}
task3 := Task{Identifier: 3, Priority: 30}
task4 := Task{Identifier: 4, Priority: 40}
task5 := Task{Identifier: 5, Priority: 50}
scheduler := NewScheduler()
scheduler.AddTask(task1)
scheduler.AddTask(task2)
scheduler.AddTask(task3)
scheduler.AddTask(task4)
scheduler.AddTask(task5)
task := scheduler.GetTask()
assert.Equal(t, task5, task)
task = scheduler.GetTask()
assert.Equal(t, task4, task)
scheduler.ChangeTaskPriority(1, 100)
task = scheduler.GetTask()
assert.Equal(t, task1, task)
task = scheduler.GetTask()
assert.Equal(t, task3, task)
}

View File

@ -0,0 +1,63 @@
package main
import (
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type UserService struct {
// not need to implement
NotEmptyStruct bool
}
type MessageService struct {
// not need to implement
NotEmptyStruct bool
}
type Container struct {
// need to implement
}
func NewContainer() *Container {
// need to implement
return &Container{}
}
func (c *Container) RegisterType(name string, constructor interface{}) {
// need to implement
}
func (c *Container) Resolve(name string) (interface{}, error) {
// need to implement
return nil, nil
}
func TestDIContainer(t *testing.T) {
container := NewContainer()
container.RegisterType("UserService", func() interface{} {
return &UserService{}
})
container.RegisterType("MessageService", func() interface{} {
return &MessageService{}
})
userService1, err := container.Resolve("UserService")
assert.NoError(t, err)
userService2, err := container.Resolve("UserService")
assert.NoError(t, err)
u1 := userService1.(*UserService)
u2 := userService2.(*UserService)
assert.False(t, u1 == u2)
messageService, err := container.Resolve("MessageService")
assert.NoError(t, err)
assert.NotNil(t, messageService)
paymentService, err := container.Resolve("PaymentService")
assert.Error(t, err)
assert.Nil(t, paymentService)
}

View File

@ -0,0 +1,83 @@
package main
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type OrderedMap struct {
// need to implement
}
func NewOrderedMap() OrderedMap {
return OrderedMap{} // need to implement
}
func (m *OrderedMap) Insert(key, value int) {
// need to implement
}
func (m *OrderedMap) Erase(key int) {
// need to implement
}
func (m *OrderedMap) Contains(key int) bool {
return false // need to implement
}
func (m *OrderedMap) Size() int {
return 0 // need to implement
}
func (m *OrderedMap) ForEach(action func(int, int)) {
// need to implement
}
func TestCircularQueue(t *testing.T) {
data := NewOrderedMap()
assert.Zero(t, data.Size())
data.Insert(10, 10)
data.Insert(5, 5)
data.Insert(15, 15)
data.Insert(2, 2)
data.Insert(4, 4)
data.Insert(12, 12)
data.Insert(14, 14)
assert.Equal(t, 7, data.Size())
assert.True(t, data.Contains(4))
assert.True(t, data.Contains(12))
assert.False(t, data.Contains(3))
assert.False(t, data.Contains(13))
var keys []int
expectedKeys := []int{2, 4, 5, 10, 12, 14, 15}
data.ForEach(func(key, _ int) {
keys = append(keys, key)
})
assert.True(t, reflect.DeepEqual(expectedKeys, keys))
data.Erase(15)
data.Erase(14)
data.Erase(2)
assert.Equal(t, 4, data.Size())
assert.True(t, data.Contains(4))
assert.True(t, data.Contains(12))
assert.False(t, data.Contains(2))
assert.False(t, data.Contains(14))
keys = nil
expectedKeys = []int{4, 5, 10, 12}
data.ForEach(func(key, _ int) {
keys = append(keys, key)
})
assert.True(t, reflect.DeepEqual(expectedKeys, keys))
}

View File

@ -0,0 +1,86 @@
package main
import (
"reflect"
"testing"
"github.com/stretchr/testify/assert"
)
// go test -v homework_test.go
type CircularQueue struct {
values []int
// need to implement
}
func NewCircularQueue(size int) CircularQueue {
return CircularQueue{} // need to implement
}
func (q *CircularQueue) Push(value int) bool {
return false // need to implement
}
func (q *CircularQueue) Pop() bool {
return false // need to implement
}
func (q *CircularQueue) Front() int {
return -1 // need to implement
}
func (q *CircularQueue) Back() int {
return -1 // need to implement
}
func (q *CircularQueue) Empty() bool {
return false // need to implement
}
func (q *CircularQueue) Full() bool {
return false // need to implement
}
func TestCircularQueue(t *testing.T) {
const queueSize = 3
queue := NewCircularQueue(queueSize)
assert.True(t, queue.Empty())
assert.False(t, queue.Full())
assert.Equal(t, -1, queue.Front())
assert.Equal(t, -1, queue.Back())
assert.False(t, queue.Pop())
assert.True(t, queue.Push(1))
assert.True(t, queue.Push(2))
assert.True(t, queue.Push(3))
assert.False(t, queue.Push(4))
assert.True(t, reflect.DeepEqual([]int{1, 2, 3}, queue.values))
assert.False(t, queue.Empty())
assert.True(t, queue.Full())
assert.Equal(t, 1, queue.Front())
assert.Equal(t, 3, queue.Back())
assert.True(t, queue.Pop())
assert.False(t, queue.Empty())
assert.False(t, queue.Full())
assert.True(t, queue.Push(4))
assert.True(t, reflect.DeepEqual([]int{4, 2, 3}, queue.values))
assert.Equal(t, 2, queue.Front())
assert.Equal(t, 4, queue.Back())
assert.True(t, queue.Pop())
assert.True(t, queue.Pop())
assert.True(t, queue.Pop())
assert.False(t, queue.Pop())
assert.True(t, queue.Empty())
assert.False(t, queue.Full())
}

View File

@ -0,0 +1,74 @@
package main
import (
"reflect"
"testing"
"unsafe"
"github.com/stretchr/testify/assert"
)
type COWBuffer struct {
data []byte
refs *int
// need to implement
}
func NewCOWBuffer(data []byte) COWBuffer {
return COWBuffer{} // need to implement
}
func (b *COWBuffer) Clone() COWBuffer {
return COWBuffer{} // need to implement
}
func (b *COWBuffer) Close() {
// need to implement
}
func (b *COWBuffer) Update(index int, value byte) bool {
return false // need to implement
}
func (b *COWBuffer) String() string {
return "" // need to implement
}
func TestCOWBuffer(t *testing.T) {
data := []byte{'a', 'b', 'c', 'd'}
buffer := NewCOWBuffer(data)
defer buffer.Close()
copy1 := buffer.Clone()
copy2 := buffer.Clone()
assert.Equal(t, unsafe.SliceData(data), unsafe.SliceData(buffer.data))
assert.Equal(t, unsafe.SliceData(buffer.data), unsafe.SliceData(copy1.data))
assert.Equal(t, unsafe.SliceData(copy1.data), unsafe.SliceData(copy2.data))
assert.True(t, (*byte)(unsafe.SliceData(data)) == unsafe.StringData(buffer.String()))
assert.True(t, (*byte)(unsafe.StringData(buffer.String())) == unsafe.StringData(copy1.String()))
assert.True(t, (*byte)(unsafe.StringData(copy1.String())) == unsafe.StringData(copy2.String()))
assert.True(t, buffer.Update(0, 'g'))
assert.False(t, buffer.Update(-1, 'g'))
assert.False(t, buffer.Update(4, 'g'))
assert.True(t, reflect.DeepEqual([]byte{'g', 'b', 'c', 'd'}, buffer.data))
assert.True(t, reflect.DeepEqual([]byte{'a', 'b', 'c', 'd'}, copy1.data))
assert.True(t, reflect.DeepEqual([]byte{'a', 'b', 'c', 'd'}, copy2.data))
assert.NotEqual(t, unsafe.SliceData(buffer.data), unsafe.SliceData(copy1.data))
assert.Equal(t, unsafe.SliceData(copy1.data), unsafe.SliceData(copy2.data))
copy1.Close()
previous := copy2.data
copy2.Update(0, 'f')
current := copy2.data
// 1 reference - don't need to copy buffer during update
assert.Equal(t, unsafe.SliceData(previous), unsafe.SliceData(current))
copy2.Close()
}

View File

@ -0,0 +1,226 @@
package main
import (
"math"
"testing"
"unsafe"
"github.com/stretchr/testify/assert"
)
type Option func(*GamePerson)
func WithName(name string) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithCoordinates(x, y, z int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithGold(gold int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithMana(mana int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithHealth(health int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithRespect(respect int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithStrength(strength int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithExperience(experience int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithLevel(level int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithHouse() func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithGun() func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithFamily() func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
func WithType(personType int) func(*GamePerson) {
return func(person *GamePerson) {
// need to implement
}
}
const (
BuilderGamePersonType = iota
BlacksmithGamePersonType
WarriorGamePersonType
)
type GamePerson struct {
// need to implement
}
func NewGamePerson(options ...Option) GamePerson {
// need to implement
return GamePerson{}
}
func (p *GamePerson) Name() string {
// need to implement
return ""
}
func (p *GamePerson) X() int {
// need to implement
return 0
}
func (p *GamePerson) Y() int {
// need to implement
return 0
}
func (p *GamePerson) Z() int {
// need to implement
return 0
}
func (p *GamePerson) Gold() int {
// need to implement
return 0
}
func (p *GamePerson) Mana() int {
// need to implement
return 0
}
func (p *GamePerson) Health() int {
// need to implement
return 0
}
func (p *GamePerson) Respect() int {
// need to implement
return 0
}
func (p *GamePerson) Strength() int {
// need to implement
return 0
}
func (p *GamePerson) Experience() int {
// need to implement
return 0
}
func (p *GamePerson) Level() int {
// need to implement
return 0
}
func (p *GamePerson) HasHouse() bool {
// need to implement
return false
}
func (p *GamePerson) HasGun() bool {
// need to implement
return false
}
func (p *GamePerson) HasFamilty() bool {
// need to implement
return false
}
func (p *GamePerson) Type() int {
// need to implement
return 0
}
func TestGamePerson(t *testing.T) {
assert.LessOrEqual(t, unsafe.Sizeof(GamePerson{}), uintptr(64))
const x, y, z = math.MinInt32, math.MaxInt32, 0
const name = "aaaaaaaaaaaaa_bbbbbbbbbbbbb_cccccccccccccc"
const personType = BuilderGamePersonType
const gold = math.MaxInt32
const mana = 1000
const health = 1000
const respect = 10
const strength = 10
const experience = 10
const level = 10
options := []Option{
WithName(name),
WithCoordinates(x, y, z),
WithGold(gold),
WithMana(mana),
WithHealth(health),
WithRespect(respect),
WithStrength(strength),
WithExperience(experience),
WithLevel(level),
WithHouse(),
WithFamily(),
WithType(personType),
}
person := NewGamePerson(options...)
assert.Equal(t, name, person.Name())
assert.Equal(t, x, person.X())
assert.Equal(t, y, person.Y())
assert.Equal(t, z, person.Z())
assert.Equal(t, gold, person.Gold())
assert.Equal(t, mana, person.Mana())
assert.Equal(t, health, person.Health())
assert.Equal(t, respect, person.Respect())
assert.Equal(t, strength, person.Strength())
assert.Equal(t, experience, person.Experience())
assert.Equal(t, level, person.Level())
assert.True(t, person.HasHouse())
assert.True(t, person.HasFamilty())
assert.False(t, person.HasGun())
assert.Equal(t, personType, person.Type())
}

View File

@ -0,0 +1,123 @@
package main
import (
"sync/atomic"
"testing"
"time"
"github.com/stretchr/testify/assert"
)
type RWMutex struct {
// need to implement
}
func (m *RWMutex) Lock() {
// need to implement
}
func (m *RWMutex) Unlock() {
// need to implement
}
func (m *RWMutex) RLock() {
// need to implement
}
func (m *RWMutex) RUnlock() {
// need to implement
}
func TestRWMutexWithWriter(t *testing.T) {
var mutex RWMutex
mutex.Lock() // writer
var mutualExlusionWithWriter atomic.Bool
mutualExlusionWithWriter.Store(true)
var mutualExlusionWithReader atomic.Bool
mutualExlusionWithReader.Store(true)
go func() {
mutex.Lock() // another writer
mutualExlusionWithWriter.Store(false)
}()
go func() {
mutex.RLock() // another reader
mutualExlusionWithReader.Store(false)
}()
time.Sleep(time.Second)
assert.True(t, mutualExlusionWithWriter.Load())
assert.True(t, mutualExlusionWithReader.Load())
}
func TestRWMutexWithReaders(t *testing.T) {
var mutex RWMutex
mutex.RLock() // reader
var mutualExlusionWithWriter atomic.Bool
mutualExlusionWithWriter.Store(true)
go func() {
mutex.Lock() // another writer
mutualExlusionWithWriter.Store(false)
}()
time.Sleep(time.Second)
assert.True(t, mutualExlusionWithWriter.Load())
}
func TestRWMutexMultipleReaders(t *testing.T) {
var mutex RWMutex
mutex.RLock() // reader
var readersCount atomic.Int32
readersCount.Add(1)
go func() {
mutex.RLock() // another reader
readersCount.Add(1)
}()
go func() {
mutex.RLock() // another reader
readersCount.Add(1)
}()
time.Sleep(time.Second)
assert.Equal(t, int32(3), readersCount.Load())
}
func TestRWMutexWithWriterPriority(t *testing.T) {
var mutex RWMutex
mutex.RLock() // reader
var mutualExlusionWithWriter atomic.Bool
mutualExlusionWithWriter.Store(true)
var readersCount atomic.Int32
readersCount.Add(1)
go func() {
mutex.Lock() // another writer is waiting for reader
mutualExlusionWithWriter.Store(false)
}()
time.Sleep(time.Second)
go func() {
mutex.RLock() // another reader is waiting for a higher priority writer
readersCount.Add(1)
}()
go func() {
mutex.RLock() // another reader is waiting for a higher priority writer
readersCount.Add(1)
}()
time.Sleep(time.Second)
assert.True(t, mutualExlusionWithWriter.Load())
assert.Equal(t, int32(1), readersCount.Load())
}