Open Odonno opened 6 days ago
@amiceli Can you review this proposition or do you agree with it?
I think we can split this in at least 2 or 3 PRs: the culture/language part and the rest.
Yes, we will split in multiple PR.
To be brief :
{boolean}
is hard to do because we need to do it for all languages, like "vrai" for french or "vero" in italien etc.{word}
it's planned, I'm OK{char}
I'm OK too, good idea{date}
It's useful but we can speak about allowed format, like 16 janvier 2024
etc what do you think ? We can start with some specific formats ?{currency}
It's planned too, it's useful. We start with $
and €
or other currencies ?{string}
and {any}
is useful, but I don't like {empty}
keyword.For {int}
, I think we can keep just {number}
and remove {float}
(I don't remember why I did that ^^).
We need to improve {numbr}
regex for it, what do you think ?
Custom expressions is planned, it's useful.
We can add it in configuration
or another global
function like addStepExpression
.
We can see a PR by expression/feature.
There are already a number of built-in parameter expressions in this package, listed in the documentation here: https://vitest-cucumber.miceli.click/features/step-expression
The proposition is to review and add new expressions to this list.
Review of existing expressions
The existing
{number}
expression is great. However, I am not really a fan of it being able to convert with symbols like$
or€
. There is a proposition in theNew expressions
section for this kind of expressions.Also, the
{list}
expression is an interesting idea. In some occasions, the list can be written using a different separator pattern. The question is, what if we can define the separator in the expression like{list:';'}
for example. So it can be used for a scenario like this one:Of course, the
{list}
expression still works, having the,
separator acting as default.New expressions
boolean
A boolean checks when a text is equal to
true
orfalse
. It will then convert the value into aboolean
type.Example:
will be triggered by
Question: should it also parse integers/numbers?
0
beingfalse
,true
otherwise.int
A particular case of
{number}
expression. Similar to{float}
but with it only being triggered by natural and non-natural integers, e.g.14
or-1
. It will then convert the value into anumber
type.Example:
will be triggered by
Question: should
{float}
be removed in favor of{number}
as the two would do the same thing?Question 2: should we also offer
{positiveInt}
or{naturalInt}
(whatever the name) to be triggered only by natural integers?word
Matches a single word without whitespace. It will then convert the value into a
string
type.Example:
will be triggered by
char
Matches a single character. It will then convert the value into a
string
type.Example:
will be triggered by
date
Expects a string to be parsed as a valid date. It will then convert the value into a
Date
type.Example:
will be triggered by
It should support the same parsing as the native
Date
js type, so basically the previous example will donew Date("2024-10-16")
.currency
Matches a currency string that have both a value and the corresponding currency symbol. Bonus point if it can handle currency unit and/or name, e.g.
$14.34
,4 USD
or even5 euros
.will be triggered by
Note: the
parsecurrency
package seems perfect for this use case, see https://www.npmjs.com/package/parsecurrencyempty
,string
orany
Matches any string (regex being
(.*)
). For information, the SpecFlow equivalent isempty
butany
feels more elegant and consistent with the existing TypeScript types. Also note thatstring
can be a valid name. It will then convert the value into a custom object type having at least the raw string value, the number value, the currency unit and/or symbol.Example:
will be triggered by
Note:
{string}
,{any}
and{empty}
can be aliases if both are considered valid keywords.Custom expressions
Having the ability to create custom expressions from regex can be interesting especially in TypeScript where you can define union types, whether having an union of different strings or even an union of different types.
This feature is already implemented in other libraries with a function called
defineParameterType
, see https://github.com/cucumber/cucumber-expressions?tab=readme-ov-file#javascript--typescriptThis new parameter expression can then be used in a scenario step:
Default culture
A main pain point when working with some parameter expressions is it being valid with the current culture/language. The most common one being the
{date}
expression when a date can be recognized asMM-JJ-AAAA
format (US, the default one) when in general we expect it to be in theJJ-MM-AAAA
format (outside the US).Either set a
culture
orlanguage
property to change the default behavior of some parameter expressions. Also having the possibility to set a global configured property and one per feature/scenario.date formats
Example:
will be triggered by
Given the default culture/language, it will create a native js
Date
January the 2nd (US format, default) or February the 1st (e.g. FR format).boolean formats
US example
Given the language is either not set, or is set to
en
or the culture is set toen-US
.will be triggered by
FR example
Given the language is set to
fr
or the culture is set tofr-FR
.will be triggered by
In french, the boolean can be translated to
true
when the pattern matches "vrai(e)(s)"false
when the pattern matches "faux|fausse(s)"