Re: Scalatest integration

282 views
Skip to first unread message

Bill Venners

unread,
Feb 3, 2012, 5:48:02 AM2/3/12
to Iulian Dragos, Chee Seng Chua, Matthew Farwell, scala-...@googlegroups.com
Hi Iulian,

On Fri, Feb 3, 2012 at 4:31 PM, Iulian Dragos
<iulian...@typesafe.com> wrote:
> i) I can't find a way to navigate up to the parent of the given Tree object,
> is there a way to do that?  I could get the children by the .children but I
> am not sure about how to get the 'parent'.
>
>
> There's no link to the parent, the AST is a 'real' tree. What would you like
> to do, maybe there's an alternative way? I really think it would be good to
> ask these questions on scala-ide-dev on Google Groups, since more people
> might be interested by the answers (and the whole IDE team reads the list).
>
I joined scala-ide-dev and CC'd the list.

The problem we are trying to solve is allowing people to get good IDE
support for custom style traits in ScalaTest. ScalaTest lets users
customize the syntax of their tests to meet their needs. We'd like
folks who do that to be able to get IDE support as good as if they use
the built-in style traits. It is fundamental to the design of
ScalaTest that people can customize it in this way, and I don't want
them to have to give up good IDE support if they do.

The hard part is enabling a pop up menu that runs selected tests when
someone selects some arbitrary code and right clicks to get a pop up
context menu. How does the IDE know what the tests are, in a framework
where that can be customized? Whatever we do needs to be very fast,
because users want that pop up to feel like it happens just about
immediately.

The current approach we are trying is to annotate ScalaTest's built in
style traits with a Style annotation, and make that annotation
available for users. When a user opens a source file containing test
classes, the IDE can follow the linearization of each of those classes
until it bumps into the first one that has a Style annotation. This
can be done before the user right clicks if need be, right when the
file is opened, and after each time it compiles successfully, etc.
But it probably would be fast enough to do it when they right click as
well. So one thing we want to know is, is there an easy way to
traverse the linearization of a class?

Then, once the Style annotation is found, it can have a "Finder" class
specified in it. The IDE can instantiate this class (again this could
be done ahead of time, but would be fast enough on demand too), and
the Finder has a method that takes an AST (wrapped in ScalaTest AST
wrapper classes to unify the API across the different IDEs), and that
method returns a "Selection" that indicates what the tests are. The
Selection tells the IDE what to put on the context menu, and what to
pass to ScalaTest if the user selects that menu item.

We have done this in IntelliJ and it was plenty fast enough. But in
IntelliJ we were able to go to the parent of an AST node. So (I think)
we have it giving just the selected bit of the AST to the Finder, and
it traverses outward via the parent pointers sometimes to get more
context. What I think we'll likely need to do given the presentation
compiler's AST does not have parent pointers is give the whole class
AST and somehow highlight what the selected part is (or where in the
tree the use right clicked, if they clicked without otherwise
selecting anything. This would work both on ASTs with parent nodes
(IntelliJ) and those without (Eclipse and NetBeans.

Chee Seng is working on this so I may have some of the details wrong.
If so, Chee Seng please correct me.

Thanks.

Bill
----
Bill Venners
Artima, Inc.
http://www.artima.com

iulian dragos

unread,
Feb 3, 2012, 7:36:44 AM2/3/12
to scala-...@googlegroups.com, Chee Seng Chua, Matthew Farwell
On Fri, Feb 3, 2012 at 11:48 AM, Bill Venners <bi...@artima.com> wrote:
Hi Iulian,

On Fri, Feb 3, 2012 at 4:31 PM, Iulian Dragos
<iulian...@typesafe.com> wrote:
> i) I can't find a way to navigate up to the parent of the given Tree object,
> is there a way to do that?  I could get the children by the .children but I
> am not sure about how to get the 'parent'.
>
>
> There's no link to the parent, the AST is a 'real' tree. What would you like
> to do, maybe there's an alternative way? I really think it would be good to
> ask these questions on scala-ide-dev on Google Groups, since more people
> might be interested by the answers (and the whole IDE team reads the list).
>
I joined scala-ide-dev and CC'd the list.

The problem we are trying to solve is allowing people to get good IDE
support for custom style traits in ScalaTest. ScalaTest lets users
customize the syntax of their tests to meet their needs. We'd like
folks who do that to be able to get IDE support as good as if they use
the built-in style traits. It is fundamental to the design of
ScalaTest that people can customize it in this way, and I don't want
them to have to give up good IDE support if they do.

Absolutely, we have to find a way to do that.
 

The hard part is enabling a pop up menu that runs selected tests when
someone selects some arbitrary code and right clicks to get a pop up
context menu. How does the IDE know what the tests are, in a framework
where that can be customized? Whatever we do needs to be very fast,
because users want that pop up to feel like it happens just about
immediately.

The current approach we are trying is to annotate ScalaTest's built in
style traits with a Style annotation, and make that annotation
available for users. When a user opens a source file containing test
classes, the IDE can follow the linearization of each of those classes
until it bumps into the first one that has a Style annotation. This
can be done before the user right clicks if need be, right when the
file is opened, and after each time it compiles successfully, etc.
But it probably would be fast enough to do it when they right click as
well. So one thing we want to know is, is there an easy way to
traverse the linearization of a class?

If I understand correctly, you need to find out the base classes of a class, in the linearization order? The compiler can tell you that, if you get hold of the Symbol of that class. It would be something along like sym.info.baseClasses (the compiler AST and type/symbol information has to be looked up in the Scala compiler project).

We're also working on wrapping those data structures for the IDE plugin writers, to simplify some of these operations (but we'll keep the same terminology, so that people can reuse the knowledge they have from the scala reflection API that will come in 2.10). For the moment you need to rely on compiler Symbols, though.
 
