2

I'm continuing my Stack-Overflow-Driven Programming of a testing DSL - thanks to all who have contributed so far!

At the moment my DSL reads like this

scenario("Incorrect password") {
  given("user visits", the[AdminHomePage])
  then(the[SignInPage], "is displayed")      

  when("username", "admin", "and password", "wrongpassword", "are entered")
  then(the[SignInPage], "is displayed")      
  and("Error message is", "Sign in failed")
}

given, when and then are methods that take Any, so when called like this they are passed a tuple of the arguments - Why and how is Scala treating a tuple specially when calling a one arg function? .

Ideally I'd drop the commas, so that it reads much nicer, with just spaces separating the tokens

scenario("Incorrect password") {
  given("user visits" the[AdminHomePage])
  then(the[SignInPage] "is displayed")      

  when("username" "admin" "and password" "wrongpassword" "are entered")
  then(the[SignInPage] "is displayed")      
  and("Error message is" "Sign in failed")
}

Can anyone think of any technique that would let me achieve this goal, or is it going too far for an internal DSL?

Community
  • 1
  • 1
Duncan McGregor
  • 17,665
  • 12
  • 64
  • 118

3 Answers3

1

No, you can't create tuples from space separated tokens (although you can use a custom operator as separator instead of comma). What you can do is to use the dot free syntax like this:

obj method obj method obj ...

Many DSL implementations (like specs) utilize this syntax to create more "text-like" syntax.

Jesper Nordenberg
  • 2,104
  • 11
  • 15
1

You need a method/operator between the "tokens". For pairs there is already ->, e.g.

println("hello" -> 12 -> '!' -> 12.0)
//--> (((hello,12),!),12.0)
Landei
  • 54,104
  • 13
  • 100
  • 195
  • I did consider using | or something like that, but everything seems as least as obtrusive as the the commas, for a lot more work. – Duncan McGregor Jun 10 '11 at 11:57
  • 1
    Often "is" seems to work well in your case: `then(the[SignInPage] is "displayed")`, `and("ErrorMessage" is "Sign in failed")` – Landei Jun 10 '11 at 12:39
1

Not sure if it works:

As mentioned before you can call one argument methods in operator notation. There is also the Dynamic Trait which allows dynamic invocation of methods: http://www.scala-lang.org/api/current/index.html#scala.Dynamic

So if you start with an object implementing the dynamic trait it might work ..

Jens Schauder
  • 77,657
  • 34
  • 181
  • 348