diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..797cbde --- /dev/null +++ b/.github/workflows/test.yml @@ -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 ./... diff --git a/chat.go b/chat.go index b29ab1e..c6883af 100644 --- a/chat.go +++ b/chat.go @@ -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 @@ -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 diff --git a/status_test.go b/status_test.go index 243229b..2cf656d 100644 --- a/status_test.go +++ b/status_test.go @@ -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," + 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,", + }, + { + 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,", + }, + { + 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") - } + }) } } @@ -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) if err != nil { t.Fatal(err) diff --git a/testdata/info_description_1_20_3.json b/testdata/info_description_1_20_3.json new file mode 100644 index 0000000..45d88be --- /dev/null +++ b/testdata/info_description_1_20_3.json @@ -0,0 +1,17 @@ +{ + "version": { + "name": "Paper 1.20.4", + "protocol": 765 + }, + "enforcesSecureChat": true, + "description": { + "text": "Foo", + "extra": [ + "Bar" + ] + }, + "players": { + "max": 20, + "online": 0 + } +}