Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 83 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# AngularJS Style Guide

*Opinionated AngularJS style guide for Liberty Seguros Compania de Seguros y Reaseguros S.A. (lu.pl) teams
*Opinionated AngularJS style guide for Liberty Seguros Compania de Seguros y Reaseguros S.A. (lu.pl) teams.*

If you are looking for an opinionated style guide for syntax, conventions, and structuring AngularJS applications, then step right in. These styles are based on my development experience with [AngularJS](//angularjs.org), presentations, [Pluralsight training courses](http://pluralsight.com/training/Authors/Details/john-papa) and working in teams.

Expand Down Expand Up @@ -2329,6 +2329,88 @@ Unit testing helps maintain clean code, as such I included some of my recommenda

*Why?*: Sinon makes it easier to toggle between Jasmine and Mocha, if you want to try both.

### Stubbing and Matching Promises
###### [Style [C001](#style-c001)]

- Use [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true) along with [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers).

*Why?*: To avoid cluttering and improve readability of your tests.

```javascript
// src/main/calculator/direct/security/authentication.js
angular
.module('calculator.direct.security', [])
.factory('authentication', authenticationFactory);

authenticationFactory.$inject = ['$http'];

function authenticationFactory($http) {
var service = {
getCurrentUser: getCurrentUser
};

/**
* @name getCurrentUser
* @desc Returns currently authenticated user.
* @returns {Object.<Promise>} resolved to object representing authenticated user or null
*/
function getCurrentUser() {
return $http.get('/authentication/current-user').then(function (response) {
// NB promise chaining in action
return response.data;
});
}

return service;
}
```

```javascript
// src/test/calculator/direct/security/authentication.spec.js
describe('authentication service', function () {

var $rootScope, $httpBackend, $q, authentication;

beforeEach(function () {
module('calculator.direct.security');
inject(function (_$rootScope_, _$httpBackend_, _$q_, _authentication_) {
$rootScope = _$rootScope_;
$httpBackend = _$httpBackend_;
$q = _$q_;
authentication = _authentication_;
});
});

it('should return currently authenticated user', function () {
$httpBackend.whenGET('/authentication/current-user')
.respond({id: 123, email: 'mtyson@lu.pl'});

expect(authentication.getCurrentUser())
.toBeResolvedWith({id: 123, email: 'mtyson@lu.pl'});

$httpBackend.flush();
$rootScope.$digest(); // actually resolve promise(s)
});

it('should stub/mock returned promise', function () {
spyOn(authentication, 'getCurrentUser').and
.returnResolvedPromise($q, {id: 123, email: 'mtyson@lu.pl'});

expect(authentication.getCurrentUser())
.toBeResolvedWith({id: 123, email: 'mtyson@lu.pl'});

$rootScope.$digest(); // actually resolve promise(s)
});

});

```

- Note: The `toBeResolvedWith` matcher provided by [jasmine promise matchers](https://github.com/bvaughn/jasmine-promise-matchers),
and the `returnResolvedPromise` spy strategy defined by [jasmine promise spy strategies](assets/jasmine-promise-spy-strategies.js?raw=true).

- Note: Similarly, you can use the `toBeRejectedWith` matcher as well as the `returnRejectedPromise` spy strategy.

### Headless Browser
###### [Style [Y194](#style-y194)]

Expand Down
20 changes: 20 additions & 0 deletions assets/jasmine-promise-spy-strategies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

beforeEach(function () {

jasmine.SpyStrategy.prototype.returnResolvedPromise = function (promiseApi, resolvedValue) {
return this.callFake(function () {
var deferred = promiseApi.defer();
deferred.resolve(resolvedValue);
return deferred.promise;
});
};

jasmine.SpyStrategy.prototype.returnRejectedPromise = function (promiseApi, rejectValue) {
return this.callFake(function () {
var deferred = promiseApi.defer();
deferred.reject(rejectValue);
return deferred.promise;
});
};
});