ecukes/ecukes — pull request #138 by atykhonov (2014-02-07 06:49:06+00:00)
Title: Concise step definitions II

Hi!

This is concise step definition II (not a secord part but another implementation).

First of all, sorry, if I was boring before. This is because I really don't like "Concise step definitions I". Yes, it could be helpful, it could help while writing definitions but I don't think that that makes ecukes better.

Well. Why Concise step definitions II?

I still believe that there should be some elispy way in writing step definitions.

You see, in ruby:

```
When /^I write article "([^\"]*)"$/ do |arg1|
```

step definitions are quite... let me say, natural. In the same time I think that for elisp current ecukes way is not quite good (quite natural) at least because we need escape many symbols. But there should be some elispy its own natural way!

And I want suggest some way. This is a little bit crazy idea, but at least (I believe) quite interesting. Why not avoid usage of regular expressions at all? Why not?

You've shown me ```rx``` and it is very powerfull and it has much more power than it is needed (for ecukes). After some time I started to think that even regular expressions provides also much more power than it is really really required!

This implementation is going to show a way. Well, I see only benefits. Yes, that implementation I believe could be (in general) better but this is right now only about idea, direction. I don't see any issues with such implementation and of course I could be very wrong. It will be much appreciated if you'll show me where I'm wrong if really wrong!

So. Basic idea is... Well, let me show me example:

```
(When '(I translate 'string from 'symbol to 'symbol)
(lambda (text source-language target-language)
...))
```

I'm looking at it right now and it looks as for me very similar to ruby's cucumber, don't you think so? :-) Of course except 'string and 'symbol. Well, let me continue with 'symbol and 'string.

'symbol -- this means any string without space inside: en, 127.0.0.1, lorem-ipsum, 204, mail@example.com, ecukes-parse-step-definition etc. 'symbol replaces in the ```ecukes-steps-define``` by regular expression ```\\([^ ]+\\)```.
'string -- this means any string which is surrounded by quotes (because such strings include space(s) in itself): "lorem ipsum", "etc etc etc" etc. It replaces by ```"\"\\(.*\\)\""```

So only two kind of sequences. Does anybody need more? Well, may be. I'll come back to that question after a while.

So, in case of such step definition:

```
(When '(I translate 'string from 'symbol to 'symbol)
(lambda (text source-language target-language)
...))
```

There will be such concrete step:

```
I translate "I read the book" from en to ru
```

May be 'symbol and 'string in step definitions looks a little bit weird (and may be unreadable) but there is lambda at the bottom which let us give a little bit more info about which exactly parameters will be used there. Well, of course there could be more different types... 'buffer-name, 'point, 'region-state etc and even user defined and even everything could be validated (existence of buffer with name for example)... But I don't see any profit of these extra definitions right now... At least because in case of two types (symbol and string) it is going to be quite simple and straightforward as for me.

Of course in case of such definitions it will be required to keep step definitions as simple as possible. So with only 'symbol and 'string there will be no possibility to write such definition in elispy way as:

```
(Given "^transient mark mode is \\(active\\|inactive\\)$"
```

And it should be devided.

The same is about:

```
(Then "^the region should be\\(?: \"\\(.*\\)\"\\|:\\)$"
```

But I think this is good (to keep definitions as simple as possible, and this elispy way keeps everything in this way!).

The only step definition which keeps me worrying right now is the:

```
(When "^I set \\(.+\\) to \\(.+\\)$"
"Set some variable."
(lambda (var val)
(set (intern var) (read val))))
```

'symbol and 'string seems are not applicable here because step definition could be:

```
Given I set google-translate-translation-directions-alist to (("en" . "ru") ("ru" . "uk") ("ru" . "en"))
```

May be it would be reasonable to use third type (special for variable), may be it reasonable just avoid such definitions and set variables in the lambdas, may be something else... I didn't find conclusion yet but in general I don't think that this is real problem. I believe solution could be found. And must be found. Because...

For now, in general, I've found a way with which I'll be continue preparing ecukes! :-)