100% Code Coverage or Die!

I have been working on my next tutorial. It will be a hapi.js api (maybe even with a React/Redux client) as close to production quality as I can get without a different (aka better) hardware infrastructure. Quality error messages, logging, input validation, fully documented, authentication with scopes and most importantly testing with 100% code coverage.

This is what I am currently working on and it’s been interesting learning how Hapi.js gets tested and what differences configuration over coding makes in my approach. So far I like it even though I am struggling with some specific routes. It is always fun to learn something new and feel that struggle again. I certainly prefer to have to work at something for a bit over working on the same thing over and over again.

I should have something ready in the next few days, maybe a week! I swear I just love coding so much!

 

Publishing an NPM Module Part 1

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription.

>Part 1 | Part 2 | Part 3 | Part 4 | Part 5 | Part 6 | Part 7

Part 1 : The Setup

These are my notes based on the phenomenal tutorial by Kent C. Dodds hosted by egghead.io both of which are my go to sources when I want to learn something new. I highly suggest you sign up for the pro subscription. They are focused on a ‘code first’ delivery so you start learning right away. I made these notes to dig a little deeper on some of the topics, but I would not have known where to get started without these two wonderful resources!

I will be using the following icons to denote certain sections.

glyphicons-55-clock  = Time Saving Idea

glyphicons-499-sunglasses = Pro Tip

glyphicons-31-pencil = Note

glyphicons-197-exclamation-sign = Alert

glyphicons-424-git-create = Code Update

glyphicons-28-search  = A Closer Look

Overview

  1. Create the git repo
  2. Create the library
  3. Publish to npm
  4. Create test suites
    1. Karma
    2. Mocha
    3. Chai
  5. Set up continuous Integration
    1. Travis-CI
  6. Add ES6/ES2015
    1. Babel
    2. web pack
  7. Distribute
    1. NPM
    2. GITHUB
    3. UMD

Create the GitHub Repo

First head over to github.com to create your account if you don’t already have one. Next create a new repo. You can skip creating the README.md as we will be making our own in the next few moments. Take note of the url for the repo as we are going to add it in as the origin in the following steps.

$ echo “# Project name” >> README.md
$ git init
$ git add README.md
$ git commit -m "Initial Commit"
$ git remote add origin <git url> //i.e. https://github.com/jmichelin/something.git
$ git push -u origin master

Setting up NPM

Install Node

To verify that you have node installed run:

$ npm -v

Head to https://docs.npmjs.com/ and read about init-author.name, init-author-email, init-author-url, init-license and save-exact. These set up defaults making future projects even easier. The save-exact true makes your project configured with an exact version rather than using npm’s default semver range operator. There are more but these are some of the more common ones that tend not to change between projects. 

glyphicons-55-clock
Run the following commands:

$ npm set init-author-name 'Name' 
$ npm set init-author-email '<your_email>' 
$ npm set init-author -url '<your_website>' 
$ npm set init-license 'MIT'
$ npm set save-exact true //makes sure you use exact versioning

let’s look at npmrc:

$ cat ~/.npmrc

You will see all of the defaults you set above saved there in case you ever want to edit them.

Create npmjs.com account by heading over to npmjs.com and click on sign up.

screen-shot-2016-09-06-at-4-27-30-pm

Then back in your console:

$ npm adduser

enter npmjs account name, password and Email, add user creates an auth token that you should keep private.

$ npm init

Accept default name, version, enter a brief description, entry point is the file that will be looked at when you require(‘module-name’); change the entry point to read src/index.js accept default for test, for github repo, enter some keywords, accept default license, and create package.json.

Next…Creating a Library

glyphicons-499-sunglasses start thinking about what you might want to make and keep it simple.

Sem.Ver.Blog

It is just Numbers and Dots, right?

I just released a new version of software. I called it 1.0.0. Why did I do that? Really it was because that is just what I do. When I make a very tiny change I adjust the last number up. When I have enough tiny changes that I can bundle them up I adjust the middle number and when I have a significant number of those changes I adjust the first number.

Is this right? No, no it is not. So it’s time to figure this out. Let me go to the source:

(from http://semver.org/)

Summary

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards-compatible manner, and
  3. PATCH version when you make backwards-compatible bug fixes.

Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

This makes way more sense. When you make incompatible API changes the major version must change, otherwise it is just extending the current versions functionality (still backwards-compatible) and finally if you are making changes, that don’t add functionality but fix originally intended functionality while maintaining the same backwards-compatibility it is a patch.

Why should I care? Do you want to live in dependency hell? I thought not. The more complicated software gets, the more likely conflicts occur among dependencies and interdependencies.  How do we avoid this? By making sure that when we write a library with a public API we show how it’s used and how it will not be used. Once these restrictions change we know we have to think about bumping up the major version. Those who want to keep their code working can stick with the working major version until they have reviewed potential impact and decide to upgrade or not.

It is not overly complicated, but I highly suggest reading the full spec to become fully enlightened. versioning

 

Prototypal Inheritance and you.

Let’s first start by saying that Javascript is a little interesting when it comes to classes and objects. Technically I think Javascript is basically classless (probably why I like it so much…) but there are class-like activities. Just remember at its root, an Object is a just a unordered collection of key:value pairs. Anything other than strings, numbers, booleans, undefined and null is an object.

Let’s create some objects.

var anObject = {};
anotherObject = new Object();

-or-

function MyObject() {}
var myObject = new MyObject();

 

Now where does Prototypal Inheritance enter into this? Each object has an internal link to another object, known as its prototype.  This other object also has a prototype, and so on until we reach null as its prototype.null ending the chain.

Objects are buckets of properties with links to a prototype object. When access to a property is requested it will look not only at the specific objects property but all the way back up the prototype chain until the property is found or the end of the chain.

Let’s add some methods to the objects.

function MyObject() {}

var myObject = new MyObject();

MyObject.simpleLog = function(value) {
    console.log(value);
}

var difObject = new MyObject();

difObject.simpleLog = function(value){
    console.log('The value is: ', value);
}

difObject.simpleLog("something should go here"); //calls the instance specific method
MyObject.simpleLog("something should go here"); //calls the static Object method
MyObject.prototype.simpleLog = MyObject.simpleLog; //apply the static method to all instances from here on in
difObject.simpleLog("still calling instance method");  //still calls the instance method
var yetAnotherObject = new MyObject();
yetAnotherObject.simpleLog("inherited from MyObject"); //inherited simpleLog() from MyObject
MyObject.simpleLog("I also inherit."); //pre-existing instances also inherit the new function

 

So as you can see when you add a method to the prototype it gets inherited along the prototype chain. There is an order to when this gets used as you can see in the difObject.simpleLog(); call that it uses the local instance method as it does not have to go up the chain to find the one we added with the line MyObject.prototype.simpleLog = MyObject.simpleLog;

Now when we reference methods in JavaScript it is not strictly accurate in the form that other class-based languages. For JavaScript any function that you add as an object property becomes a method for that object.  An inherited function acts just as any other property on that object, including method overriding!

Another key point to remember is what happens to this. Its value points to the inheriting object not back to the prototype object where the function is an own property. Let’s look at another example.

var myObject = {
    staticValue: 40,
    someMethod: function(val) {
      console.log(this.staticValue);
      return this.staticValue + 1;
    }
};

console.log(myObject.someMethod()); //42

var yourObject = Object.create(myObject);

yourObject.staticValue = 20;

console.log(yourObject.someMethod());  //21

 

As you can see once we overwrite a value it will no longer work its way up the chain allowing for differences in the objects after they are created. Very useful! I will be digging deeper into objects and modules in another post.

Importance of Self Documenting Code

What is self documenting code?

Let’s first take a look at code that is not self documenting.

var x = 1;
if (y === true) {
  x += 1;
}

vs 

let count = 1;
if ( loggedInSuccessfully === true ) {
  count += 1;
}

Even though this is a very simple example you can see right away that in the first example it is unclear what x is used for. You may be able to figure it out in context of the rest of the program but you might not.  In the second example it’s much easier to deduce that we are incrementing count every time someone has logged in successfully is true.

Now imagine this was a more complex function in the code.

function z () {
  let x = [];
  let y = _.keys(s);
  tables = _.map(y, function (y) {
    return function () {
       return z(y);
     };
   });
 return sequence(x);
}

vs

function createTables () {
  let tables = [];
  let tableNames = _.keys(Schema);
  tables = _.map(tableNames, function (tableName) {
     return function () {
       return createTable(tableName);
     };
  });
 return sequence(tables);
}

In this slightly more complex example there is only one clue as to what you might be doing in that first function. It’s the keyword sequence and even that just gives you a hint that they might be using the when promise library. This would require that either you wrote the horrible code so you know what it does or a decent amount of time trying to use it with in the code base.

The second one, well it looks like it wants to create a table based off an array of tables using the a function called keys to read the table names from a Schema variable. Then it builds that array by using a function called map to go over the tableNames schema, returning a function that calls the createTable function on the passed in tableName. Then we return the sequence output on that array we just finished building.

Even if that second paragraph does not make complete sense it will let you discuss the function with other programmers or support forums in a more intelligent way. That is the main benefit of self-documenting code, however it will also help you remember what you were doing when you have to revisit the code later.

One of the side effects of self-documenting code are potentially very long variable names. I have seen things along the lines of thisWillBeWhereWeStoreTheResultsOfTableCreationErrors. A bit hard to swallow but I have a pretty good idea what type of data I should expect to retrieve or store there.

Breaking it down

Reasoning

  • Create readable and understandable source code
  • Make it easier on the next guy (or your memory)
  • Keep code cleaner with less comments
  • Keep the documentation inside the code

Practices

The main goal is to make it as human readable as possible. Instead of single word variables use a phrase that is more closely tied to the meaning. The other aspect is to use white space to keep the structure consistent and reduce obfuscation of the algorithm being used.

Gotchas

 

There are things to watch out for, if working with a team, is to maintain uniformity, consistency and to make sure it doesn’t get too far out that it becomes a novel to go through your code.

If you stick to these basic guidelines you will do better than many professional developers out there. If you want to learn more head over to the wiki page.

Maker Square Day 5

Test Driven Development
Write a failing test, then code to the test. Go from Red to Green to Refactor. Why test? It changes the way you think about code. Forces the MVP thought process. Once you have an error, write a test.
Types of Testing
Unit Test – normally focus on 1 single method or class. Unit testing uses faked data.
Integration Test – ensures different parts of system work together like creating a customer, logging in a customer etc.
End to End test – make sure it works in real world test most realistic form of test. Start to finish, whole system. Think about smarter, less tests.
Visual Test – does it look like what it should look like?

 

Makers Square Day 3

I don’t know about you but sleep has not been a close and personal friend of mine. Its a love/hate relationship at best tending towards the latter, or is it ladder? I must be tired. It was on Day 3 (dun, dun, dunnnn) that I noticed that I had forgotten to sleep much *cough* is that an owl? *harumph* I am fine, as I was saying an owl has three eyelids: one for blinking, one for sleeping and one for keeping the eye clean and healthy. Wait, I had a segue I was supposed to say, something about night owls…

To The Notes!!!

Best Practices

I have to preface this with a caveat. I really liked this lecture. It made me feel as though I could contribute if only because I enjoy clarity over cleverness. I usually stand in awe of cleverness, but strive for clarity. If that makes sense. Well on to the actual notes.

Save often! Use the auto-save feature of whatever IDE you are in. If it does not have one complain. Only commit to git when working.

Frameworks, when, where, why? (sometimes what?) – It’s a roll your own (smoking reference in this day and age?) vs others. If you really must I would say roll your own, but REALLY look for another solution or you are wasting your time. Let others solve the problems that have already been identified by the community, for now. (A Jedi must have patience)

Modularity

Keep parts together that are related. Avoid bad closure. use input var/let for dependencies, avoid mutating. avoid global. avoid side effects.

Decoupling

Keep unrelated things, unrelated. It sounds obvious but I have found it easy to want to ‘normalize‘ everything. This is the wrong use of normalize, hence the quotes and italics but you will hear it used this way in the real world. They really mean avoid mutating. I see decoupling as breaking the functions down to as small as possible. For the MASH fans out there:

I do one thing at a time, I do it well, and then I move on.
                                                                   –Charles Emerson Winchester III

Abstractions

Hide the guts. Show the usage. It really can be that simple. Think _.each(array, thingToDo); vs

function(collection, iterator) {
  if(Array.isArray(collection)){
    for (var i=0; i < collection.length; i++)
     iterator(collection[i], i, collection);
  } else {
    for (var key in collection) {
       iterator(collection[key], key, collection);
    }
  }
}

Style

Self describing code is better than comments, but comments are better than clever. Follow the company style. Aim for short, compact code. MVP first.

Embrace Failure!

Failure is inevitable, it also indicates you are doing something interesting. Simply put, what is the formula for success? Fail until you succeed.

Common Pitfalls

Failure to read instructions. Read them. Then re-read them. Then.. yeah. Think about the intention.

Formatting

Use 2 spaces instead of tab. White space is your friend. Be consistent. Keep blocks aligned. Avoid redundancy. Keep blocks aligned. Did I mention to avoid redundancy? No? Well do it.

‘use strict’

It was a great day!