Translate

Monday 18 June 2018

Single page web app to single file web app

If the concept of a single page website was a novelty, then the single file web app is a wonder.

Without using the commonly used terms for describing the single file web app, let me describe what the file does -

1. it listens to a request using the HTTP or the https protocol and can respond with JSON. Is it a REST API?
2. it can contain multiple route handlers for a web request. A web server?
3. it is written in plain javascript or es6. A node.js web app?
4. it uses express.js to handle the request, response. A node.js web server?
5. it spins itself up as and when required to serve requests. Wait! Is it an appEngine?
6. it provides for modular services. Ok! Is it microservices?
7. it is a function that can handle web requests hosted on the cloud.

Alright, it is a lambda function or a cloud function.

What the Google Cloud Function (GCF) does as a FaaS (Function as a Service) is well-documented but it is in the enhancement of the DX (Developer eXperience) that the GCF scores hugely.

For an architect, it helps ensure that there are no async calls on the main app.js file, or promises used that don't get fulfilled because the app.js is the main server file that is only concerned about setting up the server and to start listening after running through a sequence of synchronous flow.

Like the moron in the '3 idiots' movie (Hindi movie) who simply rattles off memorized words, from a prepared speech in an unknown language, as it got interpreted in its mind, without bothering to understand the meaning of the sentences used, the app.js file in the node.js, expressjs context, simply runs through all the statements, dumbly - its sole purpose being to reach the end of the file for the magical server.listen statement!

Not so with the GCF.

The GCF simply spins up, executes the lines, intelligently, and once the request, response cycle is done, it shuts down by itself. So, no worries about load testing or listening to requests when there are none as in the app.js context or bothering about server resources! The GCF is a serverless server.

The GCF handles thens and catchs but most importantly, with its ability to act as a route handler, with the help of Firebase-functions, it completes the requirement for the most robust, lean web server - a single file web server. The GCF, by itself, cannot handle/parse parameters or query strings passed via the URL, but with firebase, it can!

Here is a simple GCF [Edit: link removed] - Edit: One of the pitfalls is managing the connections in a cloud function as each time, a new container instance may execute the Cloud function causing new connections with the Cloud Database server so, it becomes more than challenging to keep or share db connections!

Of course, the workaround is the infamous "Allow access from anywhere" option but then this is where the prudence in using something like a firebase library lies because it enables authorization token to be submitted in the request URL and so the infamous workaround may actually become an ideal workaround if not the solution.

And yes, with the GCF, you can query external databases in other cloud regions like a Mongodb Atlas database and the speed of the response is phenomenal! 

Thursday 3 May 2018

A binary converter in typescript and a reference to blockchain

While writing a binary to a decimal converter in Typescript, I came across the idea of using the example of a class of students in which every student is given a binary value and asked to convert it to a decimal value.

Add a little imagination to the idea and you can come up with an interesting parallel of how a BlockChain node functions - imagine a guy not sure if the steps that he has used to convert a binary to a decimal value is correct or not and asks the nearest neighboring girl for the answer and she gives him the SHA256 hash value of, let's say, 268 (the solution), the decimal equivalent of 100001100, which is 8b496bf96bbcc9e5ac11c068b6cfb00c32f9d163bb8a3d5af107217499de997a!

Now, the guy has the hash value and knows that till his steps yield the decimal value whose sha256 hash value matches the hash given to him, he must process the steps. This, in effect, explains what happens in mining a blockchain node.

Anyway, the code is as below: (Edit: a note on refactoring: although the code has been written with a unit test and the test was written first, it is only partially refactored, for reasons of obfuscating the logic.

Point is, many bots or maybe just humans ;) mine for code but don't bother to even leave a note of thanks and when I noticed this way back in the early 2000s, I did not bother to correct Blogger's tendency to eat up the angular brackets as used in C code where the #include statements require the < and > and even changed all the return statements to return 1 instead of 0. Make them think, don't you think? :))

// binaryconverter.ts

export default class BinaryConverter{
convertBinaryToDecimal(n){
let z=1,b=0,val=0, zeroFlag=false
b=n.length-1
for (let a in n){
var num=0
for (num=b;num>0;num--){
z*=2*n[a]
}
if (num==b){
z=0
zeroFlag=true
}
else if (num!=b){
val+=z
z=1
}
b--
}
if (zeroFlag==true && n[n.length-1]==1)val++
return val;
}
}

