www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DSpec / Templates + Delegates

reply Ruun <ruunhb googlemail.com> writes:
Hi everyone,

for my coming projects i was searching for a BDD-Framework similar like 
Ruby/RSpec or Scala/ScalaTest.
Unfortanetly, i didn't find either an implementation on dsource.org or 
something about here on the mailing list (Especially
for D2).

After looking into the old source of Tango-based DUnit, some postings 
here on the mailing list about assertions / unittests, i started a small 
try with Phobos D2 and i'm currently really amazed how clear the API can 
be by using templates + delegates + alias.

If someone is interested, i recently hosted a project DSpec on 
dsource.org and provide an experimantel example there
http://www.dsource.org/projects/dspec/
(Current source can be also found)

I'm not sure if something similar is possible in D1 and honestly it's 
the first time i'm currently working with Templates in D so intensely.
But after seeing such possibilities, i'm so impressed about D2.

void each(alias array, T : T[] = typeof(array))(void delegate(T item) dg) {
   foreach(T i; array)
     dg(i);
}

   int[] array = [1, 2, 3, 4];
   int b = 10;

   each!(array) = (int item) {
     writefln("%d", item + b);
   };

This is almost looking like an iteration in Ruby and Scala!
(I hope i'm not abusing the alias parameter in templates)

Chris

-- 
ruunhb googlemail.com
http://ruuns.de/blog/
Mar 30 2010
next sibling parent Jacob Carlborg <doob me.com> writes:
On 3/30/10 13:58, Ruun wrote:
 Hi everyone,

 for my coming projects i was searching for a BDD-Framework similar like
 Ruby/RSpec or Scala/ScalaTest.
 Unfortanetly, i didn't find either an implementation on dsource.org or
 something about here on the mailing list (Especially
 for D2).

 After looking into the old source of Tango-based DUnit, some postings
 here on the mailing list about assertions / unittests, i started a small
 try with Phobos D2 and i'm currently really amazed how clear the API can
 be by using templates + delegates + alias.

 If someone is interested, i recently hosted a project DSpec on
 dsource.org and provide an experimantel example there
 http://www.dsource.org/projects/dspec/
 (Current source can be also found)

 I'm not sure if something similar is possible in D1 and honestly it's
 the first time i'm currently working with Templates in D so intensely.
 But after seeing such possibilities, i'm so impressed about D2.

 void each(alias array, T : T[] = typeof(array))(void delegate(T item) dg) {
 foreach(T i; array)
 dg(i);
 }

 int[] array = [1, 2, 3, 4];
 int b = 10;

 each!(array) = (int item) {
 writefln("%d", item + b);
 };

 This is almost looking like an iteration in Ruby and Scala!
 (I hope i'm not abusing the alias parameter in templates)

 Chris
To make it look a little more like Ruby or Scala you change the each function to something like this, using some operator overload abuse: struct EachHelper (T) { T[] array; void opIn (void delegate (T item) dg) { foreach (i, array) dg(i); } } void each (T) (T[] array) { return EachHelper!(T)(array); } Then use it like this: int[] array = [1, 2, 3, 4]; int b = 10; array.each in (int item) { writefln("%d", item + b); }; The above code is the same as the following: each(array).opIn((int item) { writefln("%d", item + b); }); I think all the above code will work both in D1 and D2.
Mar 30 2010
prev sibling next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Ruun:
 After looking into the old source of Tango-based DUnit, some postings 
 here on the mailing list about assertions / unittests, i started a small 
 try with Phobos D2 and i'm currently really amazed how clear the API can 
 be by using templates + delegates + alias.
I think that follows the type-II solution (the worst one) I have explained here: http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=107997 (Thank you for your code and work, the worst solution is often better than no solution.) Bye, bearophile
Mar 30 2010
prev sibling next sibling parent "Masahiro Nakagawa" <repeatedly gmail.com> writes:
Hi,

I read sources. I have something on my chest.

- ruun package
Umm...need?

- import ruun.dspec.Spec; import ruun.dspec.Should;
I think ruun.dspec.Spec should uses "public import" for Should module.
Is there a case that spec empties in it! ?

- Spec methods
Why final? How can I create custom Spec?

I expect the maturation of this project in a good direction.


On Tue, 30 Mar 2010 20:58:39 +0900, Ruun <ruunhb googlemail.com> wrote:

 Hi everyone,

 for my coming projects i was searching for a BDD-Framework similar like  
 Ruby/RSpec or Scala/ScalaTest.
 Unfortanetly, i didn't find either an implementation on dsource.org or  
 something about here on the mailing list (Especially
 for D2).

 After looking into the old source of Tango-based DUnit, some postings  
 here on the mailing list about assertions / unittests, i started a small  
 try with Phobos D2 and i'm currently really amazed how clear the API can  
 be by using templates + delegates + alias.

 If someone is interested, i recently hosted a project DSpec on  
 dsource.org and provide an experimantel example there
 http://www.dsource.org/projects/dspec/
 (Current source can be also found)

 I'm not sure if something similar is possible in D1 and honestly it's  
 the first time i'm currently working with Templates in D so intensely.
 But after seeing such possibilities, i'm so impressed about D2.

 void each(alias array, T : T[] = typeof(array))(void delegate(T item)  
 dg) {
    foreach(T i; array)
      dg(i);
 }

    int[] array = [1, 2, 3, 4];
    int b = 10;

    each!(array) = (int item) {
      writefln("%d", item + b);
    };

 This is almost looking like an iteration in Ruby and Scala!
 (I hope i'm not abusing the alias parameter in templates)

 Chris
Mar 30 2010
prev sibling parent Chris Mueller <ruunhb googlemail.com> writes:
bearophile:
 I think that follows the type-II solution (the worst one) I have explained
here:
 http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.D&article_id=107997
 (Thank you for your code and work, the worst solution is often better than no
solution.)
    
I enjoyed reading your article and i agree with you about the current Unittest-situation. If i remember my time working with other Unittesting Frameworks in other languages, i was always annoyed in the beginning to find out how to setup the tests and especially it's test execution. Often it was more comfortable to rely on some buildsystems, which already configured an automatic way. Though i doesn't like it to be depending on a specific buildsystem. Walters approach to implement unittests into the compiler, is also in my opinion the most user-friendly way for developers to run unittest and avoids the annoying and time-consuming configuration management. (Though the D language give a great help to locate specific classes thanks to ModuleInfo struct and makes it eas implementing a testrunner in compare of other programming languages) Thanks to the article i decided to move the dspec execution into the unittest environment (it's also already working now) in hope to make the configuration and test execution more simpler. I also agree that developers shouldn't waste much time in the setup and API of a unittesting framework, because it's only a tool for development. Unfortanetly, i don't know a way to get commandline arguments which would offers to configure a unittest framework. I can indeed catch the arguments in the main function, but the unittest code is already executed before the main function will be invoked. A trivial workaround could be probably using a configuration file, which can be located and accessed by dspec framework. Masahiro Nakagawa:
 I read sources. I have something on my chest.

 - ruun package
 Umm...need?
    
It's surely not needed :) I already moved all modules to a simple dspec package.
 - import ruun.dspec.Spec; import ruun.dspec.Should;
 I think ruun.dspec.Spec should uses "public import" for Should module.
 Is there a case that spec empties in it! ?
    
I know other unittest frameworks, that offers different implementation for assertions / expectations and the developer can chose one. But setting Should.d to a public import would offer a standard implementation that is always accessible. Of course, this is a good idea.
 - Spec methods
 Why final? How can I create custom Spec?
    
Is not needed anymore, because the Spec class is removed and the spec methods are moved to a single module now in order to get executed in a dmd unittest environment. (Though it won't also offer creating custom Specs). Thank you very much for your code review. If someone want to test dspec, be warned the buildscript (Rakefile) can maybe fail on Linux or Mac. I haven't test it yet on that plattforms. Jacob Carlborg:
 int[] array = [1, 2, 3, 4];
 int b = 10;

 array.each in (int item) {
 	writefln("%d", item + b);
 };
    
You are right :) I like it very much. Chris Mueller -- ruunhb googlemail.com http://ruuns.de/blog/
Mar 31 2010