Then, once the Style annotation is found, it can have a "Finder" class
specified in it. The IDE can instantiate this class (again this could
be done ahead of time, but would be fast enough on demand too),

Where is this class found? You do that through reflection? If that class is part of the user code, you need to make sure the project is built and there are no errors, I imagine.
 
and
the Finder has a method that takes an AST (wrapped in ScalaTest AST
wrapper classes to unify the API across the different IDEs), and that
method returns a "Selection" that indicates what the tests are. The
Selection tells the IDE what to put on the context menu, and what to
pass to ScalaTest if the user selects that menu item.

This sounds good, and I don't think it will be too slow (unless you need to recompile the project, of course).
 

We have done this in IntelliJ and it was plenty fast enough. But in
IntelliJ we were able to go to the parent of an AST node. So (I think)
we have it giving just the selected bit of the AST to the Finder, and
it traverses outward via the parent pointers sometimes to get more
context. What I think we'll likely need to do given the presentation
compiler's AST does not have parent pointers is give the whole class
AST and somehow highlight what the selected part is (or where in the
tree the use right clicked, if they clicked without otherwise
selecting anything. This would work both on ASTs with parent nodes
(IntelliJ) and those without (Eclipse and NetBeans.

In order to get the enclosing class, this sounds like the best solution. It will likely be more efficient, since the path from the root to the enclosing class could be shorter than the path upwards from the expression level. Have a look at how `Locator` works in 


You can either subclass it, or just rewrite the Traverser, since there's very little logic there. Another solution could do something like the following on the entire compilation unit tree

tree.filter(t => t.pos includes && t.isInstanceOf[ClassDef]) 

(I haven't tried this this code).

iulian

Chee Seng Chua

unread,
Feb 3, 2012, 9:40:54 AM2/3/12
to iulian dragos, scala-...@googlegroups.com, Matthew Farwell
Hi all, 

Sorry for late replying as I have been moving around today.  Thanks Iulian for the pointers, I'll try them out during the weekend.

Thanks!

Best Regards, 
Chee Seng

Chee Seng Chua

unread,
Feb 4, 2012, 11:28:06 AM2/4/12
to iulian dragos, scala-...@googlegroups.com, Matthew Farwell
Hi all, 

I am able to work out a workaround to get the 'parent' for a Tree, in the getParent method at line 76 of:-


>>If I understand correctly, you need to find out the base classes of a class, in the linearization order? The compiler can tell you >>that, if you get hold of the Symbol of that class. It would be something along like sym.info.baseClasses (the compiler AST and >>type/symbol information has to be looked up in the Scala compiler project).

I think I am able to get the sym.info.baseClasses that you meant, if I am don't get you wrong, see line 119 of the above URL, which prints the following (seems to me is in linearization order already):-

List(class TestingFixtureSpec, trait FixtureFeatureSpec, trait FixtureSuite, trait Suite, trait AbstractSuite, trait Assertions, trait ScalaObject, class Object, class Any)

when I click on a source that looks like this:-

class TestingFixtureSpec extends fixture.FixtureFeatureSpec {
  ...
}

I'll continue tomorrow to see if I can differentiate the template, method def and method invocation (used by our default finders currently) from the AST and get the required information (args, target etc.).  The @Style annotation that contains the class of Finder is annotated at our style trait classes in ScalaTest, the classes should available from the compiled scalatest.jar, unless the user makes their own custom style trait with custom finder.  In that case we should check if the project is compiled like you said.

Thanks!

Best Regards, 
Chee Seng

Chee Seng Chua

unread,
Feb 5, 2012, 11:06:30 AM2/5/12
to iulian dragos, scala-...@googlegroups.com, Matthew Farwell
Hi all, 

I have done some research figuring out the way to gather required information to transform AST in eclipse to unified ScalaTest's AST, which currently includes the following types:-

1) Method Definition - Requires method name and argument types's classname.
2) Method Invocation - Requires target, method name, parameters (literals, parameter other than literal should be wrapped in a ToString wrapper).
3) Template - the container of the class definition.

The experimental code is available at line 113 of:-


Do they looked right to you?  I could start to put them into ScalaTest's location API's finders to test if they work, but I have no luck importing scalatest.jar into the plugin project.