and the mocha test,

import BinaryConverter from '../src/ComputeBinary.ts'
import {expect} from 'chai'
describe('Computation test',()=>{
it('to check if binary conversion is successful', ()=>{
var b=new BinaryConverter()
var bin='100001100', binResult=0
binResult=b.convertBinaryToDecimal(bin)
expect(binResult).to.equal(267)
})
})

The test result: I include the screenshot, usually, to complete the cycle of learning for the reader as the command line switches and flags, if not known, will not compile or may produce a different output.

If your test does not run from your default installation, install typescript and ts-node using npm install - explained in previous posts related to typescript.


I will try to build on this example with a blockchain reference in future posts

Monday 30 April 2018

Some Truffle tips and Blockchain blocks

Platform: node.js/Windows
Technology: BlockChain

Smart Contracts, Smart Money and Smart Wallets - be your own bank!


The BlockChain is now a famous Go-To-Technology that has innumerable possibilities for peer-to-peer interactions for exchanges of various kind like a currency, a representation of an asset, a virtual share, a proof of work, ownership etc. 

The path to adopting a new technology or framework can be really vexing if the resources online are less.

Ironing out the vexes

One very simple problem with Truffle, on Windows ie., is caused by how Windows processes the file extensions from the command line as well as a possible buggy Ganache GUI distribution bundle. Edit: Instead of the .appx file, download from this link, which provides a fully working installer for Windows.

First, the most common problem with truffle.


On node.js, after installing truffle, the first thing that you need to do is remember to either,

1. Use truffle.cmd because, by default, the Windows command-line processor runs the truffle.js file instead of the .cmd file. Simply use truffle.cmd compile or truffle.cmd migrate or any other command when using truffle.

2. Exclude the .js extension from the PATHEXT environment variable

3. Change the .js filename to something else so that the .cmd file gets executed.

Second, git clone the ganache-cli from  https://github.com/trufflesuite/ganache.git

Once cloned, open the node.js command prompt (this is assuming that you have npm installed truffle), you can do npm install and npm start from the git clone repository folder. 


Commands after cloning ganache-cli:
  1. npm install 
  2. npm start
from the cloned repository.

If you face the Microsoft Script runtime error, make sure that ganache is added to your PATH environment variable.


The cli will start and listen in to a port configured in the truffle.js with values as below:


 networks: {
    development: {
      host: "127.0.0.1",
      port: 7545,
      network_id: "*" // Match any network id
    }
  }



What Ganache does is, it creates a virtual Ethereum based blockchain that acts as a Private net (the mainnet is the live or the production network) with some dummy accounts, which you can use for testing and development without having to use any real ethers, the gas!
A personal Ethereum Blockchain.


The mnemonic is a 12-word combination that can be used to recover a wallet if you have forgotten the details required to access your wallet. Of course, using the mnemonic combination will result in creating a new wallet.






Once your personal blockchain is created, you can download and install the 
geth and Ethereum Wallet to work with your Ethereum based blockchain apps.


What all this means is that you can act as a bank by issuing your own token that will become a cryptocurrency that you can use for interchanges between your friends, club, for betting platforms etc.


Happy creating your own bank with cryptocurrency!

Monday 23 April 2018

A fake - Why faking a Person is a 'fake test'

Just happened to hit on the right word to express it!

While testing with TypeMock, I came across an interesting scenario where a class is declared within a controller that set off this simple post on why a fake is created and what purpose does it solve.

Let me elaborate using this example I found on the web. A controller with a class called Person inside it.

When writing a test for the controller, you will obviously need an instance of a Person because of Parameter Binding but a fake test is written just so that an external dependency does not hinder development!

This is the fundamental point in unit testing. If a unit test handles an external dependency code either through a direct, in place implementation of the external dependency or through accessing it, for real, then it is not unit testing because it violates the principle of testing code in isolation.

So, in this case, typing the Isolator.fake instance as a <Person> is a violation of the principle and therefore, is not even a 'fake test'

Below is the test for the ASP.Net MVC Controller code.

using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MvcApplication1.Controllers;
using TypeMock.ArrangeActAssert;
namespace MvcApplication1.Tests.Controllers
{
    [TestClass]
    public class ValuesControllerTest
    {
        [TestMethod]
        public void Get()
        {
            // Arrange
            ValuesController controller = new ValuesController();

            // Act
            IEnumerable result = controller.Get();

            // Assert
            Assert.IsNotNull(result);
            Assert.AreEqual(2, result.Count());
            Assert.AreEqual("value1", result.ElementAt(0));
            Assert.AreEqual("value2", result.ElementAt(1));
        }

        [TestMethod]
        public void GetById()
        {
            // Arrange
            ValuesController controller = new ValuesController();

            // Act
            string result = controller.Get(5);

            // Assert
            Assert.AreEqual("value", result);
        }

        [TestMethod]
        public void Post()
        {
            // Arrange
            ValuesController controller = new ValuesController();
            var p = Isolate.Fake.Instance<Person>(); // Not a fake because it creates an actual instance of type Person!
            // Act
            p.Name = "Jv";
            p.Age = 12;
            var s=controller.Post("Hello ", p);

            // Assert
            Assert.AreEqual("Hello Jv:12", s);
         
        }

        [TestMethod]
        public void Put()
        {
            // Arrange
            ValuesController controller = new ValuesController();

            // Act
            controller.Put(5, "value");

            // Assert
        }

        [TestMethod]
        public void Delete()
        {
            // Arrange
            ValuesController controller = new ValuesController();

            // Act
            controller.Delete(5);

            // Assert
        }
    }

}

  
using System.Collections.Generic;
using System.Web.Http;

namespace MvcApplication1.Controllers
{
    public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable Get()
        {
            return new string[] { "value1", "value2" };
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public string Post(string value, [FromBody]Person p)
        {
            return value+p.Name+":"+p.Age;
        }

    }
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }

        public override string ToString()
        {
            return this.Name + ": " + this.Age;
        }
    }
}

Basically, the purpose of Agile and Agile testing is to ensure that sufficient agility is always infused into the developmenr process not just through maintaining high confidence levels but also by eliminating sycophantic situations of "you praise me and I will praise you" attitude with testing techniques like using TestDoubles when a dependency is under development or not yet implemented.

And even if implemented, a unit test is not meant to test whether the Person exists or not but whether the code that expects the Person and has to interact with it in some way, either by calling an action on the Person object or by modifying some data of the Person, is behaving as expected of it.

And on the point of dependency, it is also important to note that mock testing using the Dependency Injection way is another example of wiring more dependency into the test itself and hence, a mock test, too, should not be concerned with whether the server is running or whether the database instance is up and running. The mock test should simply be able to mock the object! And this capability should be or rather, can be provided only by the mock framework ie., not as in the moq framework but in a way that the runtime calls are intercepted to fake or mock an object under test.

Happy unit testing, fake-ing and test double-ing !

Monday 9 April 2018

Explicit interface method - C#

Note: Putting the angular brackets < and > in a blogger post is more difficult than generics !

Continuing with generics, one of  my favorite language features, but this time in C#, the more dynamic of generic implementation in all programming languages, the premise, again from an example from Stackoverflow, is that there are two interfaces, IEquipment and 
IEquipmentDataProvider, with the latter providing for a generic method, GetEquipment, that returns a type of IEquipment.   

The question being on Stackoverflow ie., whether 
IEquipment
GetEquipment<E>(string Path) where E : IEquipment, new();

is correct or should there be an alternate way of working on the intent? 

An intent is what an interface is about and so when a constraint is declared on a generic method, or a normal method, the expansion of the constraint at implementation is what reveals the design of the intent. In this instance, it is a constraint that says all implementing classes must be of type 
IEquipment (
where E : IEquipment) and should have a parameterless constructor - , new().

So, what does it mean as a design when the interface IEquipmentDataProvider declares it like so,

public interface IEquipmentDataProvider
{
  IEquipment GetEquipment<E>(string Path) where E : IEquipment, new(); 
} 


