Thursday, 23 March 2017

AssertJ vs. Hamcrest

I recently came across a piece of code that used a Stack1. The Stack seems to inherit from Vector. The JavaDoc indicated (and so did my IDE, I think) that I should be using the Deque2 interface instead. To be precise:
“A more complete and consistent set of LIFO stack operations is provided by the Deque interface and its implementations, which should be used in preference to this class.”
Dequeue basically seems to be a specialized Queue3, that supports element insertion and removal at both ends4.

In order to get to grips with Deque, I decided to write some simple tests. These are JUnit Tests (version 4.12) and in one I used Hamcrest5 and in the other I went for AssertJ6.

Let's see what happens.

A simple compare

Hamcrest:
assertThat(actual, equalTo(testdata2));
AssertJ:
assertThat(actual).isEqualTo(testdata2);

Collections

Hamcrest:
assertThat(transmittedTestdata, hasSize(2));
AssertJ:
assertThat(transmittedTestdata).size().isEqualTo(2);

Null Values

Hamcrest:
assertThat(actual, not(nullValue()));
AssertJ:
assertThat(actual).isNotNull();

Exceptions

Hamcrest:
@Test(expected = NoSuchElementException.class)
public void testEmptyDequeueException()
{
  Deque<Testdata> transmittedTestdata = new ConcurrentLinkedDeque<>();
  Testdata pop = transmittedTestdata.pop();
}
AssertJ:
assertThatThrownBy(transmittedTestdata::pop).isInstanceOf(NoSuchElementException.class);

Imports

A comparison between the required imports of Hamcrest and Assertj is interesting:
Hamcrest:
import java.util.Deque;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentLinkedDeque;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasSize;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
AssertJ:
import java.util.Deque;
import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentLinkedDeque;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

Notes

  • I really like the AssertJ fluent API. It feels more natural to me than the Hamcrest one.
  • It is way easier to find the appropriate matchers in AssertJ. I get the full benefit of my IDE code completion.
  • Adding the appropriate import is way easier. Using Hamcrest, I always get a choice of five different imports for the same matcher.
  • I need fewer imports anyways.
So far, I like AssertJ a lot.

I need to work with AssertJ a lot more, to see some of the interesting stuff.

References

[1] Java 7 JavaDoc - Stack
https://docs.oracle.com/javase/7/docs/api/java/util/Stack.html
[2] Java 7 JavaDoc - Deque
https://docs.oracle.com/javase/7/docs/api/java/util/Deque.html
[3] Java 7 JavaDoc - Queue
https://docs.oracle.com/javase/7/docs/api/java/util/Queue.html
[4] Wikipedia - Double-ended queue
https://en.wikipedia.org/wiki/Double-ended_queue
[5] Hamcrest - Matchers that can be combined to create flexible expressions of intent
http://hamcrest.org/
[6] AssertJ - Quick start
http://joel-costigliola.github.io/assertj/assertj-core-quick-start.html

Thursday, 16 March 2017

reveal.js

Our architect recently put together a presentation regarding our new framework using reveal.js1.

I had never heard of reveal.js and I was intrigued. It seems to be a presentation framework that runs in your webbrowser, using npm2 and grunt3 and javascript and MarkDown4 and all that.

I figured I'd give it a try for my next presentation.

I downloaded a release6 and used the very clear instructions on how it works on GitHub5.

Installing a new release, seems to be nothing more than:
- download
- unzip
- edit index.html
- browse to index.html

Luckily, I had the changes our architect made to bring it into line with the company layout guidelines. It was nothing more than a different css file that is based on the "white"-theme (which is also a css file). The default theme when you get a release is the "black"-theme, similar to the one visible at [1].

You can decide to just browse to the file index.html locally to display the presentation, but if you do a "grunt serve" a small webserver is started that serves the webpage and related resources. The latter option provides more functionality.

MarkDown

<div class="reveal">
  <div class="slides">
    <section data-markdown="slides.md"
              data-separator="^\n\n\n"
              data-separator-vertical="^\n\n"
              data-separator-notes="^Note:"
              data-charset="utf-8">

    </section>
  </div>
</div>
As you can see above, you can specify how the sheets are divided. What exactly the sequence is for detecting a division.

Initializing the presentation is done using:
// More info https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
      width : 1280,
      height : 1024,
      slideNumber: 'c/t',
      showNotes: true,
      history: true,
// More info https://github.com/hakimel/reveal.js#dependencies
      dependencies: [
          { src: 'plugin/markdown/marked.js' },
          { src: 'plugin/markdown/markdown.js' },
          { src: 'plugin/notes/notes.js', async: true },
          { src: 'plugin/zoom-js/zoom.js', async: true } }
          ]
});
I set the "snowNotes" to true, because I wished to print out the sheets including the notes. See Printing below.

CSS

It is easy to add custom CSS to individual slides. For example:
<!-- .slide: data-background="#ffffff" data-background-image="images/background_subtitle.png"  data-background-size="auto 100%"  data-background-repeat="no-repeat" -->
A common one used to change the font of the previous element (useful for source code):
<!-- .element: class="small" -->

Printing

Printing your sheets seems to be as simple as surfing to the url:
http://localhost:8080/?print-pdf#/
It generated in Chrome browser a PDF file that you can simply print to file in the browser.

Conclusions

It is very nice, if you are a programmer or web guy and you do not wish to fire up Microsoft Powerpoint.

An advantage is of course that MarkDown files can easily be added to your version control system.

Another advantage is that you can refer to images on the Internet/Intranet. I managed to do just that, by referring to images already on our Intranet Confluence pages. At least the images will always be up to date.

(p.s. It also means that in order to view my presentation properly, one has to be logged into Confluence. I found that out rather quickly, when trying my presentation out in one of our conference rooms.)

I don't really like the markdown setting displayed above, as it is too easy to add one line or remove one line to many.

I also had a problem where I must have made a grammatical mistake, and in my FireFox browser the presentation managed to hang and after several seconds I'd get a "Script is running too long. Do something about it?" message.

There are several keyboard shortcuts for navigation through the sheets during the presentation, which is nice, as the mouse isn't all that handy.

I don't much like the "sheet notes", which are displayed in a separate browser window. I usually have them turned off.

References

[1] Reveal.ks - the HTML Presentation Framework
http://lab.hakim.se/reveal-js/
[2] NPM
https://www.npmjs.com/
[3] Grunt
https://gruntjs.com/
[4] Wikipedia - MarkDown
https://en.wikipedia.org/wiki/Markdown
[5] GitHub - reveal.js
https://github.com/hakimel/reveal.js
[6] reveal.js releases
https://github.com/hakimel/reveal.js/releases
GitHub- Basic Writing and Formatting Syntax
https://help.github.com/articles/basic-writing-and-formatting-syntax/