manifoldco / promptui

Interactive prompt for command-line applications

Home Page:https://www.manifold.co

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

UnitTesting: validation gets called one char at the time - reading from stdin?

JCzz opened this issue · comments

commented

Hi

I have the following test code:


package std

import (
	"fmt"
	"io/ioutil"
	"os"
	"testing"
)

func TestSetEmail(t *testing.T) {
	if err := _TestExpectedStdinFunc("email@test.com", setEmail); err != nil {
		t.Error(err)
		return
	}
	fmt.Println("success")
}

func _TestExpectedStdinFunc(expected string, f func() string) error {
	content := []byte(expected)
	tmpfile, err := ioutil.TempFile("", "example")
	if err != nil {
		return err
	}	defer os.Remove(tmpfile.Name()) // clean up

	if _, err := tmpfile.Write(content); err != nil {
		return err
	}
	if _, err := tmpfile.Seek(0, 0); err != nil {
		return err
	}

	oldStdin := os.Stdin
	defer func() { os.Stdin = oldStdin }()

	os.Stdin = tmpfile
	actual := f()
	if actual != expected {
		return fmt.Errorf("test failed, exptected: %s actual: %s", expected, actual)
	}

	if err := tmpfile.Close(); err != nil {
		return err
	}
	return nil
}


The problem is that Promptui validation in setEmail(beneath code) gets called one char at the time giving this:


✗ Input your Email: █
 �e �
✗ Input your Email: e█
e �
� �m �
✗ Input your Email: em█
m �
� �a �
✗ Input your Email: ema█
a �
� �i �
✗ Input your Email: emai█
i �
� �l �
✗ Input your Email: email█
l �
� �@ �
✗ Input your Email: email@█
@ �
� �t �
✗ Input your Email: email@t█
t �
� �e �
✗ Input your Email: email@te█
e �
� �s �
✗ Input your Email: email@tes█
s �
� �t �
✗ Input your Email: email@test█
t �
� �. �
✗ Input your Email: email@test.█
. �
� �c �
✗ Input your Email: email@test.c█
c �
� �o �
✗ Input your Email: email@test.co█
o �
� �m �
✗ Input your Email: email@test.com█

Code:
Note: printStdin func is just to verify stdin has values, and therefore commented out(//)

package mypackage

import (
	"bufio"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strconv"

	"github.com/manifoldco/promptui"
)

func setEmail() string {
	emailValidations := func(input string) error {
		_, err := strconv.ParseFloat(input, 64)
		if err != nil {
			return errors.New("Invalid number")
		}
		return nil
	}

	// stdin := os.Stdin
	rc := ioutil.NopCloser(bufio.NewReader(os.Stdin))
	// printStdin(os.Stdin)

	prompt := promptui.Prompt{
		Label:    "Input your Email",
		Validate: emailValidations,
		Stdin:    rc, // stdin
	}

	email, err := prompt.Run()
	if err != nil {
		fmt.Println("failed getting email")
		// os.exit(3)
	}
	return email
}

func printStdin(file *os.File) {

	fi, err := file.Stat()
	if err != nil {
		fmt.Println("file.Stat()", err)
	}

	size := fi.Size()
	if size > 0 {
		fmt.Printf("%v bytes available in Stdin\n", size)
	} else {
		fmt.Println("Stdin is empty")
	}

	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
	if err := scanner.Err(); err != nil {
		log.Fatal(err)
	}
}

How did you fix it?