public interface IEquipment{

}
public interface IEquipmentDataProvider:IEquipment
{
  IEquipment GetEquipment<E>(string Path) where E : IEquipment, new();
}
public class Equipment:IEquipment{
public Equipment(){

}
public IEquipment GetEquipment<E>(string Path){
Equipment eqp=new Equipment();
IEquipment ieq=(IEquipment) eqp;
return ieq;
}

public class EquipmentDataProvider:IEquipmentDataProvider{
public EquipmentDataProvider(){

}
public IEquipment GetEquipment<E>(string Path){
EquipmentDataProvider eqp=new EquipmentDataProvider();
IEquipmentDataProvider iedp = (IEquipmentDataProvider) eqp;
return iedp;
}
public static void Main(){
IEquipmentDataProvider da=(IEquipmentDataProvider)new EquipmentDataProvider();
IEquipment eq = (IEquipment)da.GetEquipment<Equipment>("somepath");
System.Console.WriteLine(eq);
}
}

For the above code, the compiler rejects the interface implementation because E cannot be expanded into a type conforming to the constraints because a type of IEquipment does not exist with a parameterless constructor and a corresponding GetEquipment method. ie., had the IEquipment interface declared the GetEquipment method in it instead of the IEquipmentDataProvider, the error would have been for IEquipment because the implementing class, Equipment, too, has not implemented the method as an interface method!!


It can be quite vexing if one does not know C# well, which has a feature where a method can be explicitly defined so that the interface implementation conforms to what the compiler expects.

This means that you simply qualify the method with the interface name prefixed, like so:

public IEquipment IEquipmentDataProvider.GetEquipment(string Path){

}

But since it is an explicit method definition, the compiler throws an error that the public modifier cannot be applied on it!


Because it is typed specifically as an interface method! Cool, isn't it!?

Modify the signature of the method and the complete code is as below:

public interface IEquipment{

}

public interface IEquipmentDataProvider:IEquipment
{
  IEquipment GetEquipment<E>(string Path) where E : IEquipment, new();
}
public class Equipment:IEquipment{
public Equipment(){}
public IEquipment GetEquipment<E>(string Path){
Equipment eqp=new Equipment();
IEquipment ieq=(IEquipment) eqp;
return ieq;

}
public class EquipmentDataProvider:IEquipmentDataProvider{
public EquipmentDataProvider(){}
IEquipment IEquipmentDataProvider.GetEquipment<E>(string Path){
EquipmentDataProvider eqp=new EquipmentDataProvider();
IEquipmentDataProvider iedp = (IEquipmentDataProvider) eqp;
return iedp;
}
public static void Main(){
IEquipmentDataProvider da=(IEquipmentDataProvider)new EquipmentDataProvider();
IEquipment eq = (IEquipment)da.GetEquipment<Equipment>("somepath");
System.Console.WriteLine(eq);
}
}

and, the output, even though the method returns an IEquipment type is actually an EquipmentDataProvider type!!



Happy C#-ing and generic interfacing, whatever may be the constraints!

Thursday 5 April 2018

Generic type constraints in Typescript

Platform: nodejs
npm install typescript, ts-node, mocha, babel

Generics from the C# days of 2005 onwards is a much-underused technique to implement type safety and security.

Here is a look at the fascinating feature using a mocha test and a couple of es6 classes and interface. Needless to say, this post, too, is inspired by a question from SO.

First, the premise.

An interface - interface DiscreteLinearOrder - with a generic type constraint - - declares two methods - next and lessThanOne - which are implemented in all deriving classes.

Another class that implements this interface imposes its own constraint in this form -

class DLOinterval<V, U extends DiscreteLinearOrder<any>>
implements DiscreteLinearOrder -

for the simple requirement that any consuming object is not typed as

const aaa = new abc.DLOinterval<number, string
>

or any other type but DiscreteLinearOrder interface type.

Like so,

const aaa = new abc.DLOinterval<number, abc.DLOnumber>

where abc.DLOnumber is another class implementing the DiscreteLinearOrder interface.




The interesting aspect that I originally chose this scenario was to explore the type inference happening at compile time in generics ie.,



The red squiggly line, in the above screenshot, indicates an error that since T is already the first parameter, typing another parameter with the same constraint causes the compiler to build an inference tree from the same parameter list, which had it not been a generic type would have simply been explained as a variable name already used but since T is not a variable but a type, it demonstrates that its duplicate usage causes a constraint to become almost like an infinite constraint as they both refer to each other!

Below is the code to be compiled with 

