Care for your code

Your code is a living thing. Like any living thing, it changes constantly. Old parts die and sluff off. New parts grow to replace them. Your code goes where the customers take it. One day it needs to spend all of its waking hours in the burning sun. The next it might be whisked off to the frigid tundra. Wherever it goes, you go with it, and your code depends on you to take care of it!

Care for your code!

Let’s make sure we call out that your code needs direct care. Just like a pet, your code needs to be cleaned periodically. It also needs to be groomed. You can’t let those fingernails grow too long. You must not neglect to brush your pet. It’s important to keep up with regular medical and dental visits. Preventive care, like vaccines, are important. Apply security patches. Upgrade dependencies. Remove dead code. Make sure failing tests get fixed. I can’t forget to mention that you need to watch your code for any concerning changes. If your code starts shedding hair for no obvious reason, its not time to sit back and hope that things get better.

Care for your code!

Your code needs a lot of supporting accessories. It needs memory (physical and logical), bandwidth, and data. It also needs at least a development environment and a production environment. Most of your code needs one or more of an integration, QA, staging, UAT, and/or performance testing environment. (Maybe more.) That means you need build pipelines with build, deployment, and dependency management servers. Your code also needs supporting services and databases. Not only do you need the direct databases or services that you depend on, but you also need monitoring infrastructure.

Care for your code!

For all of these things, you should have a way to go from newly unboxed server or a newly created virtual machine to fully functioning environment in less than a day. Its best if this is automated and you do it often. The point is: just like a fish tank, the environment around your code needs care. Keep an eye on it and clean it up regularly. Change the water and the filter. Vacuum the gravel.

Care for your code!

What about regular use and inspection? Does your code get enough? Do you exercise the code? I don’t mean by your customers. End users are total strangers who have no connection with your code, and who expect you to take care of it enough that they can get done whatever they need to get done. Those people aren’t there to exercise your code. They need something from your code. If your code were a horse rented to tourists in the Grand Canyon, you wouldn’t put her in the stable at night, and take her out in the morning for the next unsuspecting sap, without going over every inch of her to make sure she’s still in shape for the task.

Care for your code!

I know it’s easy to think that code is a static entity. Just words in a file somewhere. Something that sits there and does its job. Just another company asset like a desk or a whiteboard. But this is not the case. Code is alive and code matters.

Care for your code!


Java Optional, WTF?

People say Java’s Optional is broken. And man is it ever!

Let’s say you have a value object, Name, like this:

public class Name {
    private String first;
    private String last;
    public Name(String first, String last) {
        this.first = first;
        this.last = last;
    public String getFirst() {
        return first;
    public String getLast() {
        return last;
    public String getFullName() {
        return first + " " + last;

And elsewhere you have these lines of code:

Optional<Name> optionalName = Optional.of(new Name(null, null));
Optional<String> optionalFirst = optionalName.flatMap(name -> Optional.of(name.getFirst()));

Seems totally reasonable! But when you run it:

Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(
    at java.util.Optional.<init>(
    at java.util.Optional.of(
    at com.scottshipp.www.OptionalWTF1.lambda$main$0(
    at java.util.Optional.flatMap(
    at com.scottshipp.www.OptionalWTF1.main(

This is why Java’s Optional is broken!

Uh…no it’s not

But yeah, you’re a clever, observant person. You noticed that I didn’t use ofNullable in that example. It should be Optional.ofNullable(name.getFirst()).

So that totally works…

Optional<Name> optionalName = Optional.of(new Name(null, null));
Optional<String> optionalFirst = optionalName.flatMap(name -> Optional.ofNullable(name.getFirst()));

Uh… Yes it is

…but WTF? Why? Why is there an ofNullable method separate from the of method? Fucking everything in Java is nullable! Except
primitives but you can’t pass fucking primitives to either of these methods! What is this shit? What are they smoking at Oracle?

Scala only has Option (the apply method on the Option class) and it only does what ofNullable does and returns None if you pass it null:

case class Name(first: String, last: String)
val optionalName = Option(new Name(null, null))
val optionalFirst = optionalName.flatMap(name => Option(name.first))

No NullPointerException! The optionalFirst variable now holds a None.

I tried hard to fuck up Scala code as bad as Java and I could not get a NullPointerException out of it.

The worst part

Do you want to know the worst part of this? The part that makes me want to punch “Duke”, Java’s mascot, in the mouth?

The worst part is that NullPointerException is a runtime error!

And, clearly, this is something that the compiler could figure out. It turns out, that this NullPointerException is entirely on purpose, it’s part of the method contract for of (see its Javadoc). For what inhuman reasoning I can’t even guess.

The worst worst part

So now because of that, you can write a one-line Java program that compiles just fine but throws a NullPointerException:

public class OptionalWTF0 { public static void main(String[] args) { Optional.of(null); } }
Exception in thread "main" java.lang.NullPointerException
    at java.util.Objects.requireNonNull(
    at java.util.Optional.<init>(
    at java.util.Optional.of(
    at com.scottshipp.www.OptionalWTF0.main(

Jasmine Unit Tests in an RxJs + Firebase app: Part 2

For today’s post, we’ll cover some useful test execution shortcuts and then dive into how to test code that uses AngularFire’s database.list.push() method to write data into the database.

Jasmine Test Execution Shortcuts

Part 1 covered describe and it, functions that are part of Jasmine that provide BDD-style tests. We looked at the following simple test:

describe("The Alert Helper", () => {

   // DI, setup, and beforeEach code elided

  it("should create an error alert with a provided message", () => {
    spyOn(AlertCtrlStub.prototype, "create").and.callThrough();

    alertHelper.triggerErrorAlert("This is a message!");

      message: "This is a message!",
      buttons: [
          text: "Ok",
          role: "cancel",

As you can see describe can be used to mark a suite of tests and each individual test can live in an it.

Now consider what happens when you build up enough tests in your application that it takes awhile for your entire test suite to run . . .


Jasmine Unit Tests in an RxJs + Firebase app: Part 1

Unit testing can be…well….different in an app built on libraries devoted to functional, asynchronous paradigms. AngularFire 2 may well be the epitome of this. There’s a lot to unpack. It’s TypeScript for one thing, not just plain JS. On top of that, add the RxJs library. Firebase‘s realtime database feature is both real-time and NoSql for another thing. It uses WebSocket so all the RxJs stuff really does sit around emitting events whenever data changes in Firebase. Phew! This does not make things plain and simple!

I’ve gathered some experience with it the past eight months in an Ionic mobile app, and here are the tips and tricks I have gathered, collected, stumbled upon, and cringed over. We used Jasmine as the test framework in my application, and these examples do the same.

By no means do I mean the examples below to be prescriptive or otherwise thought of as “the way to do things.” Probably there are better ways. But they have worked for me and my team. I encourage anyone to provide suggestions and feedback in the comments section.

Getting started with first things first: setup . . .