I wonder how I can do the following things in Leiningen (if this is the idiomatic way to solve it):
I'd like to move my integration tests from the unit tests located in
the test folder to another folder, say integration-test. I suppose that this means that I have to configure Leiningen to add integration-test to the "test classpath".
I'd like to create a new task that executes only the integration tests
I'd like to hook in the new integration test task to the install task
I'm using Midje as test library (if that matters).
After some investigation I've managed to find a solution that I'm pleased with. First off all Midje provide filters that allows you to tag a fact with a keyword. You can then run tagged facts like this:
lein midje :filters it
This will run facts that are tagged with the :it keyword.
Next we can add a new folder for our integration tests in Leiningen:
:test-paths ["test" "itest"]
The itest folder will now be picked up by Leiningen and added to classpath.
If we find it hard to remember to write lein midje :filters it everytime we run our integration tests we can add an alias to Leiningen:
:aliases {"itest" ["midje" ":filters" "it"]}
I've also written a blog about this with some more details if anyone is interested.
Related
I'm trying to use test support classes within my tests. I want these classes to be available for all different test types.
My directory structure is as follows;
/test/functional
/test/integration
/test/unit
/test/support
I have test helper classes within the /test/support folder that I would like to be available to each of the different test types.
I'm using GGTS and I've added the support folder to the classpath. But whenever I run my integration tests running 'test-app' I get a compiler 'unable to resolve class mypackage.support.MyClass
When I run my unit tests from within GGTS the support classes are found and used. I presume this is because the integration tests run my app in its own JVM.
Is there any way of telling grails to include my support package when running any of my tests?
I don't want my test support classes to be in my application source folders.
The reason that it works for your unit tests inside the IDE is that all source folders get compiled into one directory, and that is added to your classpath along with the jars GGTS picks up from the project dependencies. This is convenient but misleading, because it doesn't take into account that Grails uses different classpaths for run-app and each of the test phases, which you see when you run the integration tests. GGTS doesn't really run the tests; it runs the same grails test-app process that you do from the commandline, and captures its output and listens for build events so it can update its JUnit view.
It's possible to add extra jar files to the classpath for tests because you can hook into an Ant event and add it to the classpath before the tests start. But the compilation process is a lot more involved and it looks like it would be rather ugly/hackish to get it working, and would likely be brittle and stop working in the future when the Grails implementation changes.
Here are some specifics about why it'd be non-trivial. I was hoping that you could call GrailsProjectTestCompiler.compileTests() for your extra directory, but you need to compile it along with the test/unit directory for unit tests and the test/integration directory for integration tests, and the compiler (GrailsProjectTestCompiler) presumes that each test phase only needs to compile that one directory. That compiler uses Gant, and each test phase has its own Grailsc subclass (org.grails.test.compiler.GrailsTestCompiler and org.grails.test.compiler.GrailsIntegrationTestCompiler) registered as taskdefs. So it should be possible to subclass them and add logic to compile both the standard directory and the shared directory, and register those as replacements, but that requires also subclassing and reworking GrailsProjectTestRunner (which instantiates GrailsProjectTestCompiler), and hooking into an event to replace the projectTestRunner field in _GrailsTest.groovy with your custom one, and at this point my brain hurts and I don't want to think about this anymore :)
So instead of all this, I'd put the code in src/groovy and src/java, but in test-specific packages that make it easy to exclude the compiled classes from your WAR files. You can do that with a grails.war.resources closure in BuildConfig.groovy, e.g.
grails.war.resources = { stagingDir ->
println '\nDeleting test classes\n'
delete(verbose: true) {
// adjust as needed to only delete test-specific classes
fileset dir: stagingDir, includes: '**/test/**/*.class'
}
println '\nFinished deleting test classes\n'
}
I am attempting to use lein-autodoc, because I believe it to be the preferred documentation generator for Clojure. I have added :dev-dependencies [[lein-autodoc "0.9.0"]] to my project definition as per the instructions on the lein-autodoc github page.
Running lein deps runs without issue, however lein autodoc fails, claiming that autodoc is not a task.
I suspect the issue is that lein-autodoc is set up to work with leiningen 1. However, I'm using leiningen 2. Is there an alternate way I should be calling lein with autodoc? Or is the lein-autodoc package not set up to work with lein 2? If not, is there another preferred lein2-compatible documentation generation option?
EDIT:
After Cubic's hint below, I created ~/.lein/profiles.clj as follows:
{:user {:plugins [[lein-autodoc "0.9.0"]]}}
Now, running lein autodoc results in the following:
$ lein autodoc
Exception in thread "main" java.lang.IllegalAccessError: sh does not exist
at clojure.core$refer.doInvoke(core.clj:3778)
at clojure.lang.RestFn.applyTo(RestFn.java:139)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_lib.doInvoke(core.clj:5279)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:603)
at clojure.core$load_libs.doInvoke(core.clj:5298)
(...)
This suggests perhaps autodoc is not compatible with Lein 2? If not, is there any doc system that works with Lein 2?
autodoc used to be the more common documentation generator, but these days it is mostly just used for Clojure itself (and is optimized for the task). I highly recommend that you use codox instead. It is excellent. You can see it in action in one of my own projects here
(I know this has been said in the other answer, but for my answer to be complete I need to add it anyways)
Also, in leiningen 2 there is no :dev-dependencies key. Instead, there is a :dev profile. Take a look at the Leiningen profile documentation for more information. In this case, all you need to do is add a :plugins key to your project or global user profile with the plugins you want (like codox, autodoc, etc).
There is no :dev-dependencies in lein 2, you'd have to do it with profiles.
I'm not sure whether autodoc actually works with lein 2 though. Keep in mind that clojure and it's environment grows pretty fast, and there's lots of outdated information out there.
I want to write some unit tests that run within Adobe CQ 5.4. I am doing what is described in this article for testing within CQ:
http://jtoee.com/2011/09/799/
However, after I create the unit test class in my Java code, it won't compile within CRXDE because it can't resolve the org.junit namespaces. I installed and activated the JUnit bundle in Felix as described (Apache Sling JUnit Core), but I am guessing there is something else I need to do in order for this active Felix bundle to be found in CRXDE. The Felix bundle in the CQ5 instance I am connected to shows these exported packages:
junit.framework,version=4.8.2
org.apache.sling.junit,version=1.0.7.SNAPSHOT
org.apache.sling.junit.annotations,version=1.0.7.SNAPSHOT
org.junit,version=4.8.2
org.junit.matchers,version=4.8.2
org.junit.rules,version=4.8.2
org.junit.runner,version=4.8.2
org.junit.runner.manipulation,version=4.8.2
org.junit.runner.notification,version=4.8.2
org.junit.runners,version=4.8.2
org.junit.runners.model,version=4.8.2
In this sample unit test code below, the last three import statements "cannot be resolved."
import org.apache.sling.api.resource.*;
import org.junit.*;
import org.junit.runner.*;
import org.apache.sling.junit.annotations.*;
#RunWith(SlingAnnotationsTestRunner.class)
public class MyUnitTest {
public ResourceResolver getResourceResolver() {
try {
return getResourceResolverFactory().
getAdministrativeResourceResolver(null);
} catch (LoginException e) {
fail(e.toString());
}
return null;
}
}
It is my novice understanding that the OSGI bundle installed in Felix should be accessible for me to reference in my Java classes using CRXDE, but it isn't happening for the JUnit bundle I installed. Why not? What do I need to do to get CRXDE to find the OSGI bundle reference and compile within CRXDE?
What you're doing looks correct at first sight.
Did you try restarting CQ after installing the required bundles? In theory that should not be required but I'm wondering if the bundle compiler is picking up the newly available packages correctly.
I have uploaded a content package with a similar simple example at http://dl.dropbox.com/u/715349/cq5-examples/junit-tests-1.0.zip (md5 2915123ad581aa225bd531247ea02878), after installing this package on a fresh CQ 5.4 instance the example test is correctly executed via http://localhost:4502/system/sling/junit/
You might want to try my sample and compare with yours.
Short Answer
The problem is not with CQ, the problem is with CRXDE. CRXDE automatically downloads and caches required jar files on your local machine so they don't have to be retrieved constantly from CQ.
If you switch to the 'Package Explore' navigation and then expand the project '{SERVER}{PORT}{HASH}' you should see a folder called Referenced Libraries. Right click and select Build Path >> Configure Build Path. From there you can add any dependencies you want into the project.
Long Answer
CRXDE is not a good tool for creating bundles. It is much better to create bundles through a full fledged IDE such as Eclipse and utilize Apache Maven as a build tool. Apache Maven can automatically manage your dependencies, run tests on your code and separate test vs. runtime dependencies.
That way you can avoid having to load dependencies that you don't really need such a jUnit into your OSGi console and you have more control over how your bundle is built and deployed.
Day has a really nice guide to getting you set up with building CQ projects with Eclipse.
http://dev.day.com/docs/v5_2/html-resources/cq5_guide_developer/ch04s02.html
here is a very specific question re the clojure class path and lein / emacs
lets say I'm working with a project and have a repl with clojure-jack-in. I need to add a new dependency to this project, is there any way to run lein deps and then be able to use the downloaded .jar in the open repl right away (possibly a repl command?)?
right now whenever I need to add a new dependency I need to reset the swank/slime connection for it to become visible in the classpath.
Thanks
I see three options:
Use Jark to start a REPL on a JVM that can handle new jar files at runtime (http://icylisper.in/jark/index.html)
add-classpath method in clojure (breaks sometimes ... http://groups.google.com/group/clojure/browse_thread/thread/43a413ae55ed25d0)
Write your own code to add the new jar file (http://groups.google.com/group/clojure/browse_thread/thread/0095ea6e918c430e)
For some reason I can't get clojure REPL working with jline, what i did was git clone the clojure repository off github then run ant to build it, then i download jline-0.9.94.jar to the directory with clojure.jar, then run the following command:
java -cp jline-0.9.94.jar:clojure.jar jline.ConsoleRunner clojure.main
And get the following errors:
Exception in thread "main" java.lang.ClassNotFoundException: clojure.main
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:317)
at java.lang.ClassLoader.loadClass(ClassLoader.java:252)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:375)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:164)
at jline.ConsoleRunner.main(Unknown Source)
Here are the files in my current directory:
vvshs-macbook-2:clojure vvsh$ ls
build.xml clojure-sources-1.2.0-master-SNAPSHOT.jar epl-v10.html src
classes clojure-sources.jar jline-0.9.94.jar test
clojure-1.2.0-master-SNAPSHOT.jar clojure.iml pom-template.xml
clojure-slim-1.2.0-master-SNAPSHOT.jar clojure.jar pom.xml
clojure-slim.jar doc readme.txt
vvshs-macbook-2:clojure vvsh$
I got the same error on clojure 1.1 and lein repl(it seems lein maintain its own version of clojure).
By the way, this is on mac ox 10.5.8
java version "1.5.0_24"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_24-b02-357-9M3165)
Java HotSpot(TM) Client VM (build 1.5.0_24-149, mixed mode, sharing)
Anybody know what's wrong and how to fix it? As I really want to get lein repl working to start a project.
I solved the same problem today by removing a redundant jline*.jar from /Library/Java/Extensions, leaving just one jline installation in CLASSPATH.
Longer explanation: I was trying to build labrepl, which installs all its dependencies in subdirectory lib, but I had previously set up jline by copying the .jar file to /Library/Java/Extensions. Apparently, java.lang.ClassLoader couldn't handle two installations of jline, and as long as there were ones available in two places, the command line starting a Clojure REPL would fail finding the latter one of classes jline.ConsoleRunner and clojure.main, depending on the order they were given to the java command.
I hope this helps.
see my alternative instructions for install on my fork:
http://github.com/jedschneider/leiningen
I sent a pull request to update the readme, but didn't get a response on it. once you have lein installed, you can put the bin/leiningen.sh in your ~/bin and call it anywhere. i put a shortcut on my .bash_profile
alias lein="~/bin/leiningen.sh"
and then call lein repl to launch a shell
also checkout the labrepl which is a great learning tool.
http://github.com/relevance/labrepl
Your java ... command looks fine, I'd double check if all the jars are where you think they should be (and that they are the jars you think they are, i.e. clojure.jar is actually the one you built locally and not some super-outdated one).
If you want to use Leiningen for lein repl, that's possible too. Note that it isn't accurate to say that it "maintains its own version of Clojure"; Leiningen is a build tool, used as part of a project-oriented workflow, and the separate Clojure jars are project-specific. To create a sample project to play around in, say lein new foo someplace convenient. Then you'll need to cd foo, get your Clojure & contrib jars with lein deps (the project.clj skeleton provided by lein new already contains entries for both) and start a REPL with lein repl.
Finally, you could use the new cljr project; it has a comprehensive README which should get you started in no time, and with it you'll be able to say cljr repl to get a Clojure REPL anywhere, without the need to create a "project".
I met the same problem. jline.ConsoleRunner (at least about jline-0.9.5 which I use) seems not to be able to find class files in the path added to class search paths from -cp option of 'java' command. It means it can't find neither classes in your current directory. I solved this by copying clojure.main under /Library/Java/Extensions/ too.