  1. tsc   
  2. mocha --compilers <path to ts-node\register> testfilename.ts
// testname.ts
import {expect} from 'chai'
import * as abc from './discretelo'
import 'mocha'
describe('a test', () => { 
it('interface', function(){
const aaa = new abc.DLOinterval<number, abc.DLOnumber>
(new abc.DLOnumber(3),new abc.DLOnumber(5),null,2)
    expect(aaa.next()).to.equal(3)
})
});
// discretelo.ts

interface DiscreteLinearOrder<T> {
    next:()=>T;
    lessThan(y:T):Boolean;
}
export class DLOnumber implements DiscreteLinearOrder<number> {
    private value: number;
    constructor(x: number) { this.value = x; }
    next = () => { return(this.value + 1); };
    lessThan = (y: number) => { return(this.value < y); };
    getValue = () => { return(this.value.toString()); }
}
export class DLOinterval<V, U extends DiscreteLinearOrder<any>>
implements DiscreteLinearOrder<number>{
    private start: U;
    private end: U;
    private data: any;
    private value: number;
    constructor(s: U, e: U, d: any,v:number) {
        this.value=v
        this.start = s;
        this.end   = e;
        this.data  = d;
    }
        next = () => { return(this.value + 2); };
        lessThan = (y: number) => { return(this.value < y); };
}



Make the test pass by changing the expected value!

Happy generic testing typsecript!

Friday 30 March 2018

Testing a typescript class with mocha

Platform: nodejs
Install typescript, mocha for nodejs and the associated typings for mocha. 

The story starts with coming across some mocha problem caused by the usage of the implements keyword in Typescript in one of the forums for techies.

As ever, I picked it up and decided to write a mocha test to see what was the problem.

The test result revelations were as interesting as the Cambridge analytica fiasco and the subsequent handling of it in Singapore!

Some premise before I take you through to the bumper details!
.
An interface, in Typescript, serves as the blueprint much like in the other languages but it serves an additional purpose of defining how classes would implement them.

For instance, for a class that accepts a locale and a local time value, if the interface types the two parameters as a string and a number, scoped public respectively, then the class is forced to apply the same constraints. Even implementing the public property as private is not allowed.


// IClockTime.ts

export default interface IClockTime {
    new (time: number): IClock;
}

// IClock.ts

export default interface IClock {
    currentTime: number;
    locale: string;  
}

// Clock.ts

import IClock from './IClock'
import IClockTime from './IClockTime'
export default class Clock implements IClock {
    constructor(public currentTime:string) { 
        this.currentTime=currentTime
        }        
    public tellTime(t:IClockTime){
            return new t(this.currentTime);
        }
}

// AnotherClock.ts

import IClock from './IClock'
import IClockTime from './IClockTime'
export default class AnotherClock implements IClock {
    constructor (public currentTime: string, count: number) {
        this.currentTime=currentTime
        this.count=count
    }
    public tellTime(t:IClockTime){
            return new t(this.currentTime);
        }
}

// interfacestest.ts

import ClockTime from './IClockTime'
import AnotherClock from './anotherclock'
import Clock from './clock';
import {expect} from 'chai'
import 'mocha'
describe('an interface test', () => {  
it('to check time', () => {
var cc: ClockTime=Clock;
var cc1:ClockTime=AnotherClock
var ci = new cc(9.15,"GMT",12);
    expect(ci.tellTime(Clock)).to.equal('9:15');
  });
});


The tsc compiler is shrewd! It has noticed that the AnotherClock class has gone ahead and implemented some member of its own and not followed the blueprint provided by the IClock interface. This is much in the comfort zone of C# programmers.

It also correctly identifies what all AnotherClock has incorrectly implemented.

Modify the anotherClock class like so:

// AnotherClock.ts

import IClock from './IClock'
import IClockTime from './IClockTime'
export default class AnotherClock implements IClock {
   private _currentTime:number;
    private _locale:string;
    public get currentTime():number{
        return this._currentTime
    }
    public set currentTime(newtime:number){
        this._currentTime=newtime
    }
    private get locale():string{
        return this._locale
    }    
    private set locale(newlocale:string){
        this._locale=newlocale
    }
    constructor (currentTime: number, locale: string) {
        this.currentTime=currentTime
        this._locale=locale
    }
    public tellTime(){
            return this.currentTime;
        }
}

And you get errors from tsc that the property locale is not in sync with how the interface published it!


I will scope this to an example of a test of the class behavior and test whether the Clock returns the time expected of it, given the locale.

The Clock class, too, attempts its own tricks by supplying a string to a parameter of type IClockTime when it types the parameter of the checkLocale() method as a IClockTime rather than as a string. Change the parameter from t:IClockTime to t:string.

Modify the Clock class like so:

import IClock from './IClock'
import IClockTime from './IClockTime'
export default class Clock implements IClock {
    private _currentTime:number;
    private _locale:string;
    public get currentTime():number{
        return this._currentTime
    }
    public set currentTime(newtime:number){
        this._currentTime=newtime
    }
    constructor(currentTime:number, public locale:string) { 
        this.currentTime=currentTime
        this._locale=locale
        }        
    private checkLocaleTime(t:string){
        if (this._locale==="GMT")
        this.currentTime=this.currentTime-5.00
        
    }
    public tellTime(){
            this.checkLocaleTime(this.locale)
            console.log(this.currentTime)
            return this.currentTime.toString();
        }
}


Modify the test like so:

// interfacetest.ts

import ClockTime from './IClockTime'
import anotherClock from './anotherclock'
import Clock from './clock';
import IClock from './IClock'
import {expect} from 'chai'
import 'mocha'
describe('an interface test', () => {  
it('to check time', () => {
let cc= new Clock(9.15,"GMT");
    expect(cc.tellTime()).to.equal('9:15');
  });
});



Modify the expectation to match the GMT (approx.!) time and make the test pass!

Happy typescripting interfaces and classes for ES5!

Monday 26 March 2018

The unhandled Promise rejection state and the others

Promises can be pleasant as well as vexing. In Javascript/node.js context, that is.

A promise can have three states: pending, fulfilled (resolved) or rejected.

Using a ES6 class, I managed to simplify the test that would demonstrate the three states and an additional, 'falsey' state!

First, the falsey state, as it can be confusing as an error message.


This message is caused when a Promise returns empty and is not handled in the test (mocha) either!

// mochatest.js

const assert=require('chai').assert
const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
})
})        
});


