Logging to MongoDB

Today, I’m willing to share a logger library written by me using node.js and npm and built with gulp.

This is a logger, which logs the log messages into a mongodb along with logging to console.

Follow the Git-hub link for more details.

Follow my last post for more info on how to use node, npm, nvm and gulp.

See you soon with another update.

Advertisements

Gulp Mocha Unit Test Tutorial

Hi Folks,

Today, I’m gonna teach you guys how to write unit testing in javascript with gulp and mocha js.

First, lets have our requirement.

I’m gonna write a javascript file to test whether a string is a palindrome or not.

And gonna write unit test cases to check it with a palindrome string, a non-palindrome string, and an undefined value.

Lets hop in. Before that, if you want the complete source code, you can get it here. And you can it can be executed as follows,

$ npm install
$ npm install --global gulp
$ gulp

You will need to have node.js, npm(node package manager) and nvm(node version manager) installed for this tutorial.

So, install them.

First, create a directory for our development and inside the directory create a file named package.json as follows.

{
"name": "gulp-training",
"version": "0.0.1",
"description": "This is a tutorial on how to write unit test with gulp and mocha js",
"author": "Sridhar <Replace with your name :)>",
"dependencies": {}
}

Thats it.

Now, open your terminal/command prompt in the directory having the package.json

npm install --save chai
npm install --save expect
npm install --save gulp
npm install --save gulp-eslint
npm install --save gulp-mocha
npm install --save run-sequence
npm install --save sinon

These are the dependencies we will require.

Once the installation completed,

create a folder names “scripts” in this only we’ll create our scripts.

inside scripts, create a file named, palindrome.js

In this file only we’ll have our function to check whether the string is a palindrome or not. The file contents will be as follows,


'use strict';
function Palindrome() {};
Palindrome.prototype.isPalindrome = function(input) {
if(input) {
return input == (input.split('').reverse().join(''));
}
return false;
}
module.exports = new Palindrome();

As you can see this is just a simple function to test a string is palindrome or not, it will return true for a palindrome and false for a non-palindrome. Note that I’ve also handled the undefined values to return false.

Now, we’ll write our test case.

Now in the project directory (the one contains package.json), create a new directory called test. Here create  a file named testpalindrome.js. The test will be as follows.


'use strict';
var expect = require('chai').expect;
var Palindrome = require('../script/palindrome');
describe('Palindrome Test Block',function(){
it('for palindrome',function(){
var result = Palindrome.isPalindrome('tat');
expect(result).to.not.be.undefined;
expect(result).to.equal(true);
});
it('for non palindrome',function(){
var result = Palindrome.isPalindrome('tata');
expect(result).to.not.be.undefined;
expect(result).to.equal(false);
});
it('handling of undefined value',function(){
var str;
var result = Palindrome.isPalindrome(str);
expect(result).to.not.be.undefined;
});
});

Now, let me explain the code here.

We’re creating the objects for expect (which is an assertion library) and the palindrome we created.

Then, we’ll describe the test case.

with the name of the test case and in the callback of the description, we’ll write the tests.

First: A palindrome

Test it with a string identification for the test case and the callback in which the test is performed.

The test expects the return value of the palindrome test to be true.

Second: A Non-palindrome

The test expects the return value of the palindrome test to be false.

Third: Undefined

Remember that in our palindrome example we handles the undefined value as well.

The test expects the return value of the palindrome test to be false(as handled in the palindrome.js).

So, this is our test script.

We’ll be using gulp and mocha to test our script.

In the project folder, create a new file named, gulpfile.js

This will be the file used for testing the project we just created.

The contents of gulp file will be as follows,


'use strict';
var gulp = require('gulp');
var mocha = require('gulp-mocha');
var runSequence = require('run-sequence');
var eslint = require('gulp-eslint');
gulp.task('lint', function() {
return gulp.src(['script/**/*.js', 'test/**/*.js']).pipe(eslint()).pipe(eslint.format()).pipe(eslint.failOnError());
});
gulp.task('test', function() {
return gulp.src('test/**/*.js', {read: false}).pipe(mocha({reporter: 'spec'}));
});
gulp.task('check', function(callback) {
runSequence('lint', 'test', callback);
});
gulp.task('default', ['check']);

