1
0
Fork 0
golang-github-nicholas-fedo.../pkg/util/generator/generator_test.go
Daniel Baumann c0c4addb85
Adding upstream version 0.8.9.
Signed-off-by: Daniel Baumann <daniel@debian.org>
2025-05-22 10:16:14 +02:00

184 lines
5.1 KiB
Go

package generator_test
import (
"fmt"
"regexp"
"strings"
"testing"
"github.com/mattn/go-colorable"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
"github.com/onsi/gomega/gbytes"
"github.com/nicholas-fedor/shoutrrr/pkg/util/generator"
)
func TestGenerator(t *testing.T) {
gomega.RegisterFailHandler(ginkgo.Fail)
ginkgo.RunSpecs(t, "Generator Suite")
}
var (
client *generator.UserDialog
userOut *gbytes.Buffer
userIn *gbytes.Buffer
)
func mockTyped(a ...any) {
_, _ = fmt.Fprint(userOut, a...)
_, _ = fmt.Fprint(userOut, "\n")
}
func dumpBuffers() {
for _, line := range strings.Split(string(userIn.Contents()), "\n") {
_, _ = fmt.Fprint(ginkgo.GinkgoWriter, "> ", line, "\n")
}
for _, line := range strings.Split(string(userOut.Contents()), "\n") {
_, _ = fmt.Fprint(ginkgo.GinkgoWriter, "< ", line, "\n")
}
}
var _ = ginkgo.Describe("GeneratorCommon", func() {
ginkgo.BeforeEach(func() {
userOut = gbytes.NewBuffer()
userIn = gbytes.NewBuffer()
userInMono := colorable.NewNonColorable(userIn)
client = generator.NewUserDialog(
userOut,
userInMono,
map[string]string{"propKey": "propVal"},
)
})
ginkgo.It("reprompt upon invalid answers", func() {
defer dumpBuffers()
answer := make(chan string)
go func() {
answer <- client.QueryString("name:", generator.Required, "")
}()
mockTyped("")
mockTyped("Normal Human Name")
gomega.Eventually(userIn).Should(gbytes.Say(`name: `))
gomega.Eventually(userIn).Should(gbytes.Say(`field is required`))
gomega.Eventually(userIn).Should(gbytes.Say(`name: `))
gomega.Eventually(answer).Should(gomega.Receive(gomega.Equal("Normal Human Name")))
})
ginkgo.It("should accept any input when validator is nil", func() {
defer dumpBuffers()
answer := make(chan string)
go func() {
answer <- client.QueryString("name:", nil, "")
}()
mockTyped("")
gomega.Eventually(answer).Should(gomega.Receive(gomega.BeEmpty()))
})
ginkgo.It("should use predefined prop value if key is present", func() {
defer dumpBuffers()
answer := make(chan string)
go func() {
answer <- client.QueryString("name:", generator.Required, "propKey")
}()
gomega.Eventually(answer).Should(gomega.Receive(gomega.Equal("propVal")))
})
ginkgo.Describe("Query", func() {
ginkgo.It("should prompt until a valid answer is provided", func() {
defer dumpBuffers()
answer := make(chan []string)
query := "pick foo or bar:"
go func() {
answer <- client.Query(query, regexp.MustCompile("(foo|bar)"), "")
}()
mockTyped("")
mockTyped("foo")
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(userIn).Should(gbytes.Say(`invalid format`))
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(answer).Should(gomega.Receive(gomega.ContainElement("foo")))
})
})
ginkgo.Describe("QueryAll", func() {
ginkgo.It("should prompt until a valid answer is provided", func() {
defer dumpBuffers()
answer := make(chan [][]string)
query := "pick foo or bar:"
go func() {
answer <- client.QueryAll(query, regexp.MustCompile(`foo(ba[rz])`), "", -1)
}()
mockTyped("foobar foobaz")
gomega.Eventually(userIn).Should(gbytes.Say(query))
var matches [][]string
gomega.Eventually(answer).Should(gomega.Receive(&matches))
gomega.Expect(matches).To(gomega.ContainElement([]string{"foobar", "bar"}))
gomega.Expect(matches).To(gomega.ContainElement([]string{"foobaz", "baz"}))
})
})
ginkgo.Describe("QueryStringPattern", func() {
ginkgo.It("should prompt until a valid answer is provided", func() {
defer dumpBuffers()
answer := make(chan string)
query := "type of bar:"
go func() {
answer <- client.QueryStringPattern(query, regexp.MustCompile(".*bar"), "")
}()
mockTyped("foo")
mockTyped("foobar")
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(userIn).Should(gbytes.Say(`invalid format`))
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(answer).Should(gomega.Receive(gomega.Equal("foobar")))
})
})
ginkgo.Describe("QueryInt", func() {
ginkgo.It("should prompt until a valid answer is provided", func() {
defer dumpBuffers()
answer := make(chan int64)
query := "number:"
go func() {
answer <- client.QueryInt(query, "", 64)
}()
mockTyped("x")
mockTyped("0x20")
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(userIn).Should(gbytes.Say(`not a number`))
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(answer).Should(gomega.Receive(gomega.Equal(int64(32))))
})
})
ginkgo.Describe("QueryBool", func() {
ginkgo.It("should prompt until a valid answer is provided", func() {
defer dumpBuffers()
answer := make(chan bool)
query := "cool?"
go func() {
answer <- client.QueryBool(query, "")
}()
mockTyped("maybe")
mockTyped("y")
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(userIn).Should(gbytes.Say(`answer must be yes or no`))
gomega.Eventually(userIn).Should(gbytes.Say(query))
gomega.Eventually(answer).Should(gomega.Receive(gomega.BeTrue()))
})
})
})