searls / jasmine-maven-plugin

Maven plugin to execute Jasmine Specs. Creates your HTML runners for you, runs headlessly, outputs JUnit XML
http://searls.github.io/jasmine-maven-plugin
Other
290 stars 163 forks source link

Allow for AMD modules #33

Closed grignaak closed 12 years ago

grignaak commented 13 years ago

I would like to have support for AMD modules in my jasmine tests.

This requires a little different setup of the specs and runner code.

I have a suggested solution for running jasmine:bdd, but I have yet to dig into how to run jasmine:test

Background

AMD modules are a common way to write maintainable JavaScript applications. Common implementations are require.js, almond, & CommonJS.

For example, a source file could look like this:

// my_module.js
define(['lib/dependency1', './dependency2'], function(dep1, dep2) {
   ...
   return MyModule;
});

And a spec would be written like this:

// my_module_spec.js
require(['my_module'], function(MyModule) {
    describe('my module's tests', function () {
      // regular old jasmine tests using MyModule
    });
});

That means the generated html driver needs to look something like this:

<script src="main/lib/require.js"/></script><!-- This is a preloadSource -->
<script>
   require([ // this is an array of all the _test_ sources
        'test/my_module_test.js',
        'test/my_other_test.js'
   ], function () {
        // regular jasmine runner code
   });
</script>

The problem and possible solution

The example runner only provides a $sources$ variable that prints out both the app sources and the test sources as html script tags. What I need is this to be a javascript array of only the test sources.

As I said at the beginning, I don't know what it would take to make this work with jasmine:test.

johannish commented 13 years ago

I'll second this request! A workaround is to create a customRunnerTemplate in which the $sources$ variable is removed, and the app sources are hard-coded, as well as specifying require in sourceIncludes like <include>require.js</include>. Then use require as in your example.

However, because the paths are all hard-coded, this can only be made to work for either the maven build, or the jasmine:bdd plugin (or maybe both if your directory structure matches the default: /src and /spec).

As grignaak mentions, having a $sources$ variable and a separate $specs$ variable would provide a solution to this issue.

ebaxt commented 13 years ago

I'm currently working on adding this feature. It currently supports Require.js, but I've tried to make it easy to add other loaders.

Have a look at this example:

require.js-support

Basically I've refactored out the ScriptRunnerHtmlGenerator into an abstract class, and added a Default implementation and a RequireJs impl that uses different templates. The example above works with both the test goal and the jasmine:bdd.

I'm currently testing the plugin in one of our projects, and if it's stable I'll open a pull request.

ebaxt commented 12 years ago

I've added support for more advanced configuration:

jasmine-webapp-advanced-requirejs

Since there are literally millions of ways to configure scriptloaders like require.js, I think the best way to add this feature is to make it configurable within reason. The example shows how one can wrap dependencies like jQuery, and use the order plugin to evaluate scripts in the correct order. (For example jQuery needs to be resolved before any plugins etc.)

Feedback on where to draw the line when it comes to configurability is welcomed!

timowest commented 12 years ago

I am getting Mismatched anonymous define() exceptions when running a Backbone + require.js app via jasmine:test.

I am using version 1.0.2-beta-5 of the plugin. Are these issues also fixed in the newer SNAPSHOT releases?

ebaxt commented 12 years ago

@timowest 1.0.2-beta-5 does not support require.js, I've added support in this branch https://github.com/ebaxt/jasmine-maven-plugin/tree/advancedRequirejsExample but haven't opened a pull request yet because of lacking documentation. Also that branch uses a bundled requires.js script, but it makes more sense to bring your own version and let the plugin refere to that (since you need requires.js to load scripts in the first place).

We are using this branch in our system and it's been stable, so once I've resolved the issues mentioned above, I'll open a pull request. In the mean time you can look at this example to get it working: https://github.com/ebaxt/jasmine-maven-plugin/tree/advancedRequirejsExample/src/test/resources/examples/jasmine-webapp-advanced-requirejs

timowest commented 12 years ago

@ebaxt Thanks, I managed to fix the issue temporarily by wrapping the test execution in the runner HTML via require.

ebaxt commented 12 years ago

Here is the pull request: https://github.com/searls/jasmine-maven-plugin/pull/50

aceontech commented 12 years ago

I've been struggling with this issue myself recently, and I'm glad to see you're working on this :-).

kshaff03 commented 12 years ago

Thanks for working on this. This would be an immense help for me.

searls commented 12 years ago

I've merged in @ebaxt's pull request. The next release will include the feature.