Issue
I am attempting to change locale in a Jasmine unit test for AngularJS (being run through Karma) using angular-dynamic-local.
describe('currency filter', function () {
var currencyFilter;
var tmhDynamicLocale;
beforeEach(function () {
module('tmh.dynamicLocale');
inject(function ($injector) {
var $filter = $injector.get('$filter');
currencyFilter = $filter('currency');
tmhDynamicLocale = $injector.get('tmhDynamicLocale');
});
});
it('formats US currency in standard form', function () {
expect(currencyFilter(50.17)).toBe("$50.17");
});
it('formats French Canadian value with $ at end and comma for decimal', function () {
tmhDynamicLocale.set('fr-ca');
expect(currencyFilter(50.17)).toBe("50,17$");
});
});
The second test fails:
Expected '$50.17' to be '50,17$'.
The locale was never changed. The console indicates a 404 error:
WARN [web-server]: 404: /angular/i18n/angular-locale_fr-ca.js
It appears that this URL path, which is recognized when running the application in the browser, is not recognized when running through Karma.
What am I missing?
Solution
Finally solved. We have several things going on here.
I was not loading the locale in karma.conf.js. I had tried loading the fr-ca locale in karma.conf.js once before, but I had deleted the line because it was breaking the default (US) test. Turns out that I need to load the en-us locale as well (and then reset the locale in beforeEach as we will see in #4).
files: [ ... 'bower_components/angular-i18n/angular-locale_en-us.js', 'bower_components/angular-i18n/angular-locale_fr-ca.js', ... ],
As martinoss correctly stated, I needed to change the locale location pattern. In a direct test of the currency filter, this is difficult, since there is no module on which to change tmhDynamicLocale's provider. In my real-world situation, this is not an issue, since I am testing a custom filter that is wrapping the currency filter. For the purposes of this post, I created a brain-dead wrapper filter:
(function() { angular .module('currencyFilterWrapper', [ 'tmh.dynamicLocale' ]) .config(['tmhDynamicLocaleProvider', function(tmhDynamicLocaleProvider) { tmhDynamicLocaleProvider.localeLocationPattern('base/bower_components/angular-i18n/angular-locale_{{locale}}.js'); }]) .filter('doCurrency', doCurrency) ; function doCurrency($filter) { return function(input) { return $filter('currency')(input); } } })();
These first two items addressed the 404 problem. But the French-Canadian locale specifies a space before the $-sign, so I changed the assertion to
expect(currencyFilter(50.17)).toBe("50,17 $");
But that didn't work either. The currency filter is actually inserting a non-breaking space. So the correct assertion isexpect(currencyFilter(50.17)).toBe("50,17\u00A0$");
tmhDynamicLocale.set is asynchronous. Also, we need to reset the locale to the default (US) before each test. So here is the complete spec (using Jasmine 1.3):
describe('currency filter', function () { var currencyFilter; var tmhDynamicLocale; function setLocale(locale) { var localeSet; runs(function () { tmhDynamicLocale.set(locale) .then(function () { localeSet = true; }); }); waitsFor(function () { return localeSet; }, 'setting locale', 100); } beforeEach(function () { module('currencyFilterWrapper'); module('tmh.dynamicLocale'); inject(function ($injector) { var $filter = $injector.get('$filter'); currencyFilter = $filter('doCurrency'); tmhDynamicLocale = $injector.get('tmhDynamicLocale'); }); setLocale('en-us'); }); it('formats US currency in standard form', function () { expect(currencyFilter(50.17)).toBe("$50.17"); }); it('formats French Canadian value with $ at end and comma for decimal', function () { setLocale('fr-ca'); runs(function () { expect(currencyFilter(50.17)).toBe("50,17\u00A0$"); }); }); });
Answered By - Daniel Steinberg
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.