/jangular

Jasmine matchers for AngularJS framework

Primary LanguageJavaScriptMIT LicenseMIT

JAngular

Jasmine matchers for AngularJS and UI-Router

Examples are written in Coffeescript.

Usage

$ npm install jangular-matchers

List of matchers

Service

Controller

State

HTTP Service matchers

Every sample Jasmine matcher for AngularJS HTTP service will be enclosed in the following describe code section:

describe 'sample http service matchers', ->
  
  # make the matchers available
  beforeEach ->
    jasmine.addMatchers jangular_matchers

  # initialize module
  beforeEach ->
    module 'sample.module'

  # inject the http service (SUT)
  beforeEach inject (sampleHttpService) =>
    @subject = sampleHttpService

  # after every test assert for no pending expectations & requests
  afterEach inject ($httpBackend) ->
    $httpBackend.verifyNoOutstandingExpectation()
    $httpBackend.verifyNoOutstandingRequest()

  # (every test will be placed here)    
  it 'example spec', =>
    expect(true).toEqual true

Every sample AngularJS HTTP service operation will be enclosed in the following Coffeescript class:

sampleHttpService = ($http) ->
  class SampleHttpService
  
    # (operations will be listed here)
    example_operation: ->
        $http.get '/some_uri'

  new SampleHttpService

angular.module('sample.module').factory 'sampleHttpService', ['$http', sampleHttpService]

to_get()

Ensures that the service operation issues a GET to a given URI.

spec

  it 'GETs a given URI', =>
    expect(@subject.do_get).to_get '/data'

impl

    do_get: ->
      $http.get '/data'

to_unwrap_get()

Ensures that the service operation unwraps the response body on success.

spec

  it 'GETs unwraps the response', =>
    expect(@subject.do_get_and_unwrap).to_unwrap_get()

impl

    do_unwrap: ->
      $http.get('/any_path').then (reply) -> reply.data

to_get_and_unwrap()

Ensures that the service operation issues a GET to a given URI and unwraps the response body on success.

spec

  it 'GETs a given URI and unwraps the response', =>
    expect(@subject.do_get_and_unwrap).to_get_and_unwrap '/data'

impl

    do_get_and_unwrap: ->
      $http.get('/data').then (reply) -> reply.data

to_post()

Ensures that the service operation issues a POST to a given URI.

spec

  it 'POSTs a given URI', =>
    expect(@subject.do_post).to_post '/post', firstname: 'Olivia', lastname: 'Lago'

impl

    do_post: ->
      $http.post '/post', firstname: 'Olivia', lastname: 'Lago'

to_unwrap_post()

Ensures that the service operation unwraps the response body on success.

spec

  it 'POST unwraps the response', =>
    expect(@subject.do_post_and_unwrap).to_unwrap_post()

impl

    do_post_and_unwrap: ->
      $http.post('/post', firstname: 'Olivia', lastname: 'Lago').then (reply) -> reply.data

to_post_and_unwrap()

Ensures that the service operation issues a POST to a given URI and unwraps the response body on success.

spec

  it 'POST a given URI and unwraps the response', =>
    expect(@subject.do_post_and_unwrap).to_post_and_unwrap '/post', firstname: 'Olivia', lastname: 'Lago'

impl

    do_post_and_unwrap: ->
      $http.post('/post', firstname: 'Olivia', lastname: 'Lago').then (reply) -> reply.data

Controller matchers

These matchers are not exclusively for AngularJS controllers, they may be used in other AngularJS services as well. Every sample Jasmine matcher for AngularJS controller will be enclosed in the following describe code section:

describe 'sample controller matchers', ->
  
  # make the matchers available
  beforeEach -> 
    jasmine.addMatchers jangular_matchers

  # initialize module
  beforeEach -> 
    module 'sample.module'

  # create controller and inject dependencies
  beforeEach inject ($controller, sampleHttpService) =>
    @subject = $controller 'SampleController'
    @sampleHttpService = sampleHttpService
    
  # (example specs listed here)
  it 'example spec', =>
    expect(true).toEqual true

Every sample AngularJS controller operation will be enclosed in the following Coffeescript class:

class SampleController
  constructor: (@sampleHttpService) ->

  # (sample operations listed here)
  some_sample_operation: =>
    console.log 'Hello I am an AngularJS controller!'

to_call_service()

Ensures that the controller operation calls the given service operation without arguments.

spec

  it 'calls a service', =>
    expect(@subject.do_service_call).to_call_service @sampleHttpService, 'do_get'

impl

  do_service_call: =>
    @sampleHttpService.do_get()

to_call_service_with()

Ensures that the controller operation calls the given service operation with the provided arguments.

spec

  it 'calls a service with parameters', =>
    expect(=> @subject.do_service_call_with_params 1, 2, 3).to_call_service_with @sampleHttpService, 'do_get_with', 1, 2, 3

  it 'calls a service with hash parameters', =>
    expect(=> @subject.do_service_call_with_hash_params a: 1, b: 2, c: 3).to_call_service_with @sampleHttpService, 'do_get_with_hash', x: 1, y: 2, z: 3

impl

  do_service_call_with_params: (a, b, c) =>
    @sampleHttpService.do_get_with a, b, c

  do_service_call_with_hash_params: ({a, b, c}) =>
    @sampleHttpService.do_get_with_hash x: a, y: b, z: c

to_subscribe_success()

Ensures that the controller operation subscribes to promise on success (completion) with the provided operation.

spec

  it 'subscribes to promise success', =>
    expect(@subject.do_subscribe).to_subscribe_success @sampleHttpService, 'do_get', @subject.do_get_success

impl

  do_subscribe: =>
    @sampleHttpService.do_get().then @do_get_success

  do_get_success: ->

to_subscribe_error()

Ensures that the controller operation subscribes to promise on failure (rejection) with the provided operation.

spec

  it 'subscribes to promise error', =>
    expect(@subject.do_subscribe_to_error).to_subscribe_error @sampleHttpService, 'do_get', @subject.do_get_fails

impl

  do_subscribe_to_error: =>
    @sampleHttpService.do_get().then (->), @do_get_fails

  do_get_fails: ->

to_subscribe()

Ensures that the controller operation subscribes to promise on success (completion) and failure (rejection) at the same time with the provided operations.

spec

  it 'subscribes to success & error', =>
    expect(@subject.do_full_subscribe).to_subscribe @sampleHttpService, 'do_get', @subject.do_get_success, @subject.do_get_fails

impl

  do_full_subscribe: =>
    @sampleHttpService.do_get().then @do_get_success, @do_get_fails

  do_get_success: ->

  do_get_fails: ->

to_callback_success_with()

Ensures that the controller operation callbacks the provided operation directly or indirectly when then promise success (completion). The difference between to_subscribe_success() and to_subscribe() with respect to to_callback_success_with() is the indirection level. to_callback_success_with() allows indirect calls, so is more flexible. The with suffix demands for arguments during the callback.

spec

  it 'callbacks the function when promise success with given parameters', =>
    expect(@subject.do_callback).to_callback_success_with @sampleHttpService, 'do_get', @subject, 'do_get_success_with', 1, 2, 3

impl

Notice the indirection on the subscription using an anonymous function that calls the expected operation:

  do_callback: =>
    @sampleHttpService.do_get().then => @do_get_success_with(1, 2, 3)

  do_get_success_with: =>

to_callback_error_with()

Ensures that the controller operation callbacks the provided operation directly or indirectly when then promise fails (rejection). The difference between to_subscribe_error() and to_subscribe() with respect to to_callback_error_with() is the indirection level. to_callback_error_with() allows indirect calls, so is more flexible. The with suffix demands for arguments during the callback.

spec

  it 'callbacks the function when promise fails with given parameters', =>
    expect(@subject.do_failing_callback).to_callback_error_with @sampleHttpService, 'do_get', @subject, 'do_get_fails_with', 1, 2, 3

impl

Notice the indirection on the subscription using an anonymous function that calls the expected operation:

  do_failing_callback: =>
    @sampleHttpService.do_get().then (->), => @do_get_fails_with 1, 2, 3

  do_get_fails_with: =>

UI Router State matchers

These matchers are designed for AngularJS when it is combined with UI-Router. Every sample Jasmine matcher for UI-Router state will be enclosed in the following describe code section:

describe 'sample ui.router state matchers', ->

  # make the matchers available
  beforeEach ->
    jasmine.addMatchers jangular_matchers

  # initialize module
  beforeEach ->
    module 'sample.module'

  # (example specs listed here)
  it 'example spec', =>
    expect(true).toEqual true

Every UI-Router state definition will be enclosed in the following config function:

config = ($stateProvider) ->
  # here state configuration for the module takes places, for instance:
  $stateProvider.state 'some_state', {}


angular.module('sample.module').config config

to_be_an_state()

Ensures that actual subject is an UI-Router state object or alternatively an state name.

spec

  describe 'stateA', =>

    # inject ui.router $state helper and get the state object
    beforeEach inject ($state) =>
      @subject = $state.get 'stateA'

    it 'is an state, using object variant', => expect(@subject).to_be_an_state()
    it 'is an state, using string variant', => expect('stateA').to_be_an_state()

