package main
import (
"fmt"
"io/ioutil"
"log"
"strings"
"gopkg.in/yaml.v2"
"github.com/DanielOaks/girc-go/ircmatch"
"github.com/DanielOaks/girc-go/ircmsg"
"github.com/DanielOaks/girc-go/ircutils"
"github.com/docopt/docopt-go"
)
type MsgSplitTests struct {
Tests []struct {
Input string
Atoms struct {
Source *string
Verb string
Params []string
Tags map[string]interface{}
}
}
}
type MsgJoinTests struct {
Tests []struct {
Atoms struct {
Source string
Verb string
Params []string
Tags map[string]interface{}
}
Matches []string
}
}
type MaskMatchTests struct {
Tests []struct {
Mask string
Matches []string
Fails []string
}
}
type MaskSplitTests struct {
Tests []struct {
Source string
Atoms struct {
Nick string
User string
Host string
}
}
}
type ValidateHostnameTests struct {
Tests []struct {
Host string
Valid bool
}
}
func main() {
version := "irc-parser-tests 0.1.0"
usage := `irc-parser-tests Go script.
Usage:
test.go run
test.go -h | --help
test.go --version
Options:
-h --help Show this screen.
--version Show version.`
arguments, _ := docopt.Parse(usage, nil, true, version, false)
if arguments["run"].(bool) {
var passed int
var failed int
fmt.Println("Running split tests")
passed = 0
failed = 0
data, err := ioutil.ReadFile("tests/msg-split.yaml")
if err != nil {
log.Fatal("Could not open test file msg-split.yaml:", err.Error())
}
var msgSplitTests *MsgSplitTests
err = yaml.Unmarshal(data, &msgSplitTests)
if err != nil {
log.Fatal("Could not unmarshal msg-split.yaml test file:", err.Error())
}
for _, test := range msgSplitTests.Tests {
msg, err := ircmsg.ParseLine(test.Input)
if err != nil {
log.Fatal(
"msg-split: Test failed to parse: ",
test.Input,
)
}
if msg.Command != strings.ToUpper(test.Atoms.Verb) {
fmt.Println(
"msg.Command != test.Verb: expected",
test.Atoms.Verb,
"got",
msg.Command,
)
failed++
continue
}
if len(msg.Params) != len(test.Atoms.Params) {
fmt.Println(
"len(msg.Params) != len(test.Params): expected",
len(test.Atoms.Params),
"got",
len(msg.Params),
)
failed++
continue
}
for i, data := range test.Atoms.Params {
if msg.Params[i] != data {
fmt.Println(
"msg.Params != test.Params: expected",
test.Atoms.Params,
"got",
msg.Params,
)
failed++
continue
}
}
if test.Atoms.Source != nil && *test.Atoms.Source != msg.Prefix {
fmt.Println(
"msg.Prefix != test.Source: expected",
*test.Atoms.Source,
"got",
msg.Prefix,
)
failed++
continue
}
for name, value := range test.Atoms.Tags {
tag, exists := msg.Tags[name]
if !exists {
fmt.Println(
"Expected tag",
name,
"but does not exist",
)
failed++
continue
}
if value == nil {
if tag.HasValue {
fmt.Println(
"Tag",
name,
"is not supposed to have value, but does!",
)
failed++
continue
}
} else {
if !tag.HasValue {
fmt.Println(
"Tag",
name,
"is supposed to have value, but doesn't!",
)
failed++
continue
}
if tag.Value != value {
fmt.Println(
"Tag",
name,
"has wrong value. Expected",
value,
"got",
tag.Value,
)
failed++
continue
}
}
}
passed++
}
fmt.Println(" * Passed tests:", passed)
fmt.Println(" * Failed tests:", failed)
fmt.Println("Running join tests")
passed = 0
failed = 0
data, err = ioutil.ReadFile("tests/msg-join.yaml")
if err != nil {
log.Fatal("Could not open test file msg-join.yaml:", err.Error())
}
var msgJoinTests *MsgJoinTests
err = yaml.Unmarshal(data, &msgJoinTests)
if err != nil {
log.Fatal("Could not unmarshal msg-join.yaml test file:", err.Error())
}
for _, test := range msgJoinTests.Tests {
var tags *map[string]ircmsg.TagValue
if test.Atoms.Tags != nil {
tagsDict := make(map[string]ircmsg.TagValue)
for key, value := range test.Atoms.Tags {
if value == nil {
tagsDict[key] = ircmsg.NoTagValue()
} else {
tagsDict[key] = ircmsg.MakeTagValue(value.(string))
}
}
tags = &tagsDict
}
msg := ircmsg.MakeMessage(tags, test.Atoms.Source, test.Atoms.Verb, test.Atoms.Params...)
line, err := msg.Line()
if err != nil {
log.Fatal(
"msg-join: Test failed to parse: ",
err.Error(),
)
}
var hasPassed bool
for _, test := range test.Matches {
if strings.TrimRight(line, "\r\n") == test {
hasPassed = true
}
}
if hasPassed {
passed++
} else {
failed++
}
}
fmt.Println(" * Passed tests:", passed)
fmt.Println(" * Failed tests:", failed)
fmt.Println("Running mask matching tests")
passed = 0
failed = 0
data, err = ioutil.ReadFile("tests/mask-match.yaml")
if err != nil {
log.Fatal("Could not open test file mask-match.yaml:", err.Error())
}
var maskMatchTests *MaskMatchTests
err = yaml.Unmarshal(data, &maskMatchTests)
if err != nil {
log.Fatal("Could not unmarshal mask-match.yaml test file:", err.Error())
}
for _, test := range maskMatchTests.Tests {
mask := ircmatch.MakeMatch(test.Mask)
var testfailed bool
for _, matchString := range test.Matches {
if !mask.Match(matchString) {
fmt.Println(fmt.Sprintf("Expected mask [%s] to match input [%s] but it did not.", test.Mask, matchString))
testfailed = true
}
}
for _, matchString := range test.Fails {
if mask.Match(matchString) {
fmt.Println(fmt.Sprintf("Did not expect mask [%s] to match input [%s] but it did.", test.Mask, matchString))
testfailed = true
}
}
if testfailed {
failed++
} else {
passed++
}
}
fmt.Println(" * Passed tests:", passed)
fmt.Println(" * Failed tests:", failed)
fmt.Println("Running userhost splitting tests")
passed = 0
failed = 0
data, err = ioutil.ReadFile("tests/userhost-split.yaml")
if err != nil {
log.Fatal("Could not open test file userhost-split.yaml:", err.Error())
}
var maskSplitTests *MaskSplitTests
err = yaml.Unmarshal(data, &maskSplitTests)
if err != nil {
log.Fatal("Could not unmarshal userhost-split.yaml test file:", err.Error())
}
for _, test := range maskSplitTests.Tests {
uh := ircutils.ParseUserhost(test.Source)
var testfailed bool
if uh.Nick != test.Atoms.Nick {
fmt.Println(fmt.Sprintf("Expected nick from userhost [%s] to match test [%s] but it was [%s].", test.Source, test.Atoms.Nick, uh.Nick))
testfailed = true
}
if uh.User != test.Atoms.User {
fmt.Println(fmt.Sprintf("Expected user from userhost [%s] to match test [%s] but it was [%s].", test.Source, test.Atoms.User, uh.User))
testfailed = true
}
if uh.Host != test.Atoms.Host {
fmt.Println(fmt.Sprintf("Expected host from userhost [%s] to match test [%s] but it was [%s].", test.Source, test.Atoms.Host, uh.Host))
testfailed = true
}
if testfailed {
failed++
} else {
passed++
}
}
fmt.Println(" * Passed tests:", passed)
fmt.Println(" * Failed tests:", failed)
fmt.Println("Running hostname validation tests")
passed = 0
failed = 0
data, err = ioutil.ReadFile("tests/validate-hostname.yaml")
if err != nil {
log.Fatal("Could not open test file validate-hostname.yaml:", err.Error())
}
var validateHostnameTests *ValidateHostnameTests
err = yaml.Unmarshal(data, &validateHostnameTests)
if err != nil {
log.Fatal("Could not unmarshal validate-hostname.yaml test file:", err.Error())
}
for _, test := range validateHostnameTests.Tests {
isValid := ircutils.HostnameIsValid(test.Host)
if isValid == test.Valid {
passed++
} else if isValid {
fmt.Println(fmt.Sprintf("Expected host [%s] to fail validation but it passed.", test.Host))
failed++
} else {
fmt.Println(fmt.Sprintf("Expected host [%s] to pass validation but it failed.", test.Host))
failed++
}
}
fmt.Println(" * Passed tests:", passed)
fmt.Println(" * Failed tests:", failed)
}
}