I tried the following steps but failed:-

In full.library project's pom.xml, I added the following under <dependencies>:-

<dependency>
  <groupId>org.scalatest</groupId>
  <artifactId>scalatest_2.9.0</artifactId>
  <version>1.7.RC2</version>
</dependency>

and the following under <executions> of maven-dependency-plugin:-

<artifactItem>
  <groupId>org.scalatest</groupId>
  <artifactId>scalatest_2.9.0</artifactId>
  <version>1.7.RC2</version>
  <outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>

I then run build-toolchain-2.9.x.sh, refresh and clean the projects.  There are compilation errors like the followings:-

No available bundle exports package 'org.easymock'
No available bundle exports package 'org.jmock.api'
No available bundle exports package 'org.jmock.internal'
No available bundle exports package 'org.jmock.lib.legacy'
No available bundle exports package 'org.jmock'
No available bundle exports package 'org.mockito.stubbing'
No available bundle exports package 'org.mockito'
No available bundle exports package 'org.scalacheck'
No available bundle exports package 'org.testng.annotations'
No available bundle exports package 'org.testng'

Those are ScalaTest's 'optional' libraries, they should only be required on the client project's classpath if they use them (another question: how to load class from the client project's classpath?).  I then tried removing the above packages from 'Imported Packages' in plugin.xml.  The project compiles without error, but when I launch to test the plugin, the scala-plugin doesn't seem to load at all.

May I know what's the correct steps to import the external libraries?

Thanks!

Best Regards, 
Chee Seng




Chee Seng Chua

unread,
Feb 5, 2012, 11:09:07 AM2/5/12
to iulian dragos, Bill Venners, scala-...@googlegroups.com, Matthew Farwell
Hi all, 

Added Bill to the list, not sure why it didn't included as I was clicking 'Reply All' previously.

Sorry about this.

Thanks!

Best Regards, 
Chee Seng

iulian dragos

unread,
Feb 5, 2012, 2:55:32 PM2/5/12
to scala-...@googlegroups.com, Matthew Farwell
Hi  Chee Seng,

Good to see the idea fleshed out so quickly! I had a look at your code and I had a few observations that I added directly by commenting on your github commits.

Regarding adding an external library, I suggest you add it to the sdt.core project, following the example of 'miglayout.jar' (add it both to the pom file, and the Bundle-Classpath entry in the MANIFEST.MF file).

Keep up the good work!
iulian

ijuma

unread,
Feb 5, 2012, 6:35:56 PM2/5/12
to scala-...@googlegroups.com, Bill Venners
Hi all,

Great to see progress on this. By the way, the following is the relevant ticket for this feature:

http://scala-ide-portfolio.assembla.com/spaces/scala-ide/tickets/1991

Best,
Ismael

Chee Seng Chua

unread,
Feb 5, 2012, 11:02:22 PM2/5/12
to iulian dragos, Bill Venners, scala-...@googlegroups.com, Matthew Farwell
Hi all, 

Some update on including scalatest.jar into the plugin project:-

I try to mark those imported packages as 'optional' instead of removing them:-

org.easymock;resolution:=optional,
org.hamcrest;resolution:=optional,
org.jmock;resolution:=optional,
org.jmock.api;resolution:=optional,
org.jmock.internal;resolution:=optional,
org.jmock.lib.legacy;resolution:=optional,

...

and add org.scalatest.xxxx into the export packages:-

Export Packages:-
...
org.scalatest,
org.scalatest.concurrent,
org.scalatest.events,
org.scalatest.fixture,
org.scalatest.junit,
org.scalatest.matchers,
org.scalatest.mock,
org.scalatest.prop,
org.scalatest.testng,
org.scalatest.tools,
org.scalatest.verb,
...

ScalaTest classes now seems to be available to the plugin project now, and I try to execute org.scalatest.tools.Runner.run when Run As -> ScalaTest is selected, the ScalaTest's Runner seems to be running correctly (at least for initial test).

Is this the correct way?

Thanks!

Best Regards, 
Chee Seng

iulian dragos

unread,
Feb 6, 2012, 5:27:19 AM2/6/12
to scala-...@googlegroups.com
On Mon, Feb 6, 2012 at 5:02 AM, Chee Seng Chua <chee...@amaseng.com> wrote:
Hi all, 


Yes, good job!

iulian 

Chee Seng Chua

unread,
Feb 8, 2012, 9:10:59 AM2/8/12
to Scala IDE Dev, Bill Venners
Hi Iulian,

I am trying to use the below following your comments:-

ScalaTestLaunchShortcut(val compiler: ScalaPresentationCompiler)

it compiles but get a runtime error due to ScalaTestLaunchShortcut
cannot be instantiated problem, do I need to do something in
plugins.xml to tell eclipse that it needs to pass in a compiler
instance when creating ScalaTestLaunchShortcut?

Also, if I omit the 'val', there's a error on the following line:-

@tailrec
final def getParentTree(candidate: Tree, node: Tree): Option[Tree] = {
...
}

with the 'Option[Tree]' being red-underlined, the error message is
saying "private value compiler escapes its defining scope as part of
type Option[ScalaTestLaunchShortcut.this.compiler.Tree]". Adding the
val fixes the compilation error, but I am not sure if it's the correct
thing to do as I am not very sure about the compiler's complaint.

Thanks again for your kind guidance.

Thanks!

Best Regards,
Chee Seng


On Feb 6, 6:27 pm, iulian dragos <iulian.dra...@typesafe.com> wrote:

Chee Seng Chua

unread,
Feb 13, 2012, 11:15:28 PM2/13/12
to Scala IDE Dev, Bill Venners
Hi Iulian,

I figure out about the dependent type, I have refactored out the code
to transform the AST and finding ScalaTest selected tests into the
following class:-

https://github.com/cheeseng/scala-ide/blob/master/org.scala-ide.sdt.core/src/scala/tools/eclipse/launching/ScalaTestFinder.scala

and let ScalaTestLaunchShortcut to pass in the
ScalaPresentationCompiler.

Another problem I have is loading classes from the client's project
classpath, the reason we need to do this is because user could write
their own custom finder implementation and put the jar/class in their
project classpath, the code I am using currently to load the test base
class (consequently the finder) is using Class.forName (line 243 in
ScalaTestFinder.scala), which probably is not correct. May I know
what's the correct way to achieve that?

Thanks!

Best Regards,
Chee Seng


iulian dragos

unread,
Feb 18, 2012, 5:14:21 AM2/18/12
to scala-...@googlegroups.com, Bill Venners
Hi Chee Seng,

Sorry to take so long to reply, I was away for a few days.

On Tue, Feb 14, 2012 at 5:15 AM, Chee Seng Chua <chee...@amaseng.com> wrote:
Hi Iulian,

I figure out about the dependent type, I have refactored out the code
to transform the AST and finding ScalaTest selected tests into the
following class:-

https://github.com/cheeseng/scala-ide/blob/master/org.scala-ide.sdt.core/src/scala/tools/eclipse/launching/ScalaTestFinder.scala

and let ScalaTestLaunchShortcut to pass in the
ScalaPresentationCompiler.

Looks good! I still think it would be more efficient to use the `Locator` style class to find the enclosing class of a given position, but it's up to you in the end.

One small observation. This code could be made prettier by making `MethodDefinition` a case class, and the pattern-matching on it.


rawChildren match {
        case primary :: rest =>
          if (primary.isInstanceOf[MethodDefinition] && primary.name == "this")
            rest.toArray
 
could be written `case MethodDefinition("this", _, _, ...) =>`


Another problem I have is loading classes from the client's project
classpath, the reason we need to do this is because user could write
their own custom finder implementation and put the jar/class in their
project classpath, the code I am using currently to load the test base
class (consequently the finder) is using Class.forName (line 243 in
ScalaTestFinder.scala), which probably is not correct.  May I know
what's the correct way to achieve that?

I guess there's no other way than Java reflection. I don't think it works like that, though, since you need a class loader that knows where to load user classes from. I would use a URLClassLoader pointing to the output directories of the current project (you'd need one class loader per project).

cheers,
iulian



--
« Je déteste la montagne, ça cache le paysage »
Alphonse Allais

Chee Seng Chua

unread,
Feb 19, 2012, 11:16:31 PM2/19/12
to Scala IDE Dev, Bill Venners
Hi iulian,

I have changed those AST wrapper classes to case classes, I think
that's good idea.

The requirement for the getParentTree() method in ScalaTestFinder is
really a workaround to access the 'parent' Tree for a Tree, it is not
necessary to find the enclosing class. For example like the following
code:-

feature("a feature") {
scenario("a scenario") {

}
}

If you click on the 'scenario' MethodInvocation, we would want to
access its parent Tree, which is the 'feature' MethodInvocation.

So given the root Tree and the selected Tree, the getParentTree()
method should return the parent Tree of the selected Tree. For
example:-

N1
/ \
N2 N3
/\ / \
N4 N5 N6 N7

Root = N1, Selected = N6, and what we want is N6.parent, which should
be N3.

I have tried modify the Locator to accept a selected Tree instead of
position:-

class Locator(selected: Tree) extends Traverser {
var last: Tree = _
def locateIn(root: Tree): Tree = {
this.last = EmptyTree
traverse(root)
this.last
}
protected def isEligible(t: Tree) = !t.pos.isTransparent
override def traverse(t: Tree) {
t match {
case tt : TypeTree if tt.original != null =>
traverse(tt.original)
case _ =>
if (t.pos includes selected.pos) {
if (isEligible(t)) last = t
super.traverse(t)
} else t match {
case mdef: MemberDef =>
traverseTrees(mdef.mods.annotations)
case _ =>
}
}
}
}

and use it in getParentTree():-

val locator = new Locator(node)
val parentTree = locator.locateIn(candidate)
if (parentTree != EmptyTree)
Some(parentTree)
else
None

but it goes into infinite loop when getParentTree get called, it's
probably because I don't quite understand the Locator's original
source to make correct modification. May be you can see what's going
wrong?

I'll try work on the class loader to load class from client project to
see if I can get it working.

Thanks!

Best Regards,
Chee Seng



On Feb 18, 6:14 pm, iulian dragos <jagua...@gmail.com> wrote:
> Hi Chee Seng,
>
> Sorry to take so long to reply, I was away for a few days.
>
> On Tue, Feb 14, 2012 at 5:15 AM, Chee Seng Chua <chees...@amaseng.com>wrote:
>
> > Hi Iulian,
>
> > I figure out about the dependent type, I have refactored out the code
> > to transform the AST and finding ScalaTest selected tests into the
> > following class:-
>
> >https://github.com/cheeseng/scala-ide/blob/master/org.scala-ide.sdt.c...

Chee Seng Chua

unread,
Feb 20, 2012, 8:12:23 AM2/20/12
to Scala IDE Dev, Bill Venners
Hi iulian,

I have checked in the code to load classes from client project's
classpath, to create the ClassLoader I use the following codes:

val loaderUrls = scProject.classpath.map{ cp =>
val cpFile = new File(cp.toString)
if (cpFile.exists && cpFile.isDirectory && !
cp.toString.endsWith(File.separator))
new URL("file://" + cp + "/")
else
new URL("file://" + cp)
}
val loader:ClassLoader = new URLClassLoader(loaderUrls.toArray,
getClass.getClassLoader)

I then use reflection to call the Finder.find in ScalaTestFinder. I
tested it using a custom Finder implemented in the client project and
it seems to be working correctly.

Does the code looks right to you?

Thanks!

Best Regards,
Chee Seng


iulian dragos

unread,
Feb 20, 2012, 9:45:46 AM2/20/12
to scala-...@googlegroups.com, Bill Venners
On Mon, Feb 20, 2012 at 2:12 PM, Chee Seng Chua <chee...@amaseng.com> wrote:
Hi iulian,

I have checked in the code to load classes from client project's
classpath, to create the ClassLoader I use the following codes:

val loaderUrls = scProject.classpath.map{ cp =>
 val cpFile = new File(cp.toString)
 if (cpFile.exists && cpFile.isDirectory && !
cp.toString.endsWith(File.separator))
   new URL("file://" + cp + "/")
 else
   new URL("file://" + cp)
}
val loader:ClassLoader = new URLClassLoader(loaderUrls.toArray,
getClass.getClassLoader)

I then use reflection to call the Finder.find in ScalaTestFinder.  I
tested it using a custom Finder implemented in the client project and
it seems to be working correctly.

Does the code looks right to you?

Looks good! Great!

Chee Seng Chua

unread,
Feb 28, 2012, 10:09:55 AM2/28/12
to Scala IDE Dev, Bill Venners
Hi all,

Just to update that I have updated the fork at:-

https://github.com/cheeseng/scala-ide

to use only the more lightweight ScalaTest Finder jar, the full
scalatest.jar is no longer required to be included in the plugin
anymore.

I have also create and register a launch configuration that works with
selected suite, it can successfully launch the selected suite using
ScalaTest Runner now.

For testing, you'll need to check out the ScalaTest finder sbt project
at:-

https://scalatest.googlecode.com/svn/branches/finder

Just build and package it using sbt, and then publish the jar to the
local maven repo, which I do using the following steps:-

1) Rename the scalatest-finders_2.9.1-1.0.0.jar built from sbt to
scalatest-finders.jar
2) Use the following command to publish to local maven repo:-

mvn install:install-file -Dfile=scalatest-finders.jar -
DgroupId=org.scalatest -DartifactId=scalatest-finders_2.9.1 -
Dversion=1.0.0 -Dpackaging=jar -DlocalRepositoryPath=/home/
cheeseng/.m2/repository

I have updated pom.xml in fulllibrary project to load the finder
artifact, so if the artifact is in your local maven repo you should be
able to build the plugin successfully after running the build-
toolchain script.

The finder will be used to detect selected test/scope from ScalaTest
suite source file, style traits in ScalaTest (load from scalatest.jar
in client project's classpath) will be annotated with @Style like
this:-

@Style("org.scalatest.finders.FunSuiteFinder")
trait FunSuite extends Suite {
...
}

The plugin will use org.scalatest.finders.FunSuiteFinder to find
selected test/scope and prints out to console (currently). To test
finder, you will need scalatest.jar built from the following branch in
your client project's classpath:-

https://scalatest.googlecode.com/svn/branches/locspi

We are going to use finder to create launch configuration to launch
selected tests when we get the ScalaTest Runner to support it.

Mirco Dotta

unread,
Feb 28, 2012, 10:17:06 AM2/28/12
to scala-...@googlegroups.com, Bill Venners
Hi Chee Seng,

Great to hear about your progresses!

> The finder will be used to detect selected test/scope from ScalaTest
> suite source file, style traits in ScalaTest (load from scalatest.jar
> in client project's classpath) will be annotated with @Style like
> this:-
>
> @Style("org.scalatest.finders.FunSuiteFinder")
> trait FunSuite extends Suite {
> ...
> }

Why not @Style(classOf[FunSuiteFinder]) ? Just wonder...


-- Mirco

Chee Seng Chua

unread,
Mar 3, 2012, 10:17:08 PM3/3/12
to scala-...@googlegroups.com
Hi Micro and Bill, 

We were using @Style(classOf[FunSuiteFinder]) when finders stuff were in scalatest.jar, but after it moved into scalatest-finders.jar, we would need to add the scalatest-finders.jar dependency in scalatest in order to use @Style(classOf[FunSuiteFinder]), it may be still ok to do so, just try to de-couple them.  Another reason is that it makes reading the style class easier using 'static' way in the AST, I am not sure in the presentation compiler AST (currently using reflection), but I have bad experience in retrieving the annotation in 'static' way while doing in IntelliJ AST, as Alex explained that they didn't fully implemented that yet as they don't need them for now.

Best Regards, 
Chee Seng


On Sat, Mar 3, 2012 at 3:56 AM, Bill Venners <bi...@artima.com> wrote:
Hi Chee Seng,

Say, can you answer Mirco's question? Is the reason because the class
may not be on the class path? That's my guess, but please let Micro
(and me too) know the real reason.

Thanks.

Bill


--

Mirco Dotta

unread,
Mar 5, 2012, 4:54:24 AM3/5/12
to scala-...@googlegroups.com

Hi Micro and Bill, 

We were using @Style(classOf[FunSuiteFinder]) when finders stuff were in scalatest.jar, but after it moved into scalatest-finders.jar, we would need to add the scalatest-finders.jar dependency in scalatest in order to use @Style(classOf[FunSuiteFinder]), it may be still ok to do so, just try to de-couple them.

I see. But I guess you could still have an overload of @Style that takes a Class, which could be used when the needed dependency is in the classpath.

Anyway, for the moment it is absolutely ok to pass a String to @Style, let's just keep this idea in mind and see in the future if we can find a way to pass a Class.

 Another reason is that it makes reading the style class easier using 'static' way in the AST, I am not sure in the presentation compiler AST (currently using reflection), but I have bad experience in retrieving the annotation in 'static' way while doing in IntelliJ AST, as Alex explained that they didn't fully implemented that yet as they don't need them for now.

I'm not sure I'm following this, can you elaborate more? Why do you mention IntelliJ AST? Are you trying to have a single ScalaTest-IDE core that you can plug in different IDEs (through different IDE-specific adapters)?


By the way, are you planning to attend Scala Days? I'd be happy to know you in person :)


Cheers,
  Mirco


---------------
Mirco Dotta
Typesafe - The software stack for applications that scale
PSE-D, 1015 Lausanne, Switzerland
Twitter: @mircodotta








Chee Seng Chua

unread,
Mar 6, 2012, 9:23:36 AM3/6/12
to Scala IDE Dev
Hi Micro,

I think adding an overload @Style that takes a Class is a good idea,
we could probably add that.

The Finders in ScalaTest is designed to be used by IDE/tools to
identify selected test(s).  The followings are how the Finders work in
short:-

1) Map/transform 'native' AST nodes in IDE/tools into unified AST
nodes understood by ScalaTest's Finders
2) Get finder class name for the selected suite, and instantiate the
finder.
3) Passed the mapped/transformed selected AST node to finder.find
method, it returns a Selection that contains:-
   - Suite Class Name
   - Display Name
   - Test Name(s)

For example, let's say we have the following:-

class ExampleSpec extends FeatureSpec {
  feature("feature 1") {
    scenario("scenario 1") {
    }
    scenario("scenario 2" {
    }
  }
  feature("feature 2") {
    scenario("scenario 1") {
    }
    scenario("scenario 2") {
    }
  }
}

When feature("feature 1") is right-clicked in the editor (get
selected), the AST node representing the method invocation of
'feature' will get passed into the finder.  The finder is instantiate
by looking in its super classes (in linearization order) with the
@Style annotation.  In this case, it will be looking at FeatureSpec
which has the following:-

@Style("org.scalatest.finders.FeatureSpecFinder")
trait FeatureSpec extends Suite {...}

It then instantiates "org.scalatest.finders.FeatureSpecFinder" and
call finder.find by passing in the selected AST node, and in the above
case the Selection returns will be:-

Suite Class Name = Fully qualified class name of ExampleSuite
Display Name = "feature 1"
Test Names = Array("feature 1 scenario 1", "feature 1 scenario 2")

If scenario("scenario 1") under feature("feature 1") get selected
instead, the Selection will be:-

Suite Class Name = Fully qualified class name of ExampleSuite
Display Name = "feature 1 scenario 1"
Test Names = Array("feature 1 scenario 1")

Note that only the jar that contains Finders implementation needs to
be included in the IDE plugin, and not the full scalatest.jar.  The
FeatureSpec in the above example should be loaded from client's
project classpath's scalatest.jar, thus if the client is using older
version of scalatest.jar that the FeatureSpec doesn't have the @Style
annotation yet, the specific test selection feature will not be
available (we may for example check if the scalatest.jar is 2.0 by
looking if some new class in 2.0 is loadable, if not it should
fallback to handle older version which allow selection of 'suite'
only, and not specific test/scope).


The style trait classes (FeatureSpec in the above example) comes from
a compiled jar file most of the time, and we need a way to get the
@Style annotation from it.  The simplest way is via reflection (using
it currently in eclipse plugin), in intellij I was trying to get it
using 'static' way:- from the AST directly.  I was trying to use
intellij PSI API to get the class name in the @Style, but without a
success (may be due to the class is loaded from a compiled jar file,
instead of source file - I am not sure).  The best I got was a plain
text of:-

@Style("org.scalatest.finders.FeatureSpecFinder")

So I parse the plain text to extract the finder class name out, I am
thinking that using @Style(classOf[FeatureSpecFinder]) may be harder
to parse, but I could be wrong.  As I am currently still using
reflection in eclipse plugin, do kindly enlighten me if there is a
better way to get the @Style info, perhaps using something from the
presentation compiler.

The reason for the creation of Finders is that we figured out that
selection in different style traits can be very different from one to
the other.  Furthermore we allow custom style traits to be created and
we want to allow custom style traits to have a way to write its own
finder that IDE/tools can recognize and use it.  The finder logic
depends on the style trait, so the creator of the style trait should
have the best knowledge to write the finder.

Sorry for the long email, just trying to explain where we are coming
from.  I hope my explanation isn't too bad, do feel free to let us
know what you think about the approach.  :)

