aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgor Minar2012-03-16 10:48:59 -0700
committerIgor Minar2012-03-16 10:52:40 -0700
commitf13dd3393dfb7a33565c9360342c193bc0bddcb6 (patch)
treefcf54fb63bb30dcf9e131c8d34d440b626019fa9
parentbca96e7c7cc723a091241fddd6845d6de262a3c9 (diff)
downloadangular.js-f13dd3393dfb7a33565c9360342c193bc0bddcb6.tar.bz2
feat(injector): infer _foo_ as foo
this is to enable nicer tests: describe('fooSvc', function() { var fooSvc; beforeEach(inject(function(_fooSvc_) { fooSvc = _fooSvc_; })); it('should do this thing', function() { //test fooSvc }); });
-rw-r--r--docs/content/guide/dev_guide.di.understanding_di.ngdoc97
-rw-r--r--src/Injector.js4
-rw-r--r--test/InjectorSpec.js6
3 files changed, 105 insertions, 2 deletions
diff --git a/docs/content/guide/dev_guide.di.understanding_di.ngdoc b/docs/content/guide/dev_guide.di.understanding_di.ngdoc
index dd6dda03..9b48585c 100644
--- a/docs/content/guide/dev_guide.di.understanding_di.ngdoc
+++ b/docs/content/guide/dev_guide.di.understanding_di.ngdoc
@@ -87,6 +87,103 @@ minifiers/obfuscators. In the future, we may provide a pre-processor which will
code and insert the `$inject` into the source code so that it can be minified/obfuscated.
+### Dependency inference and variable name shadowing
+
+During inference, the injector considers argument names with leading and trailing underscores to be
+equivivalent to the name without these underscores. For example `_fooSvc_` argument name is treated
+as if it was `fooSvc`, this is useful especially in tests where variable name shadowing can cause
+some friction. This is best illustrated on examples:
+
+When testing a service, it's common to need a reference to it in every single test. This can be
+done in jasmine with DI inference like this:
+
+<pre>
+describe('fooSvc', function() {
+ it('should do this thing', inject(function(fooSvc) {
+ //test fooSvc
+ }));
+
+ it('should do that thing', inject(function(fooSvc) {
+ //test fooSvc
+ }));
+
+ // more its
+});
+</pre>
+
+... but having to inject the service over and over gets easily tiresome.
+
+It's likely better to rewrite these tests with a use of jasmine's `beforeEach`:
+
+<pre>
+describe('fooSvc', function() {
+ var fooSvc;
+
+ beforeEach(inject(function(fooSvc) {
+ fooSvc = fooSvc; // DOESN'T WORK! outer fooSvc is being shadowed
+ }));
+
+ it('should do this thing', function() {
+ //test fooSvc
+ });
+
+ it('should do that thing', function() {
+ //test fooSvc
+ });
+
+ // more its
+});
+</pre>
+
+This obviously won't work because `fooSvc` variable in the describe block is being shadowed by the
+`fooSvc` argument of the beforeEach function. So we have to resort to alternative solutions, like
+for example use of array notation to annotate the beforeEach fn:
+
+<pre>
+describe('fooSvc', function() {
+ var fooSvc;
+
+ beforeEach(inject(['fooSvc', function(fooSvc_) {
+ fooSvc = fooSvc_;
+ }]));
+
+ it('should do this thing', function() {
+ //test fooSvc
+ });
+
+ it('should do that thing', function() {
+ //test fooSvc
+ });
+});
+</pre>
+
+
+That's better, but it's still annoying, especially if you have many services to inject.
+
+To resolve this shadowing problem, the injector considers `_fooSvc_` argument names equal to
+`fooSvc`, so the test can be rewritten like this:
+
+<pre>
+ describe('fooSvc', function() {
+ var fooSvc;
+
+ beforeEach(inject(function(_fooSvc_) {
+ fooSvc = _fooSvc_;
+ }));
+
+ it('should do this thing', function() {
+ //test fooSvc
+ });
+
+ it('should do that thing', function() {
+ //test fooSvc
+ });
+
+ // more its
+ });
+</pre>
+
+
## Related Topics
* {@link dev_guide.services Angular Services}
diff --git a/src/Injector.js b/src/Injector.js
index 10072959..1844db2a 100644
--- a/src/Injector.js
+++ b/src/Injector.js
@@ -40,7 +40,7 @@
var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/m;
var FN_ARG_SPLIT = /,/;
-var FN_ARG = /^\s*(.+?)\s*$/;
+var FN_ARG = /^\s*(_?)(.+?)\1\s*$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function inferInjectionArgs(fn) {
assertArgFn(fn);
@@ -49,7 +49,7 @@ function inferInjectionArgs(fn) {
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){
+ arg.replace(FN_ARG, function(all, underscore, name){
args.push(name);
});
});
diff --git a/test/InjectorSpec.js b/test/InjectorSpec.js
index cc5c5b50..16cf1524 100644
--- a/test/InjectorSpec.js
+++ b/test/InjectorSpec.js
@@ -147,6 +147,12 @@ describe('injector', function() {
});
+ it('should strip leading and trailing underscores from arg name during inference', function() {
+ function beforeEachFn(_foo_) { /* foo = _foo_ */ };
+ expect(inferInjectionArgs(beforeEachFn)).toEqual(['foo']);
+ });
+
+
it('should handle no arg functions', function() {
function $f_n0() {}
expect(inferInjectionArgs($f_n0)).toEqual([]);