The Blog of Brandon G Parker

Running List of Milk Dishes That Taste the Same With Almond Milk

I eat somewhat healthily but am trying to get better. Part of this process is to limit my intake of animal products such as meat, eggs, and dairy. One big way to do this is to substitute almond milk any time a recipe calls for regular cow milk. This list will be updated as I discover more items that taste the same with almond milk as a substitute.

For these I’m only going to be using original (unflavored) and unsweetened almond milk.

  • Cereal
  • Condensed soups
  • Macaroni and Cheese
  • Milkshakes (although this sort of defeats the purpose)
  • Oatmeal
  • Scrambled eggs
  • Smoothies

Last updated 2017-11-11

Pin It
Read More Leave comment

Calculate the Distance Between Two Coordinates in PHP

Sometimes you search the web for some obscure problem you need to solve, like calculating the distance between two points, thinking that you’ll for sure never need this ever again. This, my friends, is not one of those examples. While I thought I’d never need this I have come back to this helpful function time and time again. Below is a helpful function that takes in two coordinates and returns the distance. Let’s break this down.

private function distanceGeoPoints($lat1, $long1, $lat2, $long2) {
    define('EARTH_RADIUS', 3958.75);    // in miles

    $dLat = deg2rad($lat2-$lat1);
    $dLng = deg2rad($long2-$long1);

    $a = sin($dLat/2) * sin($dLat/2) +
         cos(deg2rad($lat1)) * cos(deg2rad($lat2)) *
         sin($dLng/2) * sin($dLng/2);

    $c = 2 * atan2(sqrt($a), sqrt(1-$a));
    $dist = EARTH_RADIUS * $c;

    return $dist;
}

The first line inside this function is defining a constant for the radius of the Earth. This is important for a couple reasons: the Earth radius is (relatively) constant so we don’t want to run the risk of accidentally assigning this some other value, and 2) the units you put for this radius will also tell you what units you’ll get your resulting return in as well. So, if you want miles between points, use miles. If you want feet, use feet (20902231.64). A simple Google conversion should help you here.

Next we need to convert these coordinates which are in degrees into radians. We can see that we’re taking the second latitude and subtracting the first and the same with the longitude.

Note: don’t name your longitude variables as “long” because in many systems that’s a reserved keyword. In general it’s bad practice.

I won’t get into the somewhat complicated math that happens next but basically we’re taking the various conversions and coordinates we already have and performing geometric arithmetic to them in the form of sine and cosine and doing some other additions and multiplications and such. From this we come up with $a.

Next we do some more geometric arithmetic in the form of an arc tangent and some square roots involving $a which gives us $c. Then all we have to do is multiply $c with the EARTH_RADIUS constant we defined before to get our distance.

Pin It
Read More Leave comment

Helpful SASS/LESS Mixins

Mixins are one of the most helpful and powerful features of SASS/SCSS/LESS. Being able to define a block of code like a function in JavaScript and use that over and over again in your stylesheets is awesome. Being able to make changes in just one place or being able to calculate values or pass values to your mixin makes them very extendable. Here are some of the most useful mixins that I use daily.

While these are specifically written for SASS they can easily be adapted to LESS.

border-box

Any time there are multiple vendor-prefixed conditions to be included for one specific property means it’s perfect for a mixin. Using border-box is one of these examples.

@mixin border-box {
    -moz-box-sizing: border-box;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}

border-radius

border-radius is another property that requires several vendor-prefixed properties to accommodate older browsers.

@mixin border-radius($radius) {
    -moz-border-radius: $radius;
    -ms-border-radius: $radius;
    -webkit-border-radius: $radius;
    border-radius: $radius;
}

clearfix

Whenever you’re floating elements on the page you lose that block of height because it’s taken out of the general flow of the page. Therefore you can force the height of the parent element with this mixin.

@mixin clearfix {
    &:before, &:after {
	content: " ";
	display: table;
    }

    &:after {
	clear: both;
    }
}

img-responsive

Today if a site isn’t response in some way the user experience suffers so much they’ll likely leave. Until more browsers can support tags like <picture> we need a way to change the width of images based on screen width. This mixin allows us to always force the picture to be as large as it’s container element while maintaining aspect ratio, making sure not to enlarge the image past it’s 100% width.

@mixin img-responsive {
    height: auto;
    max-width: 100%;
}

list-reset

It’s standard practice to use unordered lists for navigation and other elements on the page. Instead of constantly repeating the same code over and over each time you use a list you can include this into a helpful mixin. This works with both ordered and unordered lists.

@mixin list-reset {
    list-style-type: none;
    margin: 0;
    padding: 0;
}

opacity

There’s a trend with a lot of these mixins where in order to support older browser vendor-prefixed properties are required. This is no exception and will allow you to use the opacity property.

@mixin opacity($opacity) {
    $opacity-ie: $opacity * 100;
    filter: alpha(opacity=$opacity-ie); //IE8
    opacity: $opacity;
}