I afraid I couldn't make it to Scala Days this year, but I think Bill
will.  I'd be happy to know you in person too, hopefully in near
future!  :)

Thanks!

Best Regards,
Chee Seng

On Mar 5, 5:54 pm, Mirco Dotta <mirco.do...@typesafe.com> wrote:
> > Hi Micro and Bill,
>
> > We were using @Style(classOf[FunSuiteFinder]) when finders stuff were in scalatest.jar, but after it moved into scalatest-finders.jar, we would need to add the scalatest-finders.jar dependency in scalatest in order to use @Style(classOf[FunSuiteFinder]), it may be still ok to do so, just try to de-couple them.
>
> I see. But I guess you could still have an overload of @Style that takes a Class, which could be used when the needed dependency is in the classpath.
>
> Anyway, for the moment it is absolutely ok to pass a String to @Style, let's just keep this idea in mind and see in the future if we can find a way to pass a Class.
>
> >  Another reason is that it makes reading the style class easier using 'static' way in the AST, I am not sure in the presentation compiler AST (currently using reflection), but I have bad experience in retrieving the annotation in 'static' way while doing in IntelliJ AST, as Alex explained that they didn't fully implemented that yet as they don't need them for now.
>
> I'm not sure I'm following this, can you elaborate more? Why do you mention IntelliJ AST? Are you trying to have a single ScalaTest-IDE core that you can plug in different IDEs (through different IDE-specific adapters)?
>
> By the way, are you planning to attend Scala Days? I'd be happy to know you in person :)
>
> Cheers,
>   Mirco
>
>
>
>
>
>
>
>
>
>
>
> > Best Regards,
> > Chee Seng
>

