Skip to content

Extending Expect

James Richford edited this page Jan 6, 2017 · 1 revision

Extending the Expect call in Alsatian is super simple as it's OO and extensible by default! All you need to do is extend...

class MatcherExtension extends Matcher {
    isSomething() {
        if (this.actualValue !== "something") {
          throw new MatchError("should have been something", "something", "not something");
        }
    }
}

Then if you want to you can wrap it in a function to add some neat fluent syntax

// name it whatever your heart desires
export ExtendedExpect = (value: any) => new MatcherExtension(value);

Here's an explanation of some of the concepts that are useful here

this.actualValue

This is the value that is added into the Matcher constructor / Expect function i.e. the value under test

this.shouldMatch

This indicates whether the not opperator has been used

Expect(something).toBe(nothing);     // this.shouldMatch === true
Expect(something).not.toBe(nothing); // this.shouldMatch === false

MatchError

Throwing this error will tell Alsatian that the test found something wrong (you can extend this too). It has three arguments, the actual value, the expected value and a message. A usage example can be found below.

throw new MatchError(
  "expected nothing to be something, but it wasn't.",            // an explanation of the issue
  "something",                                                   // what the value was expected to be
  "nothing"                                                      // what the value actually was
);

You may also set each value independently if you extend them (as the setters are protected)

export class ExtendedMatchError {
  public constructor() {
    super();
    this.message = "expected nothing to be something, but it wasn't.";
    this._expected = "something";
    this._actual = "nothing";
  }
}

Example assertion function

public toBeHexCode() {
    // check whether the value provided in Expect() is a hex code or not
    const isHexCode = /^#[A-F|0-9]{6}$/i.test(this.actualValue);
    
    // if the value should have been a hex code and wasn't
    // or should not have been and was
    if (isHexCode !== this.shouldMatch) {

      // output for Alsatian that it should have been a hex code
      if (this.shouldMatch) {
        throw new MatchError(                                             
          `expected {this.actualValue} to be a hex code but it wasn't.`,                                                    
          "a hex code",     
          "not a hex code"
        );
      }
      // output for Alsatian that it should not have been a hex code
      else {
        throw new MatchError(                                            
          `expected {this.actualValue} to not be a hex code but it wasn't.`,                                           
          "not a hex code", 
          "a hex code"        
        );
      }
    }
}

Usage

Now you're ready to use your extended Expect. This is super easy...

import { ExtendedExpect as Expect } from "./your/extended-expect/location";
import { TestFixture, Test } from "alsatian";

@TestFixture("color tests")
export default class ColorTestFixture {

  @Test("check hexcodes")
  public checkHexcodes {
    Expect("#00000").toBeHexCode();
  }
}