Tuesday, January 20, 2015

Angular JS & Jasmine - Creating a sample application & running tests on functions

Angular Js & Jasmine work together to define the UI coding and unit testing framework of modern times 



I am exploring a sample application which demonstrates :

1. Necessary plumbing for making a simple angular js application work.
2. Defining unit tests.
3. Passing values in unit test mocks to test functions in developed code.


The following files are essential for the framework -

1. app.js - (holds the app module & controller module)
2. index.html - (view for your application)
3. style.css -  (for styling)
4. jasmine-test.js - (test framework code)
5. jasmine-test-runner.html - (test configuration)

You might need to download a framwork like npm to execute angular code and run tests via karma on jasmine. Karma can be installed using npm commands.


1. app.js

var app = angular.module('app', []);

angular.module('app')
  .controller('MainCtrl', function($scope) {
    $scope.title = 'Median Calculator App';
    var items =[];
    var medianVal ={};
    $scope.medianVal = medianVal;
    $scope.items = items;
    $scope.apply;
   
   $scope.addItem = function(item) {
   
    /** Module to add items on the list **/
    $scope.items.push(item);
    $scope.item = {};
   }
    $scope.apply;
   
    $scope.getCurrentMedian = function median(items) {

    /** Module to calculate median **/
    $scope.sortedItems = items.sort( function(a,b) {return a - b;} );
   
    $scope.medianVal ='';
     
    var half = Math.floor(items.length/2);
   
    if(items.length % 2) {
          $scope.medianVal = items[half];
     
    }
    else {
         $scope.medianVal = (parseInt(items[half-1])+parseInt(items[half]))/2.0;
      }        
       
        return $scope.medianVal;
    }
  });

2. index.html

<!DOCTYPE html>
<html ng-app="app">

<head>
  <link data-require="bootstrap-css@*" data-semver="3.2.0" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" />
  <link rel="stylesheet" href="style.css" />
</head>

<body ng-controller="MainCtrl">
  <h1>{{title}}</h1>
  <form>
    <label for="Value">Add Value:</label>
    <input type="number" name="value" ng-model="item.value" ng-validate="integer" class="my-input" size="5">
    <input type="Button" value="Add" ng-click="addItem(item.value)" />
  </form>
  <hr />
  <section>
    <input type="Button" value="Get Median! " ng-click="getCurrentMedian(items)" />
    Current Median: <pre> {{medianVal}}</pre>
    <!-- display current media here-->
   
    Values entered : <pre> {{items}}</pre>

  </section>

  <hr>
  <a href="jasmine-test-runner.html">Run Unit Tests</a>
  <script data-require="angular.js@*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular.js"></script>
  <script src="app.js"></script>
</body>

</html>

3. style.css

/* Styles go here */


  .my-input {
    webkit-transition:all linear 0.5s;
    transition:all linear 0.5s;
    background: transparent;
  }
  .my-input.ng-invalid {
    color:white;
    background: red;
  }


4. jasmine-test.js

var controller, scope;

beforeEach(module('app'));

beforeEach(inject(function($controller, $rootScope) {
     scope = $rootScope.$new();
     controller = $controller('MainCtrl', {
          $scope: scope
     });
}));

describe("Sample Test Suite", function() {

  it("sample thrutiness test", function() {
    expect(true).toBeTruthy();
  });

});

describe("Get Current Median", function() {

    it("should calculate median for even set", function() {
      
        var inputargs  = [5,1,-7,7,8,3];
        
        var answer = scope.getCurrentMedian(inputargs);
       
        expect(answer).toEqual(4);

    });
    
    it("should calculate median for odd set", function() {
      
        var inputargs  = [5,1,-7,7,8,3,9];
        
        var answer = scope.getCurrentMedian(inputargs);
       
        expect(answer).toEqual(5);

    });

});

5. jasmine-test-runner.html

<!DOCTYPE html>
<html>
<head>
  <link data-require="jasmine@*" data-semver="2.0.0" rel="stylesheet" href="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.css" />
  <script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine.js"></script>
  <script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/jasmine-html.js"></script>
  <script data-require="jasmine@*" data-semver="2.0.0" src="//cdn.jsdelivr.net/jasmine/2.0.0/boot.js"></script>
  <script data-require="angular.js@*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular.js"></script>
  <script data-require="angular.js@*" data-semver="1.3.5" src="https://code.angularjs.org/1.3.5/angular-mocks.js"></script>
  <script src="app.js"></script>
  <script src="jasmine-test.js"></script>
  <!-- add tests file references here if need be-->
  
  <!-- documentation for jasmine can be found at http://jasmine.github.io/2.0/introduction.html -->
</head>
<body></body>
</html>


All the configuration parameters for libraries point to environments on the internet.

You may also use the plunkr environment to run the configuration for a quick run and test of functions.


For command-line, you can use -

npm install
(to install the application)

npm start
 (to start the application, check the results in a web browser)

npm run test-single-run
 (to run one set of the tests)

Pardon me for the brevity on blogging due to lack of time but I think I tried to cover the important aspects for a newbie.

I will cover the steps on configuration of angular & jasmine on a standalone in a separate blog.