Chee Seng Chua

unread,
Mar 6, 2012, 9:26:39 AM3/6/12
to Scala IDE Dev
Hi Mirco,

Sorry about mis-spelling your name in previous emails! Typing too
many times the word 'micro' in daily work. ;)

Cheers,
Chee Seng

Mirco Dotta

unread,
Mar 7, 2012, 4:06:22 AM3/7/12
to scala-...@googlegroups.com
Don't you guys have a properties file that can be used to retrieve the version number 
(just like the scala library or compiler jars)

The style trait classes (FeatureSpec in the above example) comes from
a compiled jar file most of the time, and we need a way to get the
@Style annotation from it.  The simplest way is via reflection (using
it currently in eclipse plugin), in intellij I was trying to get it
using 'static' way:- from the AST directly.  I was trying to use
intellij PSI API to get the class name in the @Style, but without a
success (may be due to the class is loaded from a compiled jar file,
instead of source file - I am not sure).  The best I got was a plain
text of:-

@Style("org.scalatest.finders.FeatureSpecFinder")

So I parse the plain text to extract the finder class name out, I am
thinking that using @Style(classOf[FeatureSpecFinder]) may be harder
to parse, but I could be wrong.  As I am currently still using
reflection in eclipse plugin, do kindly enlighten me if there is a
better way to get the @Style info, perhaps using something from the
presentation compiler.