// asyncpromiserejection.js

class asyncpromise{ 
    constructor(s){
        this.s=s
    }
PTest(){    
    var somevar = false;
    somevar=this.s;
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
          // throw new Error("Promise rejcted")
            reject();
    });
}
}
module.exports=asyncpromise

As the else part in the code above does not do anything, it simply causes a promise rejection but since it is not handled in the test - there is no catch to handle the broken promise chain - it causes the message of a falsey.

Now, modify the test like so, by adding the catch block to handle the promise rejection state:

const assert=require('chai').assert
const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
}).catch((error)=>{
    console.log("Promise rejected")
   // assert.equal(error.message,"Promise rejected")
})
})        
});




You can test for custom error messages returned by the rejected promise, like so:


class asyncpromise{ 
    constructor(s){
        this.s=s
    }
PTest(){    
    var somevar = false;
    somevar=this.s;
    return new Promise(function (resolve, reject) {
        if (somevar === true)
            resolve();
        else
           throw new Error("Promise rejcted")
           // reject();
    });
}
}
module.exports=asyncpromise


And the test, to include the assertion:

const assert=require('chai').assert
const asyncpromise=require('./asyncpromiserejection.js')
describe("asyncTests", () => {
it("handles Promise rejection",async ()=>{
    var t=new asyncpromise(false)
    await t.PTest().then(function () {
     console.log("Promise Resolved");
}).catch((error)=>{
   // console.log("Promise rejected")
    assert.equal(error.message,"Promise rejected")
})
})        
});



Make the test pass by simply correcting the typo in the error message!


Monday 19 March 2018

Of a mocha test of a ES6 Fibonacci tree, the modulo operator, use case for getters and setters and undefined value of 0

