Home Manual Reference Source Test

src/assert/index.js

/**
 * Asserts help you to make sure, the buffer you're parsing
 * is in the correct format. These assertions are like chai, throwing an error
 * when an assertion doesn't hold.
 *
 * These functions won't modify {@link Corrode#vars}.
 */

import lodash from 'lodash';

/**
 * assert strict equal single value
 * @param {string} name   key of the value to test
 * @param {mixed}  value  comparision
 * @throws TypeError assertion-error
 */
export function equal(name, value){
    if(this.vars[name] !== value){
        throw new TypeError(`Expected ${value}, found ${this.vars[name]} at ${name}`);
    }
}

/**
 * assert deep equality each value in Object|Array
 * @param {string} name     key of the object|array to test
 * @param {mixed} testValue comparision, undefined for auto-detect
 * @throws TypeError assertion-error
 */
export function allEqual(name, testValue){
    let values = this.vars[name];
    if(!Array.isArray(values)){
        values = lodash.values(values);
    }

    if(typeof testValue === 'undefined'){
        testValue = values[0];
    }

    const notEqualObjects = values.filter(varValue => varValue !== testValue);
    if(notEqualObjects.length !== 0){
        throw new TypeError(`Expected values in ${JSON.stringify(this.vars[name])} to all be ${testValue}`);
    }
}

/**
 * assert equality objects
 * @param {string} name  key of the object to test
 * @param {object} value comparision
 * @throws TypeError assertion-error
 */
export function deepEqual(name, value){
    const binaryValue = this.vars[name];
    if(!lodash.isEqual(binaryValue, value)){
        throw new TypeError(`Expected ${JSON.stringify(value)}, found ${JSON.stringify(binaryValue)}`);
    }
}

/**
 * assert array|object to contain item
 * @param {string} name key of the value to test
 * @param {array|object} arr comparision
 * @throws TypeError assertion-error
 */
export function includes(name, arr){
    if(!lodash.includes(arr, this.vars[name])){
        throw new TypeError(`Expected ${JSON.stringify(arr)} to include ${this.vars[name]}`);
    }
}

/**
 * assert value to be within the bounds of an array
 * @param {string} name  key of the number to test
 * @param {array} value comparision
 * @throws TypeError assertion-error
 */
export function inBounds(name, value){
    const index = this.vars[name];

    if(index < 0 || index >= value.length){
        throw new TypeError(`Expected Array of ${value.length} items to be at least ${index} long`);
    }
}

/**
 * assert value via callback
 * @param {string}   name   key of the value to test
 * @param {function} fn     callback
 * @param {string}   testname optional test-name
 * @throws TypeError assertion-error
 */
export function callback(name, fn, testname = fn.name){
    if(!fn(this.vars[name])){
        throw new TypeError(`Callback failed at ${testname}(${this.vars[name]})`);
    }
}

/**
 * assert array to be a given length
 * @param {string}        name   key of the value to test
 * @param {number|string} length comparision
 * @throws TypeError assertion-error
 */
export function arrayLength(name, length){
    // try to get the length param from the vars if available
    if(typeof length === 'string' && this.vars[length] !== 'undefined'){
        length = this.vars[length];
    }

    if(typeof this.vars[name] === 'undefined' || this.vars[name].length !== length){
        throw new TypeError(`Expected array to have a length of ${length}, has ${this.vars[name].length}`);
    }
}

/**
 * asserts a variable exists in the first place
 * @param {string}   name   key of the value to test
 * @throws TypeError assertion-error
 */
export function exists(name){
    if(typeof this.vars[name] === 'undefined'){
        throw new TypeError(`Expected var ${name} to exist`);
    }
}

/**
 * asserts a variable matches a given bitmask
 * @param  {string} name         key of the value to test
 * @param  {number} mask         bitmask to match
 * @param  {boolean} assertMatch true: should match; false: shouldn't match
 * @throws TypeError assertion-error
 */
export function bitmask(name, mask, assertMatch = true){
    const val = this.vars[name];

    if((val & mask) === mask === !assertMatch){
        throw new TypeError(`Expected var ${name} to ${assertMatch ? '' : 'not '}match bitmask (value: 0b${val.toString(2)} assert: 0b${mask.toString(2)})`);
    }
}