impl

  $stateProvider.state 'stateA', {}

to_be_abstract()

Ensures that actual subject is an abstract UI-Router state. It can be use in both variants: object and string with state name.

spec

  describe 'stateB', =>

    beforeEach inject ($state) =>
      @subject = $state.get 'stateB'

    it 'is an abstract, using object variant', => expect(@subject).to_be_abstract()
    it 'is an abstract, using string variant', => expect('stateB').to_be_abstract()

impl

  $stateProvider.state 'stateB',
    abstract: yes

to_have_url()

Ensures that UI-Router state has an expected URL. It can be use in both variants: object and string with state name.

spec

  describe 'stateC', =>
    beforeEach inject ($state) =>
      @subject = $state.get 'stateC'

    it 'has an URL, using object variant', => expect(@subject).to_have_url '/some_url'
    it 'has an URL, using string variant', => expect('stateC').to_have_url '/some_url'

impl

  $stateProvider.state 'stateC',
    url: '/some_url'

to_have_controller()

Ensures that UI-Router state has an expected controller. It can be use in both variants: object and string with state name.

spec

  describe 'stateC', =>
    beforeEach inject ($state) =>
      @subject = $state.get 'stateC'

    it 'has controller, using object variant', => expect(@subject).to_have_controller 'SomeUserController'
    it 'has controller, using string variant', => expect('stateC').to_have_controller 'SomeUserController'

impl

  $stateProvider.state 'stateC',
    url: '/some_url'
    controller: 'SomeUserController'

to_have_controller_alias()

Ensures that UI-Router state has an expected controller alias. It can be use in both variants: object and string with state name.

spec

  describe 'stateC', =>
    beforeEach inject ($state) =>
      @subject = $state.get 'stateC'

    it 'has controller alias, using object variant', => expect(@subject).to_have_controller_alias 'suc'
    it 'has controller alias, using string variant', => expect('stateC').to_have_controller_alias 'suc'
    it 'has controller alias, using object variant', => expect(@subject).to_have_controller_as 'suc'
    it 'has controller alias, using string variant', => expect('stateC').to_have_controller_as 'suc'
   

impl

  $stateProvider.state 'stateC',
    url: '/some_url'
    controller: 'SomeUserController'
    controllerAs: 'suc'

to_have_template()

Ensures that UI-Router state has an expected template. It can be use in both variants: object and string with state name.

spec

  describe 'stateD', =>
    beforeEach inject ($state) =>
      @subject = $state.get 'stateD'

    it 'has a template, using object variant', => expect(@subject).to_have_template '<div id="some_template"></div>'
    it 'has a template, using string variant', => expect('stateD').to_have_template '<div id="some_template"></div>'

impl

  $stateProvider.state 'stateD',
    template: '<div id="some_template"></div>'

to_have_template_url()

Ensures that UI-Router state has an expected template URL. It can be use in both variants: object and string with state name.

spec

  describe 'stateE', =>
    beforeEach inject ($state) =>
      @subject = $state.get 'stateE'

    it 'has a template URL, using object variant', => expect(@subject).to_have_template_url '/templates/footer.html'
    it 'has a template URL, using string variant', => expect('stateE').to_have_template_url '/templates/footer.html'

impl

  $stateProvider.state 'stateE',
    templateUrl: '/templates/footer.html'

to_resolve_by_calling_service()

Ensures that UI-Router state resolves a given promise before entering. The expected promise resolution should take place by issuing an service call without arguments.

spec

  describe 'stateF', =>
    beforeEach inject ($state, @sampleHttpService) =>
      @subject = $state.get 'stateF'

    it 'resolves the promise by calling service without arguments', =>
      expect(@subject.resolve.user_profile).to_resolve_by_calling_service @sampleHttpService, 'do_get'

impl

  $stateProvider.state 'stateF',
    resolve:
      user_profile: ['sampleHttpService', (sampleHttpService) -> sampleHttpService.do_get()]

to_resolve_by_calling_service_with()

Ensures that UI-Router state resolves a given promise before entering. The expected promise resolution should take place by issuing an service call with the given arguments.

spec

  describe 'stateG', =>
    beforeEach inject ($state, @sampleHttpService) =>
      @subject = $state.get 'stateG'

    it 'resolves the promise by calling service with arguments', =>
      expect(@subject.resolve.user_history).to_resolve_by_calling_service_with @sampleHttpService, 'do_get_with', 1, 'a', true

impl

  $stateProvider.state 'stateG',
    resolve:
      user_history: ['sampleHttpService', (sampleHttpService) -> sampleHttpService.do_get_with 1, 'a', true]