ES6 has introduced some nice OO-like feel to javascript.

I, however, find it difficult to grasp the OO part of it in a language which says "Just use === when you wish to check and compare for both value and type"!

But with the ES6 specifications, the 'class' keyword and property getters and setters, javascript is looking to become more readable, intelligible and maintainable!

So, when I chanced upon a question in Stackoverflow dot com about a B Tree constructed on the Fibonacci series with 0 and 1 as root and subsequent values either to the left or to the right of the tree, I picked up the example to write a mocha test on it using ES6.

That is,
                                       0------1
                                      1--------2
                                     3----------5
                                    8-----------13
and so on.

So, the requirement says that we need a Node class with Left and Right node properties to contain the position of the node's value in the tree and a FibonacciTree class that would build the tree.

Remember, this is a test not the actual implementation of the tree so, the logic of decision-making to determine whether the value should be to the left or to the right of a node is left to the assertion of the test and is statically manipulated from the test ie., it is understood that since it is the test that knows its expectations as per "Arrange, Act, Assert" of the test, the conditional value (instanceOfB.X) is assumed.
Edit: You may need to use babel or target your config.json file to ES6 for the code to transpile.

The Fibonacci tree class is as below:

// fibonaccitree.js

var Node=require('./nodetree');
class fibonaccitree{
get X(){
    return this._X;
}
set X(newX){
    if (newX)
    this._X=newX;
}

buildTree(n){
       var node = new Node();
            console.log("Value of X is " +this._X)
            if (this._X % 2==0){
            node.left=n;
            }
            else if (this._X % 2!=0){
            node.right=n;
            }
       return node;
}
}

The node class that would contain the left and right values of a node is as below:

// nodetree.js

class nodetree {
    get right(){
        return this._right;
    }
    set right(rightValue){
        if (rightValue>=0)
        this._right=rightValue;
    }
    get left(){
        return this._left;
    }
    set left(leftValue){
        if (leftValue>=0)
        this._left=leftValue;
    }
}
module.exports=nodetree;

and the mocha test is as below:

// fibonaccitreetest.js

var A=require('./nodetree'),B=require('./fibonaccitree')
var assert=require('assert');
describe("Fibonacci tree Test", () => {
    var InstanceOfB=new B(); // Arrange
    var InstanceOfA=new A(); // Arrange
    beforeEach(() => {
          
             
    });
  afterEach(()=>{
    if (InstanceOfB.x==1){ // can use or not since test method also initializes. You may use either 
        InstanceOfB.X=2; // Arrange (Re-arrange) - edit: this is to check / ensure if /and even if the order of execution of test  methods change it will execute the if switch in code correctly
        //InstanceOfB = new B(); // Arrange (Re-arrange)
        //InstanceOfA = new A(); // Arrange (Re-arrange)
    }   
  })
    it('should check if the node is to the left of the binary tree', () => {
        InstanceOfB.X=2; // Arrange - can use or not since afterEach already initializes 
        var y=8;
        console.log("Value passed is " +y)
        var res = InstanceOfB.buildTree(y); // Act
        assert.equal(res.left,y); // Assert       
    });
    it('should check if the node is to the right of the binary tree', () => {
        InstanceOfB.X=1; // can use or not since afterEach already initializes 
        var z=13
        console.log("Value passed is " +z)
        var res = InstanceOfB.buildTree(z);
        assert.equal(res.right,z);
        
    });    
});

And the test result on node (node.js) is as in the below screenshot:


What is interesting in this example is the way the modulus operator in Javascript behaves.

If  a value of 0 is passed to the property 'X' in the fibonaccitree class then if (this._X%2==0) fails to evaluate correctly because the value of '0' supposedly gets interpreted as 'undefined', which is the reason for InstanceOfB.X=1; and InstanceOfB.X=2;


Note: To make the es6 code (only if you use import or export default keywords and the other es6 keywords) work in node.js, use the following steps:

1. npm install babel=preset-es2015 --save-dev
2. create a file called .babelrc in the root of your test/code/mocha folder with the value

{
  "presets": ["es2015"]

}

in the file.
3. Run the mocha test with "mocha --require followed by your test filename


Happy mocha-ing, ES6-ing, and modulo-ing javascript!