I’ve initialized, gulp, gulp-mocha (mocha for gulp), runsequence, gulp-eslint(for javascript syntax validation). Note: Beginners can skip the lint (javascript syntax validation) since it will report errors even for space indents.

The lint task is to pull all javascripts from script and test folders and test their format and to throw error on validation failure.

The test task uses mocha to execute and test the scripts in “test” folder.

The check task is the runsequence in which the tasks needs to be executed.

I’ve made the sequence like lint task to execute first and then the test task.

the gulp default task will be executed at first. Here, I just called the check task. which executes tasks in following order,

  1. lint task
  2. test task

So, the tasks will be tested.
How to run,

$ npm install
$ nvm install --global gulp
$ gulp

`npm install` downloads all the required libraries and keep them in a directory called “node_modules”.

`nvm install –global gulp` installs gulp which we need.

gulp executes the tests and produces an output as follows.

Screenshot from 2015-10-09 15:18:25

We’ve done it folks.

The complete source can be found here.

Java Compiler Plug-ins in Java 8 (Use a new plug-in mechanism to extend the Java compiler with new behavior)

Java Compiler Plug-ins in Java 8

(Use a new plug-in mechanism to extend the Java compiler with new behavior)


Java 8 will bring a new mechanism that allows you to write plug-ins for the Java compiler (javac). A compiler
plug-in lets you add new phases to javac without making changes to its code base. New behavior can be encapsulated
in a plug-in and distributed for other people to use. For example, javac plug-ins could be used to do the following:

¦¦ Add extra compile-time checks
¦¦ Add code transformations
¦¦ Perform customized analysis of source code

Note: The API for creating

javac plug-ins is still experimental for JDK 8; it is scheduled to ship in 2013.

In this article, we show how you can write a simple, customized source code analysis tool so you can learn how to
leverage the plug-in mechanisms for your own applications. We find code patterns that check whether the result
of calling get() on an object that is a subtype of Map is null. In other words we are looking for patterns such as
the following, where expr is a subtype of java.util.Map.

expr.get(key) == null

This pattern could be contained within a conditional expression, a return statement, and so on. It should be
reported in all cases. How Do Plug-ins Differ from Annotation Processors? Here are some ways that plug-ins differ from annotation
processors:
¦¦ Plug-ins are more flexible. They can run at various points in the compilation pipeline through a TaskListener.
¦¦ Plug-ins do not use the model of processing rounds, which incurs additional overhead. Plug-ins have a simpler interface.
¦¦ Annotation processors are defined by a standard (JSR 269). Plug-ins are javac-specific.
¦¦ Plug-ins require the use of a ServiceLoader. Java Compiler Plug-in Architecture A javac plug-in supports two methods:
¦¦ First, a getName() method that returns the name of the plug-in for identification purposes
¦¦ Second, a call() method that is invoked by the javac with the current environment it is processing The call() method gives
access to the compiler functionalities through a JavacTask object, which allows you to perform parsing, type checking, and compilation.

In addition, the JavacTask object lets you add observers (which are instances of TaskListener) to various events generated during compilation.
This is done through the method addTaskListener(), which accepts an object TaskListener. Listing 1 shows com.sun.source.util.Plugin, which
uses the getName() and call() methods. Listing 2 shows some methods available in com.sun.source.util.JavacTask, and Listing 3 shows the
methods available in com.sun.source.util.TaskListener.

But there are obvious questions that remain unanswered, for example, how do you start writing the compiler plug-in and how do you
run it? Let’s Build a Compiler Plug-In

The first step is to download and build the current release of the Java 8 compiler, which supports compiler plug-ins.
Toward this end, download(http://hg.openjdk.java.net/jdk8/jdk8/langtools)the latest version and follow the build instructions in the
README file.

Once the compiler is built, include the generated dist/lib/classes.jar file in your project. Alternatively, you can download
a ready-made binary from http://jdk8.java.net.Next, there are several steps we need to follow to build our plug-in.
Here is a summary of the steps:
1. Implement the com.sun.source.util.Plugin interface shown in Listing 1.
2. Add a TaskListener to perform additional behavior after the type-checking phase.
3. Create an abstract syntax tree(AST) visitor to locate binary expressions:
a. Evaluate whether the left side is a method call expression with a receiver’s type that is a subtype of java.util.Map.
b. Evaluate whether the right side is a null expression.

Step 1: Implement the com.sun.source.util.Plugin interface. The first step is to create the main class, which implements com.sun.source.util.Plugin.
We return the name of our plug-in via the getName() method, as shown in Listing 4.

Step 2: Add a TaskListener. We are looking for a code pattern that checks whether the receiver of the method call get() is a subtype of java.util.Map.
To get the type of the receiver, we need information about the types of expressions that are resolved during the type-checking phase. We therefore
need to insert a new phase after type checking. Toward this end, we first create a TaskListener and add it to the current JavacTask, as shown in Listing 5.

We now need to create the class CodePatternTaskListener, which implements a TaskListener. A TaskListener has two methods,started() and finished(), which are
called, respectively, before and after certain events. These events are encapsulated in a TaskEvent object. In our case, all we need to do is implement
the finished() method and check for an event mentioning the Analyze phase (type checking), as shown in Listing 6.

Step 3: Create the AST visitor. Next, we need to write the logic to locate the code pattern and report it. How do we do that? Thankfully, a task
event provides us with a CompilationUnitTree,which represents the current source file analyzed in a tree structure. It can be accessed with the getCompilationUnit() method.

Our code will need to traverse this tree, locate a binary node,and evaluate the node’s left andright children. This sounds like a visitor pattern job. The Compiler
Tree API provides us with a readymade visitor class designed for such tasks: com.sun.source.util.TreeScanner<R, P>. It visits all the nodes in the AST.

First, we initialize our visitor object and then visit the CompilationUnitTree:, as shown in Listing 7.

All we have left to do is to override visitBinary(BinaryTree node,P p) and write the logic to verify the code pattern. The full code of the visitor class with inlined
comments is provided in Listings 8. Let’s Run Our Compiler Plug-In

We are almost finished. The final step is to set up a file called com.sun.source.util.Plugin located in META-INF/services/. This file must contain the name of our
plug-in, CodePatternPlugin, which allows javac to load the appropriate plug-in.

Next, using your favorite IDE or the command line, create a Java archive (JAR) file from your project containing the META-INF directory and compiled class files:

$ jar –cvf codePatternPlugin.jar META-INF *.class

Finally, you can run the plug-in as shown in Listing 9, where
¦¦ -processorpath indicates the path where the plug-in JAR file is located
¦¦ -Xplugin indicates the name of the plug-in to run, which is CodePatternPlugin, in this case

Conclusion
The new plug-in mechanism provides a simple hook to javac. You can use it to extend javac with new behavior. In addition, you can distribute a plug-in without
making modifications to the javac code base. In this article, we showed how you can use this mechanism to easily write a customized source code analysis tool
for your applications.

Listing will be follows

Code listings for “Java Compiler Plug-ins in Java 8,”

[Listing 1]
public interface Plugin {
public String getName();
public void call(JavacTask task, String[] pluginArgs);
}

[Listing 2]
public abstract class JavacTask implements CompilationTask {

public abstract Iterable<? extends Element> analyze() throws IOException;
public abstract Iterable<? extends JavaFileObject> generate throws IOException;
public abstract void addTaskListener(TaskListener taskListener);

}

[Listing 3]
public interface TaskListener
{
public void started(TaskEvent e);
public void finished(TaskEvent e);
}

[Listing 4]
public class CodePatternPlugin implements Plugin{

@Override
public void call(JavacTask task, String[] args) {
// See Step 2
}

@Override
public String getName() {
return “CodePatternPlugin”;
}
}

[Listing 5]
public void call(JavacTask task, String[] args) {
System.out.println(“Running!”);
task.addTaskListener(new CodePatternTaskListener(task));
}

[Listing 6]
public class CodePatternTaskListener implements TaskListener {
private final CodePatternTreeVisitor visitor;

CodePatternTaskListener(JavacTask task) {
visitor = new CodePatternTreeVisitor(task);
}
@Override
public void finished(TaskEvent taskEvent) {
if(taskEvent.getKind() == TaskEvent.Kind.ANALYZE)
{
// See Step 3
}
}

@Override
public void started(TaskEvent taskEvent) {

}
}

[Listing 7]
if(taskEvent.getKind().equals(TaskEvent.Kind.ANALYZE))
{
CompilationUnitTree compilationUnit = taskEvent.getCompilationUnit();
new CodePatternTreeVisitor().scan(compilationUnit, null);
}

[Listing 8]
import javax.lang.model.element.Name;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;

import com.sun.source.tree.*;
import com.sun.source.tree.Tree.Kind;
import com.sun.source.util.JavacTask;
import com.sun.source.util.SourcePositions;
import com.sun.source.util.TreePath;
import com.sun.source.util.TreePathScanner;
import com.sun.source.util.Trees;

public class CodePatternTreeVisitor extends TreePathScanner<Void, Void> {
// offsets of AST nodes in source file
private final SourcePositions sourcePositions;
// bridges Compiler api, Annotation Processing API and Tree API
private final Trees trees;
// utility to operate on types
private final Types types;
private final TypeMirror mapType;
private final Name getName;

private CompilationUnitTree currCompUnit;

CodePatternTreeVisitor(JavacTask task) {
types = task.getTypes();
trees = Trees.instance(task);
sourcePositions = trees.getSourcePositions();

// utility to operate on program elements
Elements elements = task.getElements();
// create the type element to match against
mapType = elements.getTypeElement(“java.util.Map”).asType();
// create a Name object representing the method name to match against
getName = elements.getName(“get”);
}

@Override
public Void visitCompilationUnit(CompilationUnitTree tree, Void p) {
currCompUnit = tree;
return super.visitCompilationUnit(tree, p);
}

@Override
public Void visitBinary(BinaryTree tree, Void p) {
// unpack the kind of expression, left and right hand side
ExpressionTree left = tree.getLeftOperand();
ExpressionTree right = tree.getRightOperand();
Kind kind = tree.getKind();

// apply our code pattern logic
if (isGetCallOnMap(new TreePath(getCurrentPath(), left))
&& kind == Kind.EQUAL_TO
&& isNullLiteral(right)) {
System.out.println(“Found Match at line: ”
+ getLineNumber(tree) + ” in ”
+ currCompUnit.getSourceFile().getName());
}
return super.visitBinary(tree, p);
}

private boolean isNullLiteral(ExpressionTree node) {
// is this expression representing “null”?
return (node.getKind() == Kind.NULL_LITERAL);
}

private boolean isGetCallOnMap(TreePath path) {
switch (path.getLeaf().getKind()) {
// is it a Method Invocation?
case METHOD_INVOCATION:
MethodInvocationTree methodInvocation = (MethodInvocationTree) path.getLeaf();
// extract the identifier and receiver (methodSelectTree)
ExpressionTree methodSelect = methodInvocation.getMethodSelect();
switch (methodSelect.getKind()) {
case MEMBER_SELECT:
// extract receiver
MemberSelectTree mst = (MemberSelectTree) methodSelect;
ExpressionTree expr = mst.getExpression();
// get type of extracted receiver
TypeMirror type = trees.getTypeMirror(new TreePath(path, expr));
// extract method name
Name name = mst.getIdentifier();
// 1) check if receiver’s type is subtype of java.util.Map
// 2) check if the extracted method name is exactly “get”
if (types.isAssignable(types.erasure(type), types.erasure(mapType))
&& name == getName) {
return true;
}
}
}
return false;
}

private long getLineNumber(Tree tree) {
// map offsets to line numbers in source file
LineMap lineMap = currCompUnit.getLineMap();
if (lineMap == null)
return -1;
// find offset of the specified AST node
long position = sourcePositions.getStartPosition(currCompUnit, tree);
return lineMap.getLineNumber(position);
}
}

[Listing 9]
$ javac -processorpath codePatternPlugin.jar -Xplugin:CodePatternPlugin Test.java

Copyright 2013, Oracle Corporation