Translate

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!

No comments: