Skip to content

Commit

Permalink
Handle string list for extra siblings of description (#18)
Browse files Browse the repository at this point in the history
* Handle string list for extra siblings of description

* Add test case and switched to table driven test

* Added Github actions test workflow
  • Loading branch information
itzg committed Feb 7, 2024
1 parent a40c94a commit eae9fe6
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 56 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Test

on:
push:
branches: [ master ]
paths-ignore:
- README.md
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: 'go.mod'
- run: go test ./...
21 changes: 13 additions & 8 deletions chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ import (

// RegularChatComponent is a Minecraft chat component
// See: https://wiki.vg/Chat#Current_system_.28JSON_Chat.29
// and https://wiki.vg/Text_formatting#Content_fields
type RegularChatComponent struct {
Text string `json:"text"` // Text content
Bold bool `json:"bold"` // Component is emboldened
Italic bool `json:"italic"` // Component is italicized
Underlined bool `json:"underlined"` // Component is underlined
Strikethrough bool `json:"strikethrough"` // Component is struck out
Obfuscated bool `json:"obfuscated"` // Component randomly switches between characters of the same width
Color string `json:"color"` // Contains the color for the component
Extra []RegularChatComponent `json:"extra"` // RegularChatComponent siblings
Text string `json:"text"` // Text content
Bold bool `json:"bold"` // Component is emboldened
Italic bool `json:"italic"` // Component is italicized
Underlined bool `json:"underlined"` // Component is underlined
Strikethrough bool `json:"strikethrough"` // Component is struck out
Obfuscated bool `json:"obfuscated"` // Component randomly switches between characters of the same width
Color string `json:"color"` // Contains the color for the component
Extra []ChatComponent `json:"extra"` // siblings
}

// ChatComponent wraps a RegularChatComponent for parsing both regular & string-only MOTD's
Expand All @@ -26,6 +27,10 @@ type ChatComponent struct {
func (c *ChatComponent) UnmarshalJSON(data []byte) error {
var regular RegularChatComponent

// data can be
// {"text":"Foo"}
// "Bar"

// The data starts with quotes which means it's a string, not an object
if data[0] == '"' {
var text string
Expand Down
131 changes: 83 additions & 48 deletions status_test.go
Original file line number Diff line number Diff line change
@@ -1,77 +1,112 @@
package mcpinger

import (
"io/ioutil"
"os"
"path/filepath"
"testing"
)

const (
TestDataDir = "testdata" // Name of testdata directory
VersionName = "1.13.2"
Protocol = 404
Description = "Hello world"
MaxPlayers = 100
OnlinePlayers = 5
PlayerSampleCount = 1
PlayerSampleName = "Raqbit"
PlayerSampleUuid = "09bc745b-3679-4152-b96b-3f9c59c42059"
Favicon = "data:image/png;base64,<data>"
TestDataDir = "testdata" // Name of testdata directory
)

func TestParseServerInfo(t *testing.T) {
files := []string{
"info.json",
"info_description_string.json",
tests := []struct {
File string
VersionName string
Protocol int32
Description string
MaxPlayers int32
OnlinePlayers int32
PlayerSampleCount int
PlayerSampleName string
PlayerSampleUuid string
Favicon string
}{
{
File: "info.json",
VersionName: "1.13.2",
Protocol: 404,
Description: "Hello world",
MaxPlayers: 100,
OnlinePlayers: 5,
PlayerSampleCount: 1,
PlayerSampleName: "Raqbit",
PlayerSampleUuid: "09bc745b-3679-4152-b96b-3f9c59c42059",
Favicon: "data:image/png;base64,<data>",
},
{
File: "info_description_string.json",
VersionName: "1.13.2",
Protocol: 404,
Description: "Hello world",
MaxPlayers: 100,
OnlinePlayers: 5,
PlayerSampleCount: 1,
PlayerSampleName: "Raqbit",
PlayerSampleUuid: "09bc745b-3679-4152-b96b-3f9c59c42059",
Favicon: "data:image/png;base64,<data>",
},
{
File: "info_description_1_20_3.json",
VersionName: "Paper 1.20.4",
Protocol: 765,
Description: "Foo",
MaxPlayers: 20,
OnlinePlayers: 0,
},
}

for _, f := range files {
infoJson := GetTestFileContents(t, f)
for _, test := range tests {
t.Run(test.File, func(t *testing.T) {
infoJson := GetTestFileContents(t, test.File)

info, err := parseServerInfo(infoJson)
info, err := parseServerInfo(infoJson)

if err != nil {
t.Fatal(err)
}

if info.Version.Name != VersionName {
parseError(t, f, "version name")
}
if err != nil {
t.Fatal(err)
}

if info.Version.Protocol != Protocol {
parseError(t, f, "protocol version")
}
if info.Version.Name != test.VersionName {
parseError(t, test.File, "version name")
}

if info.Description.Text != Description {
parseError(t, f, "description")
if info.Version.Protocol != test.Protocol {
parseError(t, test.File, "protocol version")
}

}
if info.Description.Text != test.Description {
parseError(t, test.File, "description")

if info.Players.Max != MaxPlayers {
parseError(t, f, "max players")
}

}
if info.Players.Max != test.MaxPlayers {
parseError(t, test.File, "max players")

if info.Players.Online != OnlinePlayers {
parseError(t, f, "online players")
}
}

if len(info.Players.Sample) != PlayerSampleCount {
parseError(t, f, "player sample")
} else {
if info.Players.Sample[0].Name != PlayerSampleName {
parseError(t, f, "player sample name")
if info.Players.Online != test.OnlinePlayers {
parseError(t, test.File, "online players")
}

if info.Players.Sample[0].ID != PlayerSampleUuid {
parseError(t, f, "player sample uuid")
if len(info.Players.Sample) != test.PlayerSampleCount {
parseError(t, test.File, "player sample")
} else if test.PlayerSampleCount > 0 {
if info.Players.Sample[0].Name != test.PlayerSampleName {
parseError(t, test.File, "player sample name")
}

if info.Players.Sample[0].ID != test.PlayerSampleUuid {
parseError(t, test.File, "player sample uuid")
}

}

}
if info.Favicon != test.Favicon {
parseError(t, test.File, "favicon")
}

if info.Favicon != Favicon {
parseError(t, f, "favicon")
}
})
}
}

Expand All @@ -82,7 +117,7 @@ func parseError(t *testing.T, file string, name string) {
func GetTestFileContents(t *testing.T, name string) []byte {
path := filepath.Join(TestDataDir, name)

data, err := ioutil.ReadFile(path)
data, err := os.ReadFile(path)

Check failure on line 120 in status_test.go

View workflow job for this annotation

GitHub Actions / test

undefined: os.ReadFile

if err != nil {
t.Fatal(err)
Expand Down
17 changes: 17 additions & 0 deletions testdata/info_description_1_20_3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": {
"name": "Paper 1.20.4",
"protocol": 765
},
"enforcesSecureChat": true,
"description": {
"text": "Foo",
"extra": [
"Bar"
]
},
"players": {
"max": 20,
"online": 0
}
}

0 comments on commit eae9fe6

Please sign in to comment.