Angular DI in tests with jasmine-maven-plugin/HtmlUnit

2,048 views
Skip to first unread message

Mårten Dolk

unread,
Apr 26, 2011, 5:44:04 AM4/26/11
to Angular
Hi,

We're trying to get our angular/jasmine tests to run with Maven using
the jasmine-maven-plugin
(https://github.com/searls/jasmine-maven-plugin). I think we are
almost there - the trick is to use <preloadSources> to load
angular/angular-mocks in correct order before the tests. This setup
generates good test runners which executes flawless in the browser.
But when I run the tests from the command line and the tests executes
in the maven plugin (which uses HtmlUnit) i get an error like this:

1.) FooCntl it should add good from-date defaults <<< FAILURE!
* TypeError: Cannot read property "1" from null in
file:/.../js-lib/angular-0.9.15.patched.js (line 2367)

Which corresponds to the 'forEach'-line in this method:

var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /^\s*(((\$?).+?)(_?))\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function injectionArgs(fn) {
assertArgFn(fn);
if (!fn.$inject) {
var args = fn.$inject = [];
var fnText = fn.toString().replace(STRIP_COMMENTS, '');
var argDecl = fnText.match(FN_ARGS);
forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
arg.replace(FN_ARG, function(all, name, injectName, $, _){
assertArg(args, name, 'after non-injectable arg');
if ($ || _)
args.push(injectName);
else
args = null; // once we reach an argument which is not
injectable then ignore
});
});
}
return fn.$inject;
}

Looks to me like HtmlUnit does not behaive as expected by angular
regarding fn.toString()? Any suggestions how to fix this are welcome.

(I can work around this by instead of using "angular.scope();
scope.$new(FooCntl);" to setup my controller use "new FooCntl()", but
that gets ugly very fast when you need to inject dependencies.)

Thanks!
/Mårten

Mårten Dolk

unread,
Apr 26, 2011, 7:35:40 AM4/26/11
to Angular
Solved this :-)

Problem was that FN_ARGS did not match multiline string.

fnArgs looked like this:
"
function () {
return arguments.length ? fn.apply(self,
curryArgs.concat(slice.call(arguments, 0, arguments.length))) :
fn.apply(self, curryArgs);
}
"

Note the newline in the beginning of the line. Adding the multiline
modifier to FN_ARGS solved the issue for me:
- var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/;
+ var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/m;


/Mårten


2011/4/26 Mårten Dolk <marte...@gmail.com>:

Miško Hevery

unread,
Apr 26, 2011, 11:48:28 AM4/26/11
to ang...@googlegroups.com
The multiline is not needed in the browsers, so i am guessing that rhino, which is what the HTML unit uses treats the regexp differently. In any case I a glad that you resolved it. Keep a list of all of the things you had to change and perhaps we could patch it back to main.

Sent from my iPad

> --
> You received this message because you are subscribed to the Google Groups "Angular" group.
> To post to this group, send email to ang...@googlegroups.com.
> To unsubscribe from this group, send email to angular+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/angular?hl=en.
>

Mårten Dolk

unread,
Apr 27, 2011, 7:03:24 AM4/27/11
to ang...@googlegroups.com
This is the only issue I have run into this far. But I will keep a
list of the changes and probably create a pull request.

/mårten

2011/4/26 Miško Hevery <misko....@gmail.com>:

Mårten Dolk

unread,
Jul 1, 2011, 11:10:12 AM7/1/11
to ang...@googlegroups.com
Run into a new problem when migrating to angular-0.9.17. This time in
angular-mocks.js. The mock implementation of $exceptionHandler needs
the {$inject:[]} argument to angular.service or my jasmine spec runner
will throw an Error "Unknown provider for 'e'." This is the fixed
version:

angular.service('$exceptionHandler', function(e) {
return function(e) {throw e;};
}, {$inject:[]});

I will create a demo project using Java server-side, Angular in
browser, and Maven to build and execute tests and put it on github. I
hope I will have time to do this Monday and create a pull request with
my issues.

/Mårten

2011/4/27 Mårten Dolk <marte...@gmail.com>:

David Yu

unread,
Jul 1, 2011, 11:29:04 AM7/1/11
to ang...@googlegroups.com
On Fri, Jul 1, 2011 at 11:10 PM, Mårten Dolk <marte...@gmail.com> wrote:
Run into a new problem when migrating to angular-0.9.17. This time in
angular-mocks.js. The mock implementation of $exceptionHandler needs
the {$inject:[]} argument to angular.service or my jasmine spec runner
will throw an Error "Unknown provider for 'e'." This is the fixed
version:

angular.service('$exceptionHandler', function(e) {
 return function(e) {throw e;};
}, {$inject:[]});

I will create a demo project using Java server-side, Angular in
browser, and Maven to build and execute tests and put it on github. I
hope I will have time to do this Monday and create a pull request with
my issues.
Cool.  Looking forward to it. 
You received this message because you are subscribed to the Google Groups "angular" group.

To post to this group, send email to ang...@googlegroups.com.
To unsubscribe from this group, send email to angular+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/angular?hl=en.




--
When the cat is away, the mouse is alone.
- David Yu

Igor Minar

unread,
Jul 1, 2011, 9:25:17 PM7/1/11
to ang...@googlegroups.com
On Fri, Jul 1, 2011 at 8:10 AM, Mårten Dolk <marte...@gmail.com> wrote:
Run into a new problem when migrating to angular-0.9.17. This time in
angular-mocks.js. The mock implementation of $exceptionHandler needs
the {$inject:[]} argument to angular.service or my jasmine spec runner
will throw an Error "Unknown provider for 'e'." This is the fixed
version:

angular.service('$exceptionHandler', function(e) {
 return function(e) {throw e;};
}, {$inject:[]});

good find! the issue can actually be resolved by simply dropping the "e" argument from the factory function:
 
angular.service('$exceptionHandler', function() {
 return function(e) {throw e;};
});

I was wondering why our unit tests didn't reveal this and found that there was a configuration error that caused the scripts to load in wrong order during tests and that resulted in this error going unnoticed. Fortunately there were no other issues covered by this config error.

There is however an unrelated issue in angular-mocks.js that I just fixed. You can fetch angular-mocks.js with both fixes from here:



I will create a demo project using Java server-side, Angular in
browser, and Maven to build and execute tests and put it on github. I
hope I will have time to do this Monday and create a pull request with
my issues.

Sounds good. Let us know when you are ready to share it.

/i

jmilkiewicz

unread,
Jul 4, 2011, 8:35:53 AM7/4/11
to angular
Marten, I am also looking for your demo. Pls update the thread if it
is ready.

regards Jakub


On Jul 1, 11:29 am, David Yu <david.yu....@gmail.com> wrote:
> On Fri, Jul 1, 2011 at 11:10 PM, Mårten Dolk <marten.d...@gmail.com> wrote:
> > Run into a new problem when migrating to angular-0.9.17. This time in
> > angular-mocks.js. The mock implementation of $exceptionHandler needs
> > the {$inject:[]} argument to angular.service or my jasmine spec runner
> > will throw an Error "Unknown provider for 'e'." This is the fixed
> > version:
>
> > angular.service('$exceptionHandler', function(e) {
> >  return function(e) {throw e;};
> > }, {$inject:[]});
>
> > I will create a demo project using Java server-side, Angular in
> > browser, and Maven to build and execute tests and put it on github. I
> > hope I will have time to do this Monday and create a pull request with
> > my issues.
>
> Cool.  Looking forward to it.
>
>
>
>
>
>
>
>
>
>
>
> > /Mårten
>
> > 2011/4/27 Mårten Dolk <marten.d...@gmail.com>:
> > > This is the only issue I have run into this far. But I will keep a
> > > list of the changes and probably create a pull request.
>
> > > /mårten
>
> > > 2011/4/26 Miško Hevery <misko.hev...@gmail.com>:
> > >> The multiline is not needed in the browsers, so i am guessing that
> > rhino, which is what the HTML unit uses treats the regexp differently. In
> > any case I a glad that you resolved it. Keep a list of all of the things you
> > had to change and perhaps we could patch it back to main.
>
> > >> Sent from my iPad
>
> > >> On Apr 26, 2011, at 4:35 AM, Mårten Dolk <marten.d...@gmail.com> wrote:
>
> > >>> Solved this :-)
>
> > >>> Problem was that FN_ARGS did not match multiline string.
>
> > >>> fnArgs looked like this:
> > >>> "
> > >>> function () {
> > >>>    return arguments.length ? fn.apply(self,
> > >>> curryArgs.concat(slice.call(arguments, 0, arguments.length))) :
> > >>> fn.apply(self, curryArgs);
> > >>> }
> > >>> "
>
> > >>> Note the newline in the beginning of the line. Adding the multiline
> > >>> modifier to FN_ARGS solved the issue for me:
> > >>> - var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/;
> > >>> + var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/m;
>
> > >>> /Mårten
>
> > >>> 2011/4/26 Mårten Dolk <marten.d...@gmail.com>:

Mårten Dolk

unread,
Jul 6, 2011, 10:24:20 AM7/6/11
to ang...@googlegroups.com
Hi all!

I have my example project using Maven to build an Angular web-app with
Java backend up on github here:
https://github.com/mdolk/angular-java-server-midi

I also created a pull request with what I needed to change in Angular
to make this work, here:
https://github.com/angular/angular.js/pull/453

/Mårten


2011/7/4 jmilkiewicz <jmilk...@gmail.com>:

Igor Minar

unread,
Jul 22, 2011, 2:47:45 AM7/22/11
to ang...@googlegroups.com
wow!

"... Then open http://localhost:8080/ and play the piano" - You actually mean playing a "real" piano in the browser!

anyway... where does Rhino (HtmlUnit) come into play here?

/i

Mårten Dolk

unread,
Jul 22, 2011, 3:36:38 AM7/22/11
to ang...@googlegroups.com
jasmine-maven-plugin uses HtmlUnit which uses Rhino to headless
execute the jasmine specs during the build. If the tests fails you can
open the manual test runner in the browser and work on your code. But
then you are obviously not running the tests in Rhino anymore. That's
how I found the issue, running headless from mvn in command line and
the tests failed. But running the tests in a browser worked.

We are using it because it can report test results in the junit xml
format which is a defacto standard for CI servers in Java, hence we
get good integration with Hudson/Jenkins.

/mårten

2011/7/22 Igor Minar <iim...@gmail.com>:

Igor Minar

unread,
Jul 22, 2011, 3:44:25 AM7/22/11
to ang...@googlegroups.com
We use js-test-driver on our ci build. There isn't any fancy
integration, but we are able to run the tests in real browsers, which
is a must for us.

http://ci.angularjs.org/job/angular.js-angular-master/

/i

Mårten Dolk

unread,
Jul 22, 2011, 3:55:38 AM7/22/11
to ang...@googlegroups.com
We are planning to look into that. Right now we are using selenium to
do our end-to-end testing. We are coming the a lot of infrastructure
and experience in place and can't change it all over night :-)

Igor Minar

unread,
Jul 22, 2011, 4:01:03 AM7/22/11
to ang...@googlegroups.com
right, I'm not rushing you :-)

btw JSTestDriver (jstd) is primarily designed to run unit tests. we
however managed to get our e2e test runner to work on jstd as well.

/i

Dan Doyon

unread,
Jul 22, 2011, 11:39:13 AM7/22/11
to ang...@googlegroups.com
My analogy for these sorta tech transitions is "changing the tires as you drive down the road" -- not for the faint of heart, however, with existing tests in place, it certainly helps you sleep at night--

-- dan

Sent from my iPhone

Chris

unread,
Jul 23, 2011, 12:03:44 AM7/23/11
to angular
How do you typically run the e2e tests using JSTestDriver (jstd)? What
is the additional configuration that you do? Do you do something
simple like adding "- test/e2e/*.js" to jsTestDriver.conf or are
there additional configuration steps?

Chris

On Jul 22, 4:01 pm, Igor Minar <iimi...@gmail.com> wrote:
> right, I'm not rushing you :-)
>
> btw JSTestDriver (jstd) is primarily designed to run unit tests. we
> however managed to get our e2e test runner to work on jstd as well.
>
> /i
>
>
>
>
>
>
>
> On Fri, Jul 22, 2011 at 12:55 AM, Mårten Dolk <marten.d...@gmail.com> wrote:
> > We are planning to look into that. Right now we are using selenium to
> > do our end-to-end testing. We are coming the a lot of infrastructure
> > and experience in place and can't change it all over night :-)
>
> > /mårten
>
> > 2011/7/22 Igor Minar <iimi...@gmail.com>:
> >> We use js-test-driver on our ci build. There isn't any fancy
> >> integration, but we are able to run the tests in real browsers, which
> >> is a must for us.
>
> >>http://ci.angularjs.org/job/angular.js-angular-master/
>
> >> /i
>
> >> On Fri, Jul 22, 2011 at 12:36 AM, Mårten Dolk <marten.d...@gmail.com> wrote:
> >>> jasmine-maven-plugin uses HtmlUnit which uses Rhino to headless
> >>> execute the jasmine specs during the build. If the tests fails you can
> >>> open the manual test runner in the browser and work on your code. But
> >>> then you are obviously not running the tests in Rhino anymore. That's
> >>> how I found the issue, running headless from mvn in command line and
> >>> the tests failed. But running the tests in a browser worked.
>
> >>> We are using it because it can report test results in the junit xml
> >>> format which is a defacto standard for CI servers in Java, hence we
> >>> get good integration with Hudson/Jenkins.
>
> >>> /mårten
>
> >>> 2011/7/22 Igor Minar <iimi...@gmail.com>:
> >>>> wow!
> >>>> "... Then open http://localhost:8080/ and play the piano" - You actually
> >>>> mean playing a "real" piano in the browser!
> >>>> anyway... where does Rhino (HtmlUnit) come into play here?
>
> >>>> /i
>
> >>>> On Wed, Jul 6, 2011 at 7:24 AM, Mårten Dolk <marten.d...@gmail.com> wrote:
>
> >>>>> Hi all!
>
> >>>>> I have my example project using Maven to build an Angular web-app with
> >>>>> Java backend up on github here:
> >>>>>https://github.com/mdolk/angular-java-server-midi
>
> >>>>> I also created a pull request with what I needed to change in Angular
> >>>>> to make this work, here:
> >>>>>https://github.com/angular/angular.js/pull/453
>
> >>>>> /Mårten
>
> >>>>> 2011/7/4 jmilkiewicz <jmilkiew...@gmail.com>:
> >>>>> To unsubscribe from this group, send email to...
>
> read more »

Igor Minar

unread,
Jul 23, 2011, 1:09:03 AM7/23/11
to ang...@googlegroups.com
The instructions are in the adapter file:
http://code.angularjs.org/0.9.17/jstd-scenario-adapter-0.9.17.js

/i

iwein...@gmail.com

unread,
Aug 1, 2012, 7:41:09 AM8/1/12
to ang...@googlegroups.com
I've upgraded Mårten's project to angular 1.0.1 and then bumped into the following error:

* JavaException: java.lang.IllegalArgumentException: argument type mismatch in file:/Users/iwein/projects/mdolk-angular-java-server-midi-22a9a25/target/jasmine/src/lib/angular-1.0.1.js (line 1448)

What causes this exactly? Does anyone know any workarounds for that?

Iwein

Dan

unread,
Aug 22, 2012, 1:09:57 AM8/22/12
to ang...@googlegroups.com, iwein...@gmail.com
I ran into the same issue. I don't know what the problem is, but I saw that that code had to do with their JQLite stuff. So, I just included jQuery with my tests, and then got past this. Hope this helps.

scott...@gmail.com

unread,
Oct 19, 2012, 2:41:49 PM10/19/12
to ang...@googlegroups.com, iwein...@gmail.com, dnchris...@gmail.com
how did you include jquery? like this?
<preloadSources>
  <source>lib/jquery-1.8.2.js</source>
  <source>lib/angular-1.0.1.js</source>
  <source>lib/angular-mocks-1.0.1.js</source>
</preloadSources>

it is not working for me

dsan...@rapilabs.com

unread,
Oct 31, 2012, 11:12:31 AM10/31/12
to ang...@googlegroups.com, iwein...@gmail.com, dnchris...@gmail.com, scott...@gmail.com
I was also able to resolve this issue by using jQuery instead of JQLite.  I wasn't using preloadSources though as I was using require.js and setup the shim config to get jquery to load before angular.
Reply all
Reply to author
Forward
0 new messages