There are hundreds of helpful mixins but these are ones I use in every project. Post in the comments below what mixins you can’t live without!

Pin It
Read More Leave comment

Introduction to Unit Testing es6 JavaScript Modules

Introduction to Unit Testing es6 JavaScript Modules

In this post I will demonstrate how to go about unit testing the most basic example of JavaScript code. You’ll quickly see how important unit testing can be and how much it can introduce a very solid quality check against your code, allowing you to release more confidently.

To start, let’s assume the following very basic example. Note that this example is so basic you’d probably never have code like this.

string-functions.js

export function convertToLowerCase(str) {
     return str.toLowerCase();
}

This exported function, when called, will take in a string and return the string in all lowercase. Now let’s consider writing some unit tests for the code as-is. We can check to see the function actually exists. This is the most basic check and while it doesn’t provide any actual code coverage it will add a quality check to make sure if the function is removed the test will not pass.

For all of these examples we’re assuming that we’re running karma, mocha, sinon, and chai for our technology stack (although other packages will work, too). We’re also going to assume that these are wrapped in the required describe wrapper, so this is just the it statement for each test.

it('convertToLowerCase should be a function', function() {
     assert.isFunction(strFunctions.convertToLowerCase);
});

As I previously stated this provides no coverage and we actually have 0% code coverage at this point. But before we can write more tests we probably need to ask some questions about the code in order to know what tests to write. So let’s ask some questions about this code:

  1. Is passing a string required?
  2. What happens if something other than a string is passed?
  3. Is a string always returned?
  4. Does the function return a lowercase version of the string that was passed?

Let’s look at these one at a time.

Is passing a string required?

Yes, in order to use the toLowerCase() method a string needs to be passed.

What happens if something other than a string is passed?

Passing something like an object is going to throw an error. Passing nothing will cause an error. We really only want to be able to pass a string to this function.

Is a string always returned?

For sure if a string is passed in a string will be passed out. But if we’re not passing a string in we have unexpected results. We always need a string.

Does the function return a lowercase version of the string that was passed?

We need to assume a string is being passed, it’s important to make sure the expected result is the actual result of this function so that we can possibly iterate on it later.

Based on these answers we need to modify the code some in order to ensure expected results always.

export function convertToLowerCase(str) {
     if (!str || typeof str !== 'string') {
          return false;
     }

     return str.toLowerCase();
}

Now, with these changes, we force the developer to pass in a string. We won’t get any sorts of errors if we don’t because we aren’t executing that code. We can also then guarantee that we’re always going to return a string and the string will always be as expected. So let’s write tests to confirm this:

it('convertToLowerCase() should return bool false when no parameter is passed', function() {
     assert.isBoolean(strFunctions.convertToLowerCase());
     assert.equal(false, strFunctions.convertToLowerCase());
});
it('convertToLowerCase() should return bool false when parameter passed is not a string', function() {
     assert.isBoolean(strFunctions.convertToLowerCase(1234));
     assert.equal(false, strFunctions.convertToLowerCase(1234));

     assert.isBoolean(strFunctions.convertToLowerCase(['asdf']));
     assert.equal(false, strFunctions.convertToLowerCase(['asdf']));

     assert.isBoolean(strFunctions.convertToLowerCase(true));
     assert.equal(false, strFunctions.convertToLowerCase(true));

     assert.isBoolean(strFunctions.convertToLowerCase(null));
     assert.equal(false, strFunctions.convertToLowerCase(null));

     assert.isBoolean(strFunctions.convertToLowerCase({ 'option': true }));
     assert.equal(false, strFunctions.convertToLowerCase({ 'option': true }));
});
it('convertToLowerCase() should return a string when a string is passed', function() {
     assert.isString(strFunctions.convertToLowerCase('ASDF'));
});
it('convertToLowerCase() should return a lowercase string when a string is passed', function() {
     assert.equal('asdf', strFunctions.convertToLowerCase('ASDF'));
     assert.equal('asdf', strFunctions.convertToLowerCase('asdf'));
     assert.equal('another test', strFunctions.convertToLowerCase('Another Test'));
});

Before we refactored the code we had no branches but 1 line, 1 statement, and 1 function, all for 0% code coverage. When we refactored the code we introduced 4 branches and an additional line and statement. We’ve successfully tested all lines, statements, functions, and branches. We’ve introduced negative checks to go along with our happy-path tests and have much greater confidence in the future that if we make a change to this function we’ll know before we release it if it might break a function that relies upon it.

Pin It
Read More Leave comment

Code Coverage with es6, Babel, Karma, Mocha, and Webpack

I was trying to get JavaScript unit testing set up at work and was really struggling. While I could get unit tests and established a testing framework I wasn’t able to determine my code coverage. For those of you that haven’t tested before, code coverage is a really important aspect of unit tests because it will tell you where you have gaps in your tests. If you’re not testing a specific branch or function you have a greater chance of pushing out a bug because the code isn’t tested.  So code coverage is pretty important.

Take this piece of my devDependencies within my package.json.

package.json:

"devDependencies": { 
    "babel-core": "6.23.1", 
    "babel-loader": "6.3.2", 
    "babel-preset-es2015": "6.22.0", 
    "babel-preset-stage-1": "6.22.0", 
    "chai": "3.5.0", 
    "gulp-mocha": "4.0.1", 
    "karma": "1.5.0", 
    "karma-cli": "1.0.1", 
    "karma-coverage": "1.1.1", 
    "karma-mocha": "1.3.0", 
    "karma-phantomjs-launcher": "1.0.2", 
    "karma-sinon-chai": "1.2.4", 
    "karma-webpack": "2.0.2", 
    "mocha": "3.2.0", 
    "sinon": "1.17.7", 
    "sinon-chai": "2.8.0", 
    "webpack": "2.2.1" 
} 

This is a pretty standard build out when you’re using es6 (Babel) and are transpiling down from 6 to 5 as part of your bundling/minifying/uglifying process (Webpack). I chose the Karma/Mocha/Sinon/Chai technology stack simply because it’s widely adopted and lightweight. Some people prefer Jasmine more, which is fine, Jasmine comes with a lot of this functionality built-in, but I like to have options.

A lot of sites tell you to set up your karma.conf.js file something like this:

karma.conf,js


const src = './scripts/**/*.js',
      tests = './tests/**/*.spec.js';

const karmaConfig = {
    frameworks: ['mocha', 'sinon-chai'],
    files: [
        src,
        tests
    ],
    preprocessors: {
        src: ['webpack', 'coverage'],
        tests: ['webpack']
    },
    webpack: webpackConfig('test'),
    reporters: ['coverage'],
    browsers: ['PhantomJS'],
    client: {
        captureConsole: false
    },
    specReporter: {
        showSpecTiming: true
    },
    reportSlowerThan: 25,
    coverageReporter: {
        dir: 'coverage',
        reporters: [
            { type: 'text' },
            { type: 'text-summary' },
            { type: 'html' }
        ]
    }
};

karmaConfig.preprocessors[src] = ['webpack', 'coverage'];
karmaConfig.preprocessors[tests] = ['webpack'];

module.exports = function (config) {
    config.set(karmaConfig);
}

If you have something like this you’ll get bundled output and your tests will run, but your test coverage will be extremely low. If you add the coverage reporter to the tests you’ll likely get an error saying you can’t require the module because the module is already required. You’ve created a cyclical reference.

What we want really is to run the tests, and from the tests determine what source code was executed by the tests. But we also need to run the tests and code coverage on the non-transpiled code. In order to do this we need to include another handy babel package:

npm install babel-plugin-istanbul --save-dev

Istanbul is pretty much the gold standard when it comes to coverage reporting in the front-end world and it does this extremely well. I also have a JSON file of config settings, that currently has this node for Babel:

config.json


"babel": {
     "presets": [
          ["es2015", {
               "modules": false
          }],
          "stage-1"
     ]
}

So I need to add another configuration to this file:


"babel": {
     "presets": [
          ["es2015", {
               "modules": false
          }],
          "stage-1"
     ],
     "plugins": [
          ["istanbul", {
               "exclude": [
                    "**/*.spec.js"
                ]
          }]
     ]
}

You’ll notice a line about exclusions. This plugin by default will exclude certain naming conventions from your code coverage. If you don’t use one of the standards (which sometimes I don’t) it will include the test code files as part of your code coverage report – not good!  So I just add in the path to my test files to prevent this.

We also need to remove the coverage reporter from the files but leave the coverage reporter settings. This seems wrong but I promise this works. We also don’t want to include source files in our karma.conf.js file because right now we only want to get coverage for files that we have created a test file for. Why? Well what if we had a vendor script? If we included that file we’d be penalized for not writing unit tests on the file or maybe we’d write unit tests on the file anyway, which could be troublesome if it’s not written for testability. Ideally third-party and vendor scripts have been tested during the development phase.


const tests = './tests/**/*.spec.js';

const karmaConfig = {
    frameworks: ['mocha', 'sinon-chai'],
    files: [
        tests
    ],
    preprocessors: {
        tests: ['webpack']
    },
    webpack: webpackConfig('test'),
    reporters: ['coverage'],
    browsers: ['PhantomJS'],
    client: {
        captureConsole: false
    },
    specReporter: {
        showSpecTiming: true
    },
    reportSlowerThan: 25,
    coverageReporter: {
        dir: 'coverage',
        reporters: [
            { type: 'text' },
            { type: 'text-summary' },
            { type: 'html' }
        ]
    }
};

karmaConfig.preprocessors[tests] = ['webpack'];

module.exports = function (config) {
    config.set(karmaConfig);
}

Now when we run our tests we will get coverage only on the files that we want to have coverage for. Look out for posts on how to write unit tests and how to write your code to be testable in the future. There will also be a post on how to test third-party scripts, because sometimes it’s a critical component and you need the certainty that upgrades won’t break functionality on the site.

Pin It
Read More Leave comment