Git Product home page Git Product logo

Comments (13)

martinhelmer avatar martinhelmer commented on September 24, 2024 1

roger that. tests look like this atm:
image

from iris.

initial-mockingbird avatar initial-mockingbird commented on September 24, 2024

Maybe generalizing the Yes/No questions into multiple options via:

data MultipleChoicePrompt a = MultipleChoicePrompt
    { promptMessage :: ByteString -- ^ The prompted message
    , promptOptions :: NonEmpty (MultipleChoiceOption a) -- ^ each option
    }

And packing each option with a way to parse it:

data MultipleChoiceOption a = MultipleChoiceOption
    { displayName   :: ByteString 
    , parsingFun    :: ByteString -> Maybe a
    }

Would allow to write a function that prints the prompt (via Iris.Colour.Formatting.putStdoutColouredLn), reads the input, and return the first parse success

multipleChoiceQuestion
    ::  ( MonadIO m
        , MonadReader (CliEnv cmd appEnv) m
        )
    => MultipleChoicePrompt a
    -> m (Maybe a)

Since colourista isn'tyet in GHC 9.2, we can maybe use ansi-terminal to color things up, or straight up use Ansi Escape codes as a temp meassure. i.e:

-- | Resets colors back to normal
reset :: ByteString -> ByteString
reset s = s <> "\ESC[0m"

boldGreenText :: ByteString -> ByteString
boldGreenText s = "\ESC[1;38;5;82m" <> s <> reset

Finally, maybe this would be a good candidate for the IO module mentioned in Issue#14

from iris.

chshersh avatar chshersh commented on September 24, 2024

@initial-mockingbird This is a bit more nuanced. I imagine, I'm going to implement colouring entirely from scratch in Iris and I haven't figured the proper design yet.

Another disadvantage of colourista is that it doesn't support disabling colours in pure functions. I'd love to be able to describe how to format pure values of type Text without the need to run them in IO and writing the formatting twice and getting the colour disable based on CLI options.

I have a sketch of the final design but haven't got time to implement it. I've created the following issue to track the implementation of colouring separately:

As for the multiple choice questions. I believe the design for them will be more complicated than for Yes/No. So it can be implemented separately. Feel free to open a separate issue for Multiple-Choice questions and propose your implementation design there 🙂

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

I'd like to take crack at this. This will be my first contribution ever to a project, so yay!
I think i understand what's supposed to be done. Just one question: for getting the actual interactive input, just use Data.Text.IO.getLine ?

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

also, predicting other types of questions (such as multiplechoice) , maybe yesnoquestion or simplequestion would be a more appropriate name ?

from iris.

chshersh avatar chshersh commented on September 24, 2024

Hey @martinhelmer 👋🏻

Happy to see your passion for contribution 🤗

Answering your questions,

for getting the actual interactive input, just use Data.Text.IO.getLine ?

Yes, you can use this function 👍🏻

also, predicting other types of questions (such as multiplechoice) , maybe yesnoquestion or simplequestion would be a more appropriate name ?

Good point. I envision only two types of questions: (1) Yes-No and (2) Multiple Choice. In that case, let's name the function just yesno, and the multiple choice one will be called just choice.

I've updated the issue description accordingly.

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

👍 pls update the usage example as well

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

also, if yesno has the use of getLine hard-coded it will be hard to write a test, no?
either we use

yesno :: (MonadIO m, MonadReader (CliEnv cmd appEnv) m)
    => Text  -- ^ Question
    -> Answer  -- ^ Default answer when --no-input is provided
    -> m Answer  -- ^ Resulting answer
yesno = yesno' TIO.getLine  


yesno' :: (MonadIO m, MonadReader (CliEnv cmd appEnv) m)
    => IO Text -- ^ Actual answer as text 
    -> Text  -- ^ Question
    -> Answer  -- ^ Default answer when --no-input is provided
    -> m Answer  -- ^ Resulting answer
yesno' = undefined 

and test on yesno`

or, provide the (IO Text) function through the appEnv, (default TIO.getLine ) , setting it to something different in the tests.

or maybe there's a 3rd option I don't see?

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

furthermore: what if the answer is not parseable

  1. use default
  2. keep asking until we encounter something parseable
    ?

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

regarding how to test, suggest adding

data CliEnv (cmd :: Type) (appEnv :: Type) = CliEnv
    { ...
    , cliEnvInteractiveInputHandle :: Handle
    -- ^ @since x.x.x.x
    }

which defaults to stdin and can be set to fileinput by a test, or by future functionality which reads the interactive answers from file.

from iris.

chshersh avatar chshersh commented on September 24, 2024

@martinhelmer

what if the answer is not parseable

I suggest keeping asking in a loop. In the future, a more sophisticated and configurable approach can be implemented but from my experience, this is a good default.

if yesno has the use of getLine hard-coded it will be hard to write a test, no?

The best way to solve this problem is to test only relevant things. Mocks here won't help us test what we want and instead will make the code more complicated. If we have the function parseYesNo :: Text -> Maybe YesNo then it makes sense to test it. There's no benefit in testing a function that reads Text from stdin and calls parseYesNo on the result.

+1 pls update the usage example as well

After giving a consideration, I decided to rename the data type from Answer to YesNo (and changed all the functions accordingly). I believe it makes the API more consistent, self-explainable, and self-discoverable.

from iris.

martinhelmer avatar martinhelmer commented on September 24, 2024

is there anything left to do on this or can it be closed?

from iris.

chshersh avatar chshersh commented on September 24, 2024

@martinhelmer Indeed, this can be closed 🆗

I usually put a line like the following one at the beginning of the PR description to automatically close the issue on the PR merge:

Resolves #9

It's specified in the PR template but looks like it was edited away in #117. I forgot to check whether this line was specified or not when merged, so the issue didn't close automatically 🤖

from iris.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.