I see. I thought you could use the `FeatureSpec` symbol to retrieve its 
annotations (assuming you have a handle on the symbol). But I am no 
compiler expert, so you should check that Symbol do store annotations.

The reason for the creation of Finders is that we figured out that
selection in different style traits can be very different from one to
the other.  Furthermore we allow custom style traits to be created and
we want to allow custom style traits to have a way to write its own
finder that IDE/tools can recognize and use it.  The finder logic
depends on the style trait, so the creator of the style trait should
have the best knowledge to write the finder.

Sorry for the long email, just trying to explain where we are coming
from.  I hope my explanation isn't too bad, do feel free to let us
know what you think about the approach.  :)

I think it's very solid. Thank you for the detailed explanation! 


Cheers,
  Mirco

P.S. Don't worry about my name ;)

ijuma

unread,
Apr 1, 2012, 4:32:58 AM4/1/12
to scala-...@googlegroups.com
Hi Chee Seng,

Do you have a rough idea of when you will submit this code for integration?

Best,
Ismael

Chee Seng Chua

unread,
Apr 1, 2012, 9:40:13 PM4/1/12
to Scala IDE Dev, Bill Venners
Hi Ismael,

We are going to work on the view that display the running result this
week, it should be similar to the JUnit plugin one in look and when
clicked, it should enable user to hop to correct line number in the
source file. After completing the view I think we can do a pull
request.

Cheers,
Chee Seng

ijuma

unread,
Apr 4, 2012, 5:16:26 AM4/4/12
to scala-...@googlegroups.com, Bill Venners
On Monday, 2 April 2012 02:40:13 UTC+1, Chee Seng Chua wrote:
We are going to work on the view that display the running result this
week, it should be similar to the JUnit plugin one in look and when
clicked, it should enable user to hop to correct line number in the
source file.  After completing the view I think we can do a pull
request.

Excellent. Looking forward to it. :)

Best,
Ismael

ijuma

unread,
Jul 4, 2012, 3:31:08 AM7/4/12
to scala-...@googlegroups.com
Hi. Any updates on this?

Best,
Ismael

Chee Seng Chua

unread,
Jul 4, 2012, 11:14:16 PM7/4/12
to scala-...@googlegroups.com
Hi Ismael, 

We are doing full code review at the following repo:-


luc has given review comments here:-


I'll be back soon working on luc's review, hopefully we can move it to fully public soon.

Thanks.

Best Regards, 
Chee Seng

Chee Seng Chua

unread,
Jul 5, 2012, 5:05:08 AM7/5/12
to scala-...@googlegroups.com, Iulian Dragos, Chee Seng Chua, Matthew Farwell
Hi all, 

I am just trying to refresh my working copy, I git clone from https://github.com/skyluc/scalatest and trying to build with the following command:-

mvn clean install -Drepo.scala-ide=http://download.scala-ide.org/luc-scala-ide-1001056/site/ -P scala-ide-master-scala-2.9

but unfortunately I got a tycho error, complaining about parsing the OSGi MANIFEST (see attached), any idea what could be wrong?
error.txt

Chee Seng Chua

unread,
Jul 6, 2012, 1:06:58 AM7/6/12
to scala-...@googlegroups.com, Iulian Dragos, Matthew Farwell, Bill Venners, Luc Bourlier
Hi all, 

The above problem problem seems to be due to -Drepo.scala-ide=http://download.scala-ide.org/luc-scala-ide-1001056/site/ , running:-

mvn clean install -P scala-ide-master-scala-2.9

works, though there's a new compilation error in scalatest bundle due to accessing ClasspathManagement trait's classpath field that cause the build to fail, gonna try to fix it to see if I can get it to build correctly.

Thanks.

Best Regards, 
Chee Seng

Chee Seng Chua

unread,
Jul 6, 2012, 1:28:46 AM7/6/12
to scala-...@googlegroups.com, Iulian Dragos, Matthew Farwell, Bill Venners, Luc Bourlier
Hi all, 

I just checked in a fixed for the mentioned compilation error:-


Also, I removed the -Drepo.scala-ide=http://download.scala-ide.org/luc-scala-ide-1001056/site/ from the build command in README:-


I can build the project successfully now, am going to go through the review comments in pull request 4 to see what I can help.

Thanks!

Best Regards, 
Chee Seng

ijuma

unread,
Jul 6, 2012, 10:21:17 AM7/6/12
to scala-...@googlegroups.com
On Thursday, 5 July 2012 04:14:16 UTC+1, Chee Seng Chua wrote:
I'll be back soon working on luc's review, hopefully we can move it to fully public soon.

Great and thanks for the update.

Best,
Ismael

Chee Seng Chua

unread,
Jul 9, 2012, 9:26:55 AM7/9/12
to scala-...@googlegroups.com, Iulian Dragos, Chee Seng Chua, Matthew Farwell, Luc Bourlier, Bill Venners
Hi all, 

Just to update that I have gone through the list in https://github.com/skyluc/scalatest/pull/4 and made related changes.
Reply all
Reply to author
Forward
0 new messages