fbpx

Testing exceptions with Async Await

Normally when testing your code throwing exceptions is goes something like this: (examples in typescript with Jasmine)


function isTwo(num: number): number {
  if(num != 2) throw new Error("Yo! It's not number 2!!");
  return num;
}

// ... inside describe block
it("should throw an error", () => {
  const throwError = function() { isTwo(3) };

  expect(throwError).toThrowError("Yo! It's not number2!!")
}

We wrap our function in an anonymous function and pass it to the expectation.  All is good and we move on with our day!

But what if our function is returning a promise! Aha, things can’t work the same.

Let’s use async / await to help us.


function isTwo(num: number): Promise<number> {
  new Promise(resolve, reject) {
    if(num != 2) reject("Yo! It's not number 2!!");
    resolve(num);
  }
}

// ... inside describe block
it("should throw an error", async () => {
  try {
    const throwError = isTwo(3); 
  } catch(error) {
    expect(error.message).toBe(""Yo! It's not number 2!!");
  }
}

Bootstrapping WordPress

Today I came across a situation where I needed to use the wordpress core but did not need the theme as the project had a separate framework for the front end.  To accomplish this you can add the following code to your php file:

<?php
    /** Must be false to disable template! */
    define('WP_USE_THEMES', false);

    /** Loads the WordPress Environment */
    require ('./wp-blog-header.php');

JSON API Resource GEM

Working on a Rails project using JSON API Resource gem I came across an interesting “gotcha”. When making a POST request and the JSON key is multiple words you must use dashes to separate the words, the corresponding incoming param uses underscore.

For example you have the following Model attribute: date_of_birth. JSON API Resource will not accept “date_of_birth” only “date-of-birth”.

Testing time based activities in Angular

When testing time streams or promised based activities use ‘fakeAsync’ and ‘tick’.

For example, given a service:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Rx';

@Injectable()
export class CountdownService {
  // counts down from given number to zero
  source(num: number): Observable<number> {
    return Observable.timer(1000, 1000)
    .map( (v) => num - v)
    .takeWhile( (v) => v !== -1);
  }
}

To test the CountDown class source method:

// … test setup above, inside describe function

it('should count down from 5 to 0', inject([CountdownService], fakeAsync( (service: CountdownService) => {
    let num: number = undefined;
    const count = service.source(5).subscribe( (value) => num = value);
    tick(7000)

    expect(num).toEqual(0);
})));

Wrap the ‘it’ callback function in fakeAsync() which creates a new zone for the asynchronous code to run.

Calling tick() with a time span in ms, simulates the code after that amount of time has passed.

Use tick() with no arguments for promise based code

My expectation is based on what happens after 7 seconds has passed.

Using Wicked PDF gem in rails in a docker container

When you need to generate a PDF in your rails application the wicked PDF gem is great and easy to use. But requires the wkhtmltopdf binary to run. If you are running you rails app in a docker container be sure to use the linux binary. Go to https://wkhtmltopdf.org/downloads.html and download the linux 64-bit binary to your rails bin directory. Open bash in your docker container and cd into the bin directory:

docker-compose run app bash
cd bin

Then uncompress your binary:

tar -xJf wkhtmltox-0.12.4_linux-generic-amd64.tar.xz

Reference the new binary for your development environment in the initializer:

if Rails.env.production?
  wkhtmltopdf_path = "#{Rails.root}/bin/wkhtmltopdf-prod"
else
  wkhtmltopdf_path = "#{Rails.root}/bin/wkhtmltox/bin/wkhtmltopdf"            
end

Environment Variables in Webpack

Diving into webpack module loader can often seem like a confusing and daunting task. Luckily, setting environment variables is rather straight forward.

At the top of your webpack.config.js file define your environment variables like so:

/**
 * Example Constants
 */
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const API_URL = process.env.API_URL = 'http://localhost:3000';
const METADATA = {
  API_URL: API_URL,
  ENV: ENV
};

Then in the plugins array use DefinePlugin method to define global variables configured at compile time:

/**
 * Make Webpack Constants Available Globally
 */
   new webpack.DefinePlugin({
     'ENV': JSON.stringify(METADATA.ENV),
     'API_URL': JSON.stringify(METADATA.API_URL),
     'process.env': {
       'ENV': JSON.stringify(METADATA.ENV),
       'NODE_ENV': JSON.stringify(METADATA.ENV),
       'API_URL' : JSON.stringify(METADATA.API_URL),
     }
   }),

Re-compile and now your variables will be globally available.

Immutable Objects using Object.assign

Is immutability important? Mutating data can produce code that’s hard to read and error prone. But we can avoid this mess using vanilla javascript’s ES6 feature Object.assign!

Let’s look at the problem….

var obj1 = { key: 'some value' };

var obj2 = obj1;
obj2.key = 'another value';

console.log( obj1 === obj2) // true
console.log( obj1.key ) // 'another value'

When we changed obj2’s key property, it also changed obj1’s key property. No bueno! The solution:

var obj1 = { key: 'some value' };

var obj2 = Object.assign( {}, obj1, { key: 'another value' });

console.log( obj1 === obj2) // false
console.log( obj1.key ) // 'some value'
console.log( obj2.key ) // 'another value'

As you can see we changed obj2’s key property and it left obj1’s state intact! Now that’s immutable! Object.assign takes objects as its parameters and passing in an empty object as the ‘target’ keeps our ‘source’ objects intact.

Object.assign is widely supported by desktop and mobile browsers, please check Mozilla for more info.