Skip to content

Commit fb96d60

Browse files
authored
Merge pull request #206 from markus-wa/improve-codecov
v2: unit tests and cleanup
2 parents d967d90 + a67432a commit fb96d60

File tree

13 files changed

+350
-31
lines changed

13 files changed

+350
-31
lines changed

pkg/demoinfocs/common/common_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ func entityWithProperty(propName string, value st.PropertyValue) *stfake.Entity
188188
prop.On("Value").Return(value)
189189

190190
entity.On("Property", propName).Return(prop)
191-
entity.On("PropertyValue", propName).Return(prop, true)
191+
entity.On("PropertyValue", propName).Return(value, true)
192192
entity.On("PropertyValueMust", propName).Return(value)
193193

194194
return entity
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package common
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestGetFloat_Nil(t *testing.T) {
10+
assert.Zero(t, getFloat(nil, "test"))
11+
}
12+
13+
func TestGetInt_Nil(t *testing.T) {
14+
assert.Zero(t, getInt(nil, "test"))
15+
}
16+
17+
func TestGetString_Nil(t *testing.T) {
18+
assert.Empty(t, getString(nil, "test"))
19+
}
20+
21+
func TestGetBool_Nil(t *testing.T) {
22+
assert.Empty(t, getBool(nil, "test"))
23+
}

pkg/demoinfocs/common/equipment.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,9 +273,9 @@ func MapEquipment(eqName string) EquipmentType {
273273
type ZoomLevel int
274274

275275
const (
276-
ZoomNone = 0
277-
ZoomHalf = 1
278-
ZoomFull = 2
276+
ZoomNone ZoomLevel = 0
277+
ZoomHalf ZoomLevel = 1
278+
ZoomFull ZoomLevel = 2
279279
)
280280

281281
// Equipment is a weapon / piece of equipment belonging to a player.
@@ -315,12 +315,17 @@ func (e Equipment) AmmoInMagazine() int {
315315
return 1
316316
}
317317

318+
if e.Entity == nil {
319+
return 0
320+
}
321+
318322
val, ok := e.Entity.PropertyValue("m_iClip1")
319323
if !ok {
320324
return -1
321325
}
322326

323-
return val.IntVal
327+
// need to subtract 1 as m_iClip1 is nrOfBullets + 1
328+
return val.IntVal - 1
324329
}
325330

326331
// AmmoType returns the weapon's ammo type, mostly (only?) relevant for grenades.
@@ -354,6 +359,10 @@ func (e Equipment) AmmoReserve() int {
354359
return 0
355360
}
356361

362+
if e.Entity == nil {
363+
return 0
364+
}
365+
357366
// if the property doesn't exist we return 0 by default
358367
val, _ := e.Entity.PropertyValue("m_iPrimaryReserveAmmoCount")
359368

pkg/demoinfocs/common/equipment_test.go

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,29 @@ func TestEquipment_UniqueID(t *testing.T) {
3838
assert.NotEqual(t, NewEquipment(EqAK47).UniqueID(), NewEquipment(EqAK47).UniqueID(), "UniqueIDs of different equipment instances should be different")
3939
}
4040

41+
func TestEquipment_AmmoInMagazine(t *testing.T) {
42+
wep := &Equipment{
43+
Type: EqAK47,
44+
Entity: entityWithProperty("m_iClip1", st.PropertyValue{IntVal: 31}),
45+
}
46+
47+
// returned value should be minus 1, m_iClip1 is always 1 more than the actual number of bullets
48+
assert.Equal(t, 30, wep.AmmoInMagazine())
49+
}
50+
51+
func TestEquipment_AmmoInMagazine_NotFound(t *testing.T) {
52+
entity := entityWithID(1)
53+
entity.On("PropertyValue", "m_iClip1").Return(st.PropertyValue{}, false)
54+
55+
wep := &Equipment{
56+
Type: EqAK47,
57+
Entity: entity,
58+
}
59+
60+
// returned value should be minus 1, m_iClip1 is always 1 more than the actual number of bullets
61+
assert.Equal(t, -1, wep.AmmoInMagazine())
62+
}
63+
4164
func TestEquipment_AmmoInMagazine_Grenade(t *testing.T) {
4265
wep := &Equipment{
4366
Type: EqFlash,
@@ -46,6 +69,24 @@ func TestEquipment_AmmoInMagazine_Grenade(t *testing.T) {
4669
assert.Equal(t, 1, wep.AmmoInMagazine())
4770
}
4871

72+
func TestEquipment_AmmoInMagazine_EntityNil(t *testing.T) {
73+
wep := &Equipment{
74+
Type: EqAK47,
75+
}
76+
77+
assert.Equal(t, 0, wep.AmmoInMagazine())
78+
}
79+
80+
func TestEquipment_AmmoReserve(t *testing.T) {
81+
entity := entityWithProperty("m_iPrimaryReserveAmmoCount", st.PropertyValue{IntVal: 60})
82+
wep := &Equipment{
83+
Type: EqAK47,
84+
Entity: entity,
85+
}
86+
87+
assert.Equal(t, 60, wep.AmmoReserve())
88+
}
89+
4990
func TestEquipment_AmmoReserve_Grenade(t *testing.T) {
5091
owner := new(Player)
5192
owner.AmmoLeft[1] = 2
@@ -60,14 +101,39 @@ func TestEquipment_AmmoReserve_Grenade(t *testing.T) {
60101
assert.Equal(t, 1, wep.AmmoReserve())
61102
}
62103

63-
func TestEquipment_AmmoReserve2_Grenade_OwnerNil(t *testing.T) {
104+
func TestEquipment_AmmoReserve_Grenade_OwnerNil(t *testing.T) {
64105
wep := &Equipment{
65106
Type: EqFlash,
66107
}
67108

68109
assert.Equal(t, 0, wep.AmmoReserve())
69110
}
70111

112+
func TestEquipment_AmmoReserve_EntityNil(t *testing.T) {
113+
wep := &Equipment{
114+
Type: EqAK47,
115+
}
116+
117+
assert.Equal(t, 0, wep.AmmoReserve())
118+
}
119+
120+
func TestEquipment_ZoomLevel(t *testing.T) {
121+
wep := &Equipment{
122+
Type: EqAK47,
123+
Entity: entityWithProperty("m_zoomLevel", st.PropertyValue{IntVal: 2}),
124+
}
125+
126+
assert.Equal(t, ZoomFull, wep.ZoomLevel())
127+
}
128+
129+
func TestEquipment_ZoomLevel_EntityNil(t *testing.T) {
130+
wep := &Equipment{
131+
Type: EqAK47,
132+
}
133+
134+
assert.Equal(t, ZoomLevel(0), wep.ZoomLevel())
135+
}
136+
71137
func TestEquipmentAlternative(t *testing.T) {
72138
assert.Equal(t, EqUSP, EquipmentAlternative(EqP2000))
73139
assert.Equal(t, EqCZ, EquipmentAlternative(EqP250))

pkg/demoinfocs/common/player.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -278,9 +278,9 @@ func (p *Player) Velocity() r3.Vector {
278278
}
279279

280280
return r3.Vector{
281-
X: p.Entity.PropertyValueMust("localdata.m_vecVelocity[0]").Float64Val(),
282-
Y: p.Entity.PropertyValueMust("localdata.m_vecVelocity[1]").Float64Val(),
283-
Z: p.Entity.PropertyValueMust("localdata.m_vecVelocity[2]").Float64Val(),
281+
X: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[0]").FloatVal),
282+
Y: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[1]").FloatVal),
283+
Z: float64(p.Entity.PropertyValueMust("localdata.m_vecVelocity[2]").FloatVal),
284284
}
285285
}
286286

pkg/demoinfocs/common/player_test.go

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import (
44
"testing"
55
"time"
66

7+
"github.com/golang/geo/r3"
78
"github.com/stretchr/testify/assert"
89

910
st "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/sendtables"
11+
stfake "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/sendtables/fake"
1012
)
1113

1214
func TestPlayerActiveWeapon(t *testing.T) {
@@ -206,6 +208,36 @@ func TestPlayer_IsAirborne(t *testing.T) {
206208
assert.True(t, pl.IsAirborne())
207209
}
208210

211+
func TestPlayer_IsDucking(t *testing.T) {
212+
pl := playerWithProperty("localdata.m_Local.m_bDucking", st.PropertyValue{IntVal: 0})
213+
214+
assert.False(t, pl.IsDucking())
215+
216+
pl = playerWithProperty("localdata.m_Local.m_bDucking", st.PropertyValue{IntVal: 1})
217+
218+
assert.True(t, pl.IsDucking())
219+
}
220+
221+
func TestPlayer_HasDefuseKit(t *testing.T) {
222+
pl := playerWithProperty("m_bHasDefuser", st.PropertyValue{IntVal: 0})
223+
224+
assert.False(t, pl.HasDefuseKit())
225+
226+
pl = playerWithProperty("m_bHasDefuser", st.PropertyValue{IntVal: 1})
227+
228+
assert.True(t, pl.HasDefuseKit())
229+
}
230+
231+
func TestPlayer_HasHelmet(t *testing.T) {
232+
pl := playerWithProperty("m_bHasHelmet", st.PropertyValue{IntVal: 0})
233+
234+
assert.False(t, pl.HasHelmet())
235+
236+
pl = playerWithProperty("m_bHasHelmet", st.PropertyValue{IntVal: 1})
237+
238+
assert.True(t, pl.HasHelmet())
239+
}
240+
209241
func TestPlayer_IsControllingBot_NilEntity(t *testing.T) {
210242
pl := new(Player)
211243

@@ -250,6 +282,107 @@ func TestPlayer_ControlledBot(t *testing.T) {
250282
assert.Same(t, dave, pl.ControlledBot())
251283
}
252284

285+
func TestPlayer_Armor(t *testing.T) {
286+
pl := playerWithProperty("m_ArmorValue", st.PropertyValue{IntVal: 95})
287+
288+
assert.Equal(t, 95, pl.Armor())
289+
}
290+
291+
func TestPlayer_Money(t *testing.T) {
292+
pl := playerWithProperty("m_iAccount", st.PropertyValue{IntVal: 800})
293+
294+
assert.Equal(t, 800, pl.Money())
295+
}
296+
297+
func TestPlayer_ViewDirectionX(t *testing.T) {
298+
pl := playerWithProperty("m_angEyeAngles[1]", st.PropertyValue{FloatVal: 180})
299+
300+
assert.Equal(t, float32(180), pl.ViewDirectionX())
301+
}
302+
303+
func TestPlayer_ViewDirectionY(t *testing.T) {
304+
pl := playerWithProperty("m_angEyeAngles[0]", st.PropertyValue{FloatVal: 15})
305+
306+
assert.Equal(t, float32(15), pl.ViewDirectionY())
307+
}
308+
309+
func TestPlayer_Position(t *testing.T) {
310+
entity := new(stfake.Entity)
311+
pos := r3.Vector{X: 1, Y: 2, Z: 3}
312+
313+
entity.On("Position").Return(pos)
314+
315+
pl := &Player{Entity: entity}
316+
317+
assert.Equal(t, pos, pl.Position())
318+
}
319+
320+
func TestPlayer_Position_EntityNil(t *testing.T) {
321+
pl := new(Player)
322+
323+
assert.Empty(t, pl.Position())
324+
}
325+
326+
func TestPlayer_Velocity(t *testing.T) {
327+
entity := new(stfake.Entity)
328+
entity.On("PropertyValueMust", "localdata.m_vecVelocity[0]").Return(st.PropertyValue{FloatVal: 1})
329+
entity.On("PropertyValueMust", "localdata.m_vecVelocity[1]").Return(st.PropertyValue{FloatVal: 2})
330+
entity.On("PropertyValueMust", "localdata.m_vecVelocity[2]").Return(st.PropertyValue{FloatVal: 3})
331+
332+
pl := &Player{Entity: entity}
333+
334+
expected := r3.Vector{X: 1, Y: 2, Z: 3}
335+
assert.Equal(t, expected, pl.Velocity())
336+
}
337+
338+
func TestPlayer_Velocity_EntityNil(t *testing.T) {
339+
pl := new(Player)
340+
341+
assert.Empty(t, pl.Velocity())
342+
}
343+
344+
func TestPlayer_ClanTag(t *testing.T) {
345+
pl := playerWithResourceProperty("m_szClan", st.PropertyValue{StringVal: "SuperClan"})
346+
347+
assert.Equal(t, "SuperClan", pl.ClanTag())
348+
}
349+
350+
func TestPlayer_Ping(t *testing.T) {
351+
pl := playerWithResourceProperty("m_iPing", st.PropertyValue{IntVal: 45})
352+
353+
assert.Equal(t, 45, pl.Ping())
354+
}
355+
356+
func TestPlayer_Score(t *testing.T) {
357+
pl := playerWithResourceProperty("m_iScore", st.PropertyValue{IntVal: 10})
358+
359+
assert.Equal(t, 10, pl.Score())
360+
}
361+
362+
func TestPlayer_Kills(t *testing.T) {
363+
pl := playerWithResourceProperty("m_iKills", st.PropertyValue{IntVal: 5})
364+
365+
assert.Equal(t, 5, pl.Kills())
366+
}
367+
368+
func TestPlayer_Deaths(t *testing.T) {
369+
pl := playerWithResourceProperty("m_iDeaths", st.PropertyValue{IntVal: 2})
370+
371+
assert.Equal(t, 2, pl.Deaths())
372+
}
373+
374+
func TestPlayer_Assists(t *testing.T) {
375+
pl := playerWithResourceProperty("m_iAssists", st.PropertyValue{IntVal: 3})
376+
377+
assert.Equal(t, 3, pl.Assists())
378+
}
379+
380+
func TestPlayer_MVPs(t *testing.T) {
381+
pl := playerWithResourceProperty("m_iMVPs", st.PropertyValue{IntVal: 4})
382+
383+
assert.Equal(t, 4, pl.MVPs())
384+
}
385+
253386
func TestPlayer_SteamID32(t *testing.T) {
254387
pl := &Player{SteamID64: 76561198012952267}
255388

@@ -263,3 +396,12 @@ func newPlayer(tick int) *Player {
263396
func playerWithProperty(propName string, value st.PropertyValue) *Player {
264397
return &Player{Entity: entityWithProperty(propName, value)}
265398
}
399+
400+
func playerWithResourceProperty(propName string, value st.PropertyValue) *Player {
401+
return &Player{
402+
EntityID: 1,
403+
demoInfoProvider: demoInfoProviderMock{
404+
playerResourceEntity: entityWithProperty(propName+".001", value),
405+
},
406+
}
407+
}

pkg/demoinfocs/datatables.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ func (p *parser) infernoExpired(inf *common.Inferno) {
527527
p.gameEventHandler.deleteThrownGrenade(inf.Thrower(), common.EqIncendiary)
528528
}
529529

530+
//nolint:funlen
530531
func (p *parser) bindGameRules() {
531532
grPrefix := func(s string) string {
532533
return fmt.Sprintf("%s.%s", gameRulesPrefix, s)

pkg/demoinfocs/sendtables/entity.go

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,12 @@ func (e *entity) Properties() (out []Property) {
4242
}
4343

4444
func (e *entity) property(name string) *property {
45-
return &e.props[e.serverClass.propNameToIndex[name]]
45+
i, ok := e.serverClass.propNameToIndex[name]
46+
if !ok {
47+
return nil
48+
}
49+
50+
return &e.props[i]
4651
}
4752

4853
// Property finds a property on the entity by name.
@@ -271,16 +276,6 @@ func (e *entity) OnPositionUpdate(h func(pos r3.Vector)) {
271276
}
272277
}
273278

274-
// BindPosition binds the entity's position to a pointer variable.
275-
// The pointer is updated every time a position-relevant property is updated.
276-
//
277-
// See also OnPositionUpdate()
278-
func (e *entity) BindPosition(pos *r3.Vector) {
279-
e.OnPositionUpdate(func(newPos r3.Vector) {
280-
*pos = newPos
281-
})
282-
}
283-
284279
// Returns a coordinate from a cell + offset
285280
func coordFromCell(cell, cellWidth int, offset float64) float64 {
286281
return float64(cell*cellWidth-maxCoordInt) + offset

0 commit comments

Comments
 (0)