<!DOCTYPE html>
<html>
<head>
<link data-require="jasmine@1.3.1" data-semver="1.3.1" rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css" />
<!-- Include the Jasmine, JQuery and Angular libraries. -->
<script data-require="jasmine@1.3.1" data-semver="1.3.1" src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script data-require="jasmine@1.3.1" data-semver="1.3.1" src="//cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>
<script data-require="angular.js@1.2.16" data-semver="1.2.16" src="https://code.angularjs.org/1.2.16/angular.js"></script>
<script data-require="jquery@2.0.3" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
<script data-require="json2@*" data-semver="0.0.2012100-8" src="//cdnjs.cloudflare.com/ajax/libs/json2/20121008/json2.js"></script>
<!-- angular-mocks.js is required for our unit tests. -->
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.16/angular-mocks.js"></script>
<!-- The application whose directive we're testing. -->
<script src="myApplication.js"></script>
<!-- Our Jasmine tests. -->
<script src="myTests.js"></script>
<!-- Let's get started! -->
<script src="jasmineBoot.js"></script>
</head>
<body></body>
</html>
describe('directiveUsingAsyncService', function(){
var elementUnderTest;
var deferredResolution;
var parentScope;
beforeEach(module('app'));
beforeEach(angular.mock.inject(function($compile, $rootScope, $q, AsyncService ) {
// $q.defer() returns an object that packages a promise together with
// methods to resolve or reject it. We will use this variable to manually
// resolve the promise at the right moment.
deferredResolution = $q.defer();
// Replace the AsyncService.promiseToDoSomething() with a spy that
// returns the promise inside our $q.defer() object.
spyOn(AsyncService,'promiseToDoSomething')
.andReturn(deferredResolution.promise);
// Add the directive we want to test to the DOM.
elementUnderTest = angular.element('<directive-using-async-service></directive-using-async-service>');
parentScope = $rootScope.$new();
$compile(elementUnderTest)(parentScope);
$('body').append(elementUnderTest);
parentScope.$apply();
}));
afterEach(function() {
$(elementUnderTest).remove();
});
var getCurrentText = function () {
return $(elementUnderTest).text();
}
it('says "Waiting..." before the async method completes', function() {
// We have not yet resolved deferToResolveCallToAsyncService.promise,
// so the directive should behave as if the service call has not completed.
expect(getCurrentText()).toBe("Waiting...");
});
it('says "Done!" after the async method completes', function() {
// Pretend that the AsyncService.promiseToDoSomething has completed.
deferredResolution.resolve("Here's your data!");
// Need to run a digest cycle. Angular's asynchronous methods such as
// $http.get generally do this for you, but our method does no such favor.
parentScope.$apply();
expect(getCurrentText()).toBe("Done!");
});
});
angular.module('app',[])
.service('AsyncService', function ($q) {
// Like Angular's $http.get, this function returns a promise.
this.promiseToDoSomething = function() {
return $q.when('Promise fulfilled!');
};
})
.directive('directiveUsingAsyncService', function() {
return {
restrict: 'E',
scope: {},
controller: ['$scope', 'AsyncService', function ($scope, asyncService) {
// The text to which this directive's <p> element binds changes from
// "Waiting..." to "Done!" when the async operation completes.
$scope.text = 'Waiting...';
// Like Angular's $http.get, this function returns a promise.
asyncService.promiseToDoSomething().then( function() {
$scope.text = 'Done!';
});
}],
template: '<p>{{text}}</p>'
};
});
// Runs the Jasmine 1.3.1 tests.
// Jasmine 2.0 provides this functionality in its boot.js.
(function () {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var trivialReporter = new jasmine.TrivialReporter();
jasmineEnv.addReporter(trivialReporter);
jasmineEnv.specFilter = function (spec) {
return trivialReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function () {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();