Skip to content

Commit 14c0680

Browse files
authored
Add unit tests for Creatures Overview and Creature (#59)
also fix bug with determining boosted creature
1 parent d98c0cd commit 14c0680

File tree

7 files changed

+2669
-75
lines changed

7 files changed

+2669
-75
lines changed

src/TibiaCreaturesCreatureV3.go

Lines changed: 54 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,35 @@ import (
1010
"github.com/gin-gonic/gin"
1111
)
1212

13+
// Child of JSONData
14+
type Creature struct {
15+
Name string `json:"name"`
16+
Race string `json:"race"`
17+
ImageURL string `json:"image_url"`
18+
Description string `json:"description"`
19+
Behaviour string `json:"behaviour"`
20+
Hitpoints int `json:"hitpoints"`
21+
ImmuneTo []string `json:"immune"`
22+
StrongAgainst []string `json:"strong"`
23+
WeaknessAgainst []string `json:"weakness"`
24+
BeParalysed bool `json:"be_paralysed"`
25+
BeSummoned bool `json:"be_summoned"`
26+
SummonMana int `json:"summoned_mana"`
27+
BeConvinced bool `json:"be_convinced"`
28+
ConvincedMana int `json:"convinced_mana"`
29+
SeeInvisible bool `json:"see_invisible"`
30+
ExperiencePoints int `json:"experience_points"`
31+
IsLootable bool `json:"is_lootable"`
32+
LootList []string `json:"loot_list"`
33+
Featured bool `json:"featured"`
34+
}
35+
36+
// The base includes two levels: Creature and Information
37+
type CreatureResponse struct {
38+
Creature Creature `json:"creature"`
39+
Information Information `json:"information"`
40+
}
41+
1342
var (
1443
CreatureDataRegex = regexp.MustCompile(`.*;">(.*)<\/h2> <img src="(.*)"\/>.*<p>(.*)<\/p> <p>(.*)<\/p> <p>(.*)<\/p>.*`)
1544
CreatureHitpointsRegex = regexp.MustCompile(`.*have (.*) hitpoints. (.*)`)
@@ -22,43 +51,9 @@ var (
2251

2352
// TibiaCreaturesCreatureV3 func
2453
func TibiaCreaturesCreatureV3(c *gin.Context) {
25-
26-
// local strings used in this function
27-
var localDamageString = " damage"
28-
2954
// getting params from URL
3055
race := c.Param("race")
3156

32-
// Child of JSONData
33-
type Creature struct {
34-
Name string `json:"name"`
35-
Race string `json:"race"`
36-
ImageURL string `json:"image_url"`
37-
Description string `json:"description"`
38-
Behaviour string `json:"behaviour"`
39-
Hitpoints int `json:"hitpoints"`
40-
ImmuneTo []string `json:"immune"`
41-
StrongAgainst []string `json:"strong"`
42-
WeaknessAgainst []string `json:"weakness"`
43-
BeParalysed bool `json:"be_paralysed"`
44-
BeSummoned bool `json:"be_summoned"`
45-
SummonMana int `json:"summoned_mana"`
46-
BeConvinced bool `json:"be_convinced"`
47-
ConvincedMana int `json:"convinced_mana"`
48-
SeeInvisible bool `json:"see_invisible"`
49-
ExperiencePoints int `json:"experience_points"`
50-
IsLootable bool `json:"is_lootable"`
51-
LootList []string `json:"loot_list"`
52-
Featured bool `json:"featured"`
53-
}
54-
55-
//
56-
// The base includes two levels: Creature and Information
57-
type JSONData struct {
58-
Creature Creature `json:"creature"`
59-
Information Information `json:"information"`
60-
}
61-
6257
// Getting data with TibiadataHTMLDataCollectorV3
6358
TibiadataRequest.URL = "https://www.tibia.com/library/?subtopic=creatures&race=" + TibiadataQueryEscapeStringV3(race)
6459
BoxContentHTML, err := TibiadataHTMLDataCollectorV3(TibiadataRequest)
@@ -69,6 +64,16 @@ func TibiaCreaturesCreatureV3(c *gin.Context) {
6964
return
7065
}
7166

67+
jsonData := TibiaCreaturesCreatureV3Impl(race, BoxContentHTML)
68+
69+
// return jsonData
70+
TibiaDataAPIHandleSuccessResponse(c, "TibiaCreaturesCreatureV3", jsonData)
71+
}
72+
73+
func TibiaCreaturesCreatureV3Impl(race string, BoxContentHTML string) CreatureResponse {
74+
// local strings used in this function
75+
var localDamageString = " damage"
76+
7277
// Loading HTML data into ReaderHTML for goquery with NewReader
7378
ReaderHTML, err := goquery.NewDocumentFromReader(strings.NewReader(BoxContentHTML))
7479
if err != nil {
@@ -86,12 +91,21 @@ func TibiaCreaturesCreatureV3(c *gin.Context) {
8691

8792
// Preparing vars
8893
var (
89-
CreatureDescription, CreatureBehaviour string
90-
CreatureLootList, CreatureImmuneTo, CreatureStrongAgainst, CreatureWeaknessAgainst []string
91-
CreatureHitpoints, CreatureSummonedMana, CreatureConvincedMana, CreatureExperiencePoints int
92-
CreatureBeParalysed, CreatureBeSummoned, CreatureBeConvinced, CreatureSeeInvisible, CreatureIsLootable bool
94+
CreatureDescription, CreatureBehaviour string
95+
CreatureLootList, CreatureImmuneTo, CreatureStrongAgainst, CreatureWeaknessAgainst []string
96+
CreatureHitpoints, CreatureSummonedMana, CreatureConvincedMana, CreatureExperiencePoints int
97+
CreatureBeParalysed, CreatureBeSummoned, CreatureBeConvinced, CreatureSeeInvisible, CreatureIsLootable, CreatureIsBoosted bool
9398
)
9499

100+
//Find boosted creature
101+
boostedMonsterTitle, boostedCreatureFound := ReaderHTML.Find("#Monster").First().Attr("title")
102+
103+
if boostedCreatureFound {
104+
boostedCreatureRace := boostedMonsterTitle[strings.Index(boostedMonsterTitle, ": ")+2:]
105+
106+
CreatureIsBoosted = boostedCreatureRace == race
107+
}
108+
95109
// Preparing data for JSONData
96110
if len(subma1) > 0 {
97111

@@ -158,7 +172,7 @@ func TibiaCreaturesCreatureV3(c *gin.Context) {
158172

159173
//
160174
// Build the data-blob
161-
jsonData := JSONData{
175+
return CreatureResponse{
162176
Creature{
163177
Name: TibiaDataSanitizeEscapedString(subma1[0][1]),
164178
Race: race,
@@ -178,13 +192,11 @@ func TibiaCreaturesCreatureV3(c *gin.Context) {
178192
ExperiencePoints: CreatureExperiencePoints,
179193
IsLootable: CreatureIsLootable,
180194
LootList: CreatureLootList,
195+
Featured: CreatureIsBoosted,
181196
},
182197
Information{
183198
APIVersion: TibiadataAPIversion,
184199
Timestamp: TibiadataDatetimeV3(""),
185200
},
186201
}
187-
188-
// return jsonData
189-
TibiaDataAPIHandleSuccessResponse(c, "TibiaCreaturesCreatureV3", jsonData)
190202
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
package main
2+
3+
import (
4+
"io/ioutil"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestDemon(t *testing.T) {
11+
data, err := ioutil.ReadFile("../testdata/creatures/creature/demon.html")
12+
if err != nil {
13+
t.Errorf("File reading error: %s", err)
14+
return
15+
}
16+
17+
demonJson := TibiaCreaturesCreatureV3Impl("Demon", string(data))
18+
assert := assert.New(t)
19+
20+
assert.Equal("Demons", demonJson.Creature.Name)
21+
assert.Equal("Demon", demonJson.Creature.Race)
22+
assert.Equal("https://static.tibia.com/images/library/demon.gif", demonJson.Creature.ImageURL)
23+
assert.Equal("The famous knight Apoc once wrote: \"Demons are the most malevolent, powerful, and dangerous creatures in Tibia. In addition to their awesome physical strength, they can also use powerful spells, such as fireballs and fire fields. Especially dangerous is their gaze, which can produce beams of pure energy to annihilate their poor victims. Moreover, they drain mana off their victims, heal themselves and summon fire elementals as their vassals.\nFortunately, Demons usually live in the deepest dungeons near hell but sometimes they appear also on the surface. When they do, they leave a track of death and destruction behind them. Nobody has ever been able to slay even one of these entities and only very few adventurers have survived an encounter with them.\"", demonJson.Creature.Description)
24+
assert.Equal("They are immune to fire damage and cannot be paralysed. Moreover, they are strong against death, earth, energy and physical damage. On the other hand, they are weak against holy and ice damage. These creatures can neither be summoned nor convinced. In addition, they are able to sense invisible creatures.", demonJson.Creature.Behaviour)
25+
assert.Equal(8200, demonJson.Creature.Hitpoints)
26+
27+
assert.Equal(1, len(demonJson.Creature.ImmuneTo))
28+
assert.Equal("fire", demonJson.Creature.ImmuneTo[0])
29+
30+
assert.Equal(4, len(demonJson.Creature.StrongAgainst))
31+
assert.Equal("death", demonJson.Creature.StrongAgainst[0])
32+
assert.Equal("earth", demonJson.Creature.StrongAgainst[1])
33+
assert.Equal("energy", demonJson.Creature.StrongAgainst[2])
34+
assert.Equal("physical", demonJson.Creature.StrongAgainst[3])
35+
36+
assert.Equal(2, len(demonJson.Creature.WeaknessAgainst))
37+
assert.Equal("holy", demonJson.Creature.WeaknessAgainst[0])
38+
assert.Equal("ice", demonJson.Creature.WeaknessAgainst[1])
39+
40+
assert.False(demonJson.Creature.BeParalysed)
41+
assert.False(demonJson.Creature.BeSummoned)
42+
assert.Equal(0, demonJson.Creature.SummonMana)
43+
assert.False(demonJson.Creature.BeConvinced)
44+
assert.Equal(0, demonJson.Creature.ConvincedMana)
45+
assert.True(demonJson.Creature.SeeInvisible)
46+
assert.Equal(6000, demonJson.Creature.ExperiencePoints)
47+
assert.True(demonJson.Creature.IsLootable)
48+
49+
assert.Equal(13, len(demonJson.Creature.LootList))
50+
assert.Equal("assassin stars", demonJson.Creature.LootList[0])
51+
assert.Equal("ultimate health potions", demonJson.Creature.LootList[12])
52+
53+
assert.False(demonJson.Creature.Featured)
54+
}
55+
56+
func TestQuaraPredatorFeatured(t *testing.T) {
57+
data, err := ioutil.ReadFile("../testdata/creatures/creature/quara predator.html")
58+
if err != nil {
59+
t.Errorf("File reading error: %s", err)
60+
return
61+
}
62+
63+
quaraPredatorJson := TibiaCreaturesCreatureV3Impl("Quara Predator", string(data))
64+
assert := assert.New(t)
65+
66+
assert.Equal("Quara Predators", quaraPredatorJson.Creature.Name)
67+
assert.Equal("Quara Predator", quaraPredatorJson.Creature.Race)
68+
assert.Equal("https://static.tibia.com/images/library/quarapredator.gif", quaraPredatorJson.Creature.ImageURL)
69+
assert.Equal("Even more bloodthirsty than the other quara and even feared by their own kind for their murderous frenzy, Quara Predators are usually found in the first lines of a battlefield whenever the quara decide to fight their sworn enemies (which basically means all non-quara). Obviously a mixture of quara and sharks, they share the most disgusting and most lethal attributes of both. Ruthless and vicious they know no mercy and no surrender. Quara Predators are known to fight until the last spark of life leaves their bodies. Sometimes they even fight against each other after slaying all enemies in sight.On shore they are somewhat weaker, losing their speed and agility, but their huge jaws are still fatal.", quaraPredatorJson.Creature.Description)
70+
assert.Equal("They are immune to fire and ice damage. On the other hand, they are weak against earth and energy damage. These creatures can neither be summoned nor convinced. In addition, they are able to sense invisible creatures.", quaraPredatorJson.Creature.Behaviour)
71+
assert.Equal(2200, quaraPredatorJson.Creature.Hitpoints)
72+
73+
assert.Equal(2, len(quaraPredatorJson.Creature.ImmuneTo))
74+
assert.Equal("fire", quaraPredatorJson.Creature.ImmuneTo[0])
75+
assert.Equal("ice", quaraPredatorJson.Creature.ImmuneTo[1])
76+
77+
assert.Equal(0, len(quaraPredatorJson.Creature.StrongAgainst))
78+
79+
assert.Equal(2, len(quaraPredatorJson.Creature.WeaknessAgainst))
80+
assert.Equal("earth", quaraPredatorJson.Creature.WeaknessAgainst[0])
81+
assert.Equal("energy", quaraPredatorJson.Creature.WeaknessAgainst[1])
82+
83+
assert.True(quaraPredatorJson.Creature.BeParalysed)
84+
assert.False(quaraPredatorJson.Creature.BeSummoned)
85+
assert.Equal(0, quaraPredatorJson.Creature.SummonMana)
86+
assert.False(quaraPredatorJson.Creature.BeConvinced)
87+
assert.Equal(0, quaraPredatorJson.Creature.ConvincedMana)
88+
assert.True(quaraPredatorJson.Creature.SeeInvisible)
89+
assert.Equal(1600, quaraPredatorJson.Creature.ExperiencePoints)
90+
assert.True(quaraPredatorJson.Creature.IsLootable)
91+
92+
assert.Equal(2, len(quaraPredatorJson.Creature.LootList))
93+
assert.Equal("gold coins", quaraPredatorJson.Creature.LootList[0])
94+
assert.Equal("quara bones", quaraPredatorJson.Creature.LootList[1])
95+
96+
assert.True(quaraPredatorJson.Creature.Featured)
97+
}

src/TibiaCreaturesOverviewV3.go

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,27 @@ import (
1010
"github.com/gin-gonic/gin"
1111
)
1212

13+
// Child of Creatures (used for list of creatures and boosted section)
14+
type OverviewCreature struct {
15+
Name string `json:"name"`
16+
Race string `json:"race"`
17+
ImageURL string `json:"image_url"`
18+
Featured bool `json:"featured"`
19+
}
20+
21+
// Child of JSONData
22+
type CreaturesContainer struct {
23+
Boosted OverviewCreature `json:"boosted"`
24+
Creatures []OverviewCreature `json:"creature_list"`
25+
}
26+
27+
//
28+
// The base includes two levels: Creatures and Information
29+
type CreaturesOverviewResponse struct {
30+
Creatures CreaturesContainer `json:"creatures"`
31+
Information Information `json:"information"`
32+
}
33+
1334
var (
1435
BoostedCreatureNameAndRaceRegex = regexp.MustCompile(`<a.*race=(.*)".*?>(.*)</a>`)
1536
BoostedCreatureImageRegex = regexp.MustCompile(`<img[^>]+\bsrc=["']([^"']+)["']`)
@@ -18,28 +39,6 @@ var (
1839

1940
// TibiaCreaturesOverviewV3 func
2041
func TibiaCreaturesOverviewV3(c *gin.Context) {
21-
22-
// Child of Creatures (used for list of creatures and boosted section)
23-
type Creature struct {
24-
Name string `json:"name"`
25-
Race string `json:"race"`
26-
ImageURL string `json:"image_url"`
27-
Featured bool `json:"featured"`
28-
}
29-
30-
// Child of JSONData
31-
type Creatures struct {
32-
Boosted Creature `json:"boosted"`
33-
Creatures []Creature `json:"creature_list"`
34-
}
35-
36-
//
37-
// The base includes two levels: Creatures and Information
38-
type JSONData struct {
39-
Creatures Creatures `json:"creatures"`
40-
Information Information `json:"information"`
41-
}
42-
4342
// Getting data with TibiadataHTMLDataCollectorV3
4443
TibiadataRequest.URL = "https://www.tibia.com/library/?subtopic=creatures"
4544
BoxContentHTML, err := TibiadataHTMLDataCollectorV3(TibiadataRequest)
@@ -50,6 +49,13 @@ func TibiaCreaturesOverviewV3(c *gin.Context) {
5049
return
5150
}
5251

52+
jsonData := TibiaCreaturesOverviewV3Impl(BoxContentHTML)
53+
54+
// return jsonData
55+
TibiaDataAPIHandleSuccessResponse(c, "TibiaCreaturesOverviewV3", jsonData)
56+
}
57+
58+
func TibiaCreaturesOverviewV3Impl(BoxContentHTML string) CreaturesOverviewResponse {
5359
// Loading HTML data into ReaderHTML for goquery with NewReader
5460
ReaderHTML, err := goquery.NewDocumentFromReader(strings.NewReader(BoxContentHTML))
5561
if err != nil {
@@ -74,7 +80,7 @@ func TibiaCreaturesOverviewV3(c *gin.Context) {
7480
BoostedCreatureImage := subma2b[0][1]
7581

7682
// Creating empty CreaturesData var
77-
var CreaturesData []Creature
83+
var CreaturesData []OverviewCreature
7884

7985
// Running query over each div
8086
ReaderHTML.Find(".BoxContent div div").Each(func(index int, s *goquery.Selection) {
@@ -90,29 +96,26 @@ func TibiaCreaturesOverviewV3(c *gin.Context) {
9096

9197
// check if regex return length is over 0 and the match of name is over 1
9298
if len(subma1) > 0 && len(subma1[0][3]) > 1 {
93-
9499
// Adding bool to indicate features in creature_list
95100
FeaturedRace := false
96101
if subma1[0][1] == BoostedCreatureRace {
97102
FeaturedRace = true
98103
}
99104

100105
// Creating data block to return
101-
CreaturesData = append(CreaturesData, Creature{
106+
CreaturesData = append(CreaturesData, OverviewCreature{
102107
Name: TibiaDataSanitizeEscapedString(subma1[0][3]),
103108
Race: subma1[0][1],
104109
ImageURL: subma1[0][2],
105110
Featured: FeaturedRace,
106111
})
107-
108112
}
109113
})
110114

111-
//
112115
// Build the data-blob
113-
jsonData := JSONData{
114-
Creatures{
115-
Boosted: Creature{
116+
return CreaturesOverviewResponse{
117+
CreaturesContainer{
118+
Boosted: OverviewCreature{
116119
Name: BoostedCreatureName,
117120
Race: BoostedCreatureRace,
118121
ImageURL: BoostedCreatureImage,
@@ -125,7 +128,4 @@ func TibiaCreaturesOverviewV3(c *gin.Context) {
125128
Timestamp: TibiadataDatetimeV3(""),
126129
},
127130
}
128-
129-
// return jsonData
130-
TibiaDataAPIHandleSuccessResponse(c, "TibiaCreaturesOverviewV3", jsonData)
131131
}

0 commit comments

Comments
 (0)