UNPKG

unassessed

Version:
2,192 lines 75.2 kB
function createCasedFunction(
  expect,
  typesOfValues,
  __assertionString__,
  __camelCasedString__
) {
  if (typesOfValues.length === 0) {
    return function (subject) {
      return expect(subject, __assertionString__);
    };
  }

  if (typesOfValues.length === 2) {
    return function (subject, value, value2) {
      if (
        (value && value.__itPlaceholder) ||
        (value2 && value2.__itPlaceholder)
      ) {
        throw new Error(
          ("unassessed: nested assertions are not supported by ." + __camelCasedString__ + "()")
        );
      }

      return expect(subject, __assertionString__, value, value2);
    };
  }

  return function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        ("unassessed: nested assertions are not supported by ." + __camelCasedString__ + "()")
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, __assertionString__ ].concat( args ));
  };
}

function createCasedFunctionOpen(expect, __assertionString__) {
  return function (subject, valueOrItPlaceholder) {
    return expect(subject, __assertionString__, valueOrItPlaceholder);
  };
}

function createCasedFunctions(expect, casedDefinitions) {
  var casedFunctions = {};

  Object.keys(casedDefinitions).forEach(function (camelCasedString) {
    var ref = casedDefinitions[camelCasedString];
    var assertionString = ref.assertionString;
    var isNestingAllowed = ref.isNestingAllowed;
    var typesOfValues = ref.typesOfValues;

    if (isNestingAllowed) {
      casedFunctions[camelCasedString] = createCasedFunctionOpen(
        expect,
        assertionString
      );
      return;
    }

    casedFunctions[camelCasedString] = createCasedFunction(
      expect,
      typesOfValues,
      assertionString,
      camelCasedString
    );
  });

  return casedFunctions;
}

var createCasedFunctions_1 = createCasedFunctions;

function prepareAssertions(expect) {
  var assertions = {};
  var assertionsWithNestingSuffix = {};

  Object.keys(expect.assertions).forEach(function (key) {
    var value = expect.assertions[key];

    if (key.endsWith(" assertion")) {
      assertionsWithNestingSuffix[key] = value;
    } else {
      assertions[key] = value;
    }
  });

  Object.keys(assertionsWithNestingSuffix).forEach(function (key) {
    var value = assertionsWithNestingSuffix[key];
    var assertionAlternation;
    if (
      value.length > 1 &&
      (assertionAlternation = value.find(function (v) { return v.declaration.endsWith("<assertion>"); }
      ))
    ) {
      var keywithoutSuffix = key.slice(0, -" assertion".length);
      if (assertions[keywithoutSuffix]) {
        assertions[keywithoutSuffix].push(assertionAlternation);
      } else {
        assertions[key] = value;
      }
    }
  });

  return assertions;
}

var prepareAssertions_1 = prepareAssertions;

var ASSERTIONS_TO_EXCLUDE = {
  called: true,
  "when called": true,
  "called with": true,
  "when called with": true,
  "decoded as": true,
  "when decoded as": true,
  "passed as parameter to": true,
  "when passed as parameter to": true,
  "passed as parameters to": true,
  "when passed as parameters to": true,
  "passed as parameter to async": true,
  "when passed as parameter to async": true,
  "passed as parameters to async": true,
  "passed as parameter to constructor": true,
  "when passed as parameter to constructor": true,
  "when passed as parameters to async": true,
  "passed as parameters to constructor": true,
  "when passed as parameters to constructor": true,
  sorted: true,
  "when sorted": true,
  "sorted by": true,
  "when sorted by": true,
  "sorted numerically": true,
  "when sorted numerically": true,
  "when fulfilled": true,
  "when rejected": true,
  // "to only have properties" - only and not are mutually exclusive
  "not to only have own properties": true,
  "not to only have properties": true,
  // "to have key"
  "to have key": true,
  "to only have key": true,
  "to not have key": true,
  "to not only have key": true,
  "not to have key": true,
  // "to have keys"
  "to have keys": true,
  "to only have keys": true,
  "to not have keys": true,
  "to not only have keys": true,
  "not to have keys": true,
  // others
  "to be ok": true,
  "not to be ok": true
};

var ASSERTIONS_TO_FORCE_NO_VALUE = {
  "to be falsy": true,
  "to be truthy": true,
  "not to be falsy": true,
  "not to be truthy": true
};

function upperCaseFirst(string) {
  return string[0].toUpperCase() + string.slice(1);
}

function determineTypesOfValues(expect, assertionString) {
  var originalAssertion = expect.assertions[assertionString];

  var typesOfValues = [];
  originalAssertion.forEach(function (definition) {
    var valueMatches = definition.declaration.match(
      /(?: <([a-zA-z-]+[+?]?(?:[|][a-zA-z-]+)*)>)* <([a-zA-z-]+[+?]?(?:[|][a-zA-z-]+)*)>$/
    );
    if (valueMatches) {
      var validMatches = valueMatches.slice(1).filter(Boolean);
      validMatches.forEach(function (valueMatch, index) {
        if (!valueMatch) { return; }
        var typeOfValue;
        if (typesOfValues.length <= index) {
          typeOfValue = new Set();
          typesOfValues.push(typeOfValue);
        } else {
          typeOfValue = typesOfValues[index];
        }
        var matchedTypes = valueMatch.split("|");
        // handle vararg types by treating them a single arg type
        matchedTypes = matchedTypes.map(function (type) { return type.endsWith("+") ? type.slice(0, -1) : type; }
        );
        matchedTypes.map(function (type) { return typeOfValue.add(type); });
      });
    }
  });
  return typesOfValues;
}

function identifyTypesOfValues(typesOfValues) {
  var maybeNested =
    typesOfValues.length > 0 &&
    (typesOfValues[typesOfValues.length - 1].has("assertion?") ||
      typesOfValues[typesOfValues.length - 1].has("assertion"));

  var lastTypesSet = maybeNested && typesOfValues[typesOfValues.length - 1];

  return {
    isMiddleRocket: maybeNested && lastTypesSet.size === 1,
    isNestingAllowed: maybeNested && lastTypesSet.size > 1
  };
}

function processUnexpectedInstance(expect, assertions) {
  var casedDefinitions = {};

  Object.keys(assertions).forEach(function (assertionString) {
    var assertionTokens = assertionString.split(" ");
    var assertionOpener = assertionTokens[0];

    if (assertionString in ASSERTIONS_TO_EXCLUDE) {
      return;
    }

    // skip any variants using "non-empty"
    if (assertionTokens.includes("non-empty")) {
      return;
    }

    var camelCasedString =
      assertionOpener +
      assertionTokens
        .slice(1)
        .map(upperCaseFirst)
        .join("");

    var typesOfValues =
      assertionString in ASSERTIONS_TO_FORCE_NO_VALUE
        ? [] // TODO: remove this workaround when "to be ok" string value is removed
        : determineTypesOfValues(expect, assertionString);

    if (
      casedDefinitions[camelCasedString] &&
      casedDefinitions[camelCasedString].isNestingAllowed
    ) {
      // avoid overwriting any assertion where nesting was enabled
      return;
    }

    var ref = identifyTypesOfValues(
      typesOfValues
    );
    var isMiddleRocket = ref.isMiddleRocket;
    var isNestingAllowed = ref.isNestingAllowed;

    // record all information derived for the assertion
    casedDefinitions[camelCasedString] = {
      assertionString: assertionString,
      isMiddleRocket: isMiddleRocket,
      isNestingAllowed: isNestingAllowed,
      typesOfValues: typesOfValues
    };
  });

  return casedDefinitions;
}

var processUnexpectedInstance_1 = processUnexpectedInstance;
var determineTypesOfValues_1 = determineTypesOfValues;
var identifyTypesOfValues_1 = identifyTypesOfValues;
processUnexpectedInstance_1.determineTypesOfValues = determineTypesOfValues_1;
processUnexpectedInstance_1.identifyTypesOfValues = identifyTypesOfValues_1;

var casedFunctions = function (expect) { return ({
  notToBeTruthy: function (subject) {
    return expect(subject, "not to be truthy");
  },
  toBeTruthy: function (subject) {
    return expect(subject, "to be truthy");
  },
  notToBe: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBe()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be" ].concat( args ));
  },
  toBe: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBe()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be" ].concat( args ));
  },
  notToBeTrue: function (subject) {
    return expect(subject, "not to be true");
  },
  toBeTrue: function (subject) {
    return expect(subject, "to be true");
  },
  notToBeFalse: function (subject) {
    return expect(subject, "not to be false");
  },
  toBeFalse: function (subject) {
    return expect(subject, "to be false");
  },
  notToBeFalsy: function (subject) {
    return expect(subject, "not to be falsy");
  },
  toBeFalsy: function (subject) {
    return expect(subject, "to be falsy");
  },
  notToBeNull: function (subject) {
    return expect(subject, "not to be null");
  },
  toBeNull: function (subject) {
    return expect(subject, "to be null");
  },
  notToBeUndefined: function (subject) {
    return expect(subject, "not to be undefined");
  },
  toBeUndefined: function (subject) {
    return expect(subject, "to be undefined");
  },
  notToBeDefined: function (subject) {
    return expect(subject, "not to be defined");
  },
  toBeDefined: function (subject) {
    return expect(subject, "to be defined");
  },
  notToBeNaN: function (subject) {
    return expect(subject, "not to be NaN");
  },
  toBeNaN: function (subject) {
    return expect(subject, "to be NaN");
  },
  notToBeCloseTo: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeCloseTo()"
      );
    }

    return expect(subject, "not to be close to", value, value2);
  },
  toBeCloseTo: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeCloseTo()"
      );
    }

    return expect(subject, "to be close to", value, value2);
  },
  notToBeA: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeA()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be a" ].concat( args ));
  },
  notToBeAn: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeAn()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be an" ].concat( args ));
  },
  toBeA: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeA()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be a" ].concat( args ));
  },
  toBeAn: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeAn()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be an" ].concat( args ));
  },
  notToBeOneOf: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeOneOf()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be one of" ].concat( args ));
  },
  toBeOneOf: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeOneOf()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be one of" ].concat( args ));
  },
  notToBeAnObject: function (subject) {
    return expect(subject, "not to be an object");
  },
  notToBeAnArray: function (subject) {
    return expect(subject, "not to be an array");
  },
  toBeAnObject: function (subject) {
    return expect(subject, "to be an object");
  },
  toBeAnArray: function (subject) {
    return expect(subject, "to be an array");
  },
  notToBeABoolean: function (subject) {
    return expect(subject, "not to be a boolean");
  },
  notToBeANumber: function (subject) {
    return expect(subject, "not to be a number");
  },
  notToBeAString: function (subject) {
    return expect(subject, "not to be a string");
  },
  notToBeAFunction: function (subject) {
    return expect(subject, "not to be a function");
  },
  notToBeARegexp: function (subject) {
    return expect(subject, "not to be a regexp");
  },
  notToBeARegex: function (subject) {
    return expect(subject, "not to be a regex");
  },
  notToBeARegularExpression: function (subject) {
    return expect(subject, "not to be a regular expression");
  },
  notToBeADate: function (subject) {
    return expect(subject, "not to be a date");
  },
  toBeABoolean: function (subject) {
    return expect(subject, "to be a boolean");
  },
  toBeANumber: function (subject) {
    return expect(subject, "to be a number");
  },
  toBeAString: function (subject) {
    return expect(subject, "to be a string");
  },
  toBeAFunction: function (subject) {
    return expect(subject, "to be a function");
  },
  toBeARegexp: function (subject) {
    return expect(subject, "to be a regexp");
  },
  toBeARegex: function (subject) {
    return expect(subject, "to be a regex");
  },
  toBeARegularExpression: function (subject) {
    return expect(subject, "to be a regular expression");
  },
  toBeADate: function (subject) {
    return expect(subject, "to be a date");
  },
  toBeTheEmptyString: function (subject) {
    return expect(subject, "to be the empty string");
  },
  toBeAnEmptyString: function (subject) {
    return expect(subject, "to be an empty string");
  },
  toBeTheEmptyArray: function (subject) {
    return expect(subject, "to be the empty array");
  },
  toBeAnEmptyArray: function (subject) {
    return expect(subject, "to be an empty array");
  },
  toMatch: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toMatch()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to match" ].concat( args ));
  },
  notToMatch: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToMatch()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to match" ].concat( args ));
  },
  notToHaveOwnProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveOwnProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have own property" ].concat( args ));
  },
  toHaveOwnProperty: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveOwnProperty()"
      );
    }

    return expect(subject, "to have own property", value, value2);
  },
  notToHaveEnumerableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveEnumerableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have enumerable property" ].concat( args ));
  },
  notToHaveConfigurableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveConfigurableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have configurable property" ].concat( args ));
  },
  notToHaveWritableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveWritableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have writable property" ].concat( args ));
  },
  toHaveEnumerableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveEnumerableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have enumerable property" ].concat( args ));
  },
  toHaveConfigurableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveConfigurableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have configurable property" ].concat( args ));
  },
  toHaveWritableProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveWritableProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have writable property" ].concat( args ));
  },
  notToHaveProperty: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveProperty()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have property" ].concat( args ));
  },
  toHaveProperty: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveProperty()"
      );
    }

    return expect(subject, "to have property", value, value2);
  },
  notToHaveOwnProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveOwnProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have own properties" ].concat( args ));
  },
  notToHaveProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have properties" ].concat( args ));
  },
  toOnlyHaveOwnProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toOnlyHaveOwnProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to only have own properties" ].concat( args ));
  },
  toOnlyHaveProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toOnlyHaveProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to only have properties" ].concat( args ));
  },
  toHaveOwnProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveOwnProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have own properties" ].concat( args ));
  },
  toHaveProperties: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveProperties()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have properties" ].concat( args ));
  },
  notToHaveLength: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToHaveLength()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to have length" ].concat( args ));
  },
  toHaveLength: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveLength()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have length" ].concat( args ));
  },
  notToBeEmpty: function (subject) {
    return expect(subject, "not to be empty");
  },
  toBeEmpty: function (subject) {
    return expect(subject, "to be empty");
  },
  notToContain: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToContain()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to contain" ].concat( args ));
  },
  toContain: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toContain()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to contain" ].concat( args ));
  },
  notToBeginWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeginWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to begin with" ].concat( args ));
  },
  toBeginWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeginWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to begin with" ].concat( args ));
  },
  notToStartWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToStartWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to start with" ].concat( args ));
  },
  toStartWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toStartWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to start with" ].concat( args ));
  },
  notToEndWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToEndWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to end with" ].concat( args ));
  },
  toEndWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toEndWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to end with" ].concat( args ));
  },
  notToBeFinite: function (subject) {
    return expect(subject, "not to be finite");
  },
  toBeFinite: function (subject) {
    return expect(subject, "to be finite");
  },
  notToBeInfinite: function (subject) {
    return expect(subject, "not to be infinite");
  },
  toBeInfinite: function (subject) {
    return expect(subject, "to be infinite");
  },
  notToBeWithin: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeWithin()"
      );
    }

    return expect(subject, "not to be within", value, value2);
  },
  toBeWithin: function (subject, value, value2) {
    if (
      (value && value.__itPlaceholder) ||
      (value2 && value2.__itPlaceholder)
    ) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeWithin()"
      );
    }

    return expect(subject, "to be within", value, value2);
  },
  notToBeLessThan: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeLessThan()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be less than" ].concat( args ));
  },
  notToBeBelow: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeBelow()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be below" ].concat( args ));
  },
  toBeLessThan: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeLessThan()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be less than" ].concat( args ));
  },
  toBeBelow: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeBelow()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be below" ].concat( args ));
  },
  notToBeLessThanOrEqualTo: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeLessThanOrEqualTo()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be less than or equal to" ].concat( args ));
  },
  toBeLessThanOrEqualTo: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeLessThanOrEqualTo()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be less than or equal to" ].concat( args ));
  },
  notToBeGreaterThan: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeGreaterThan()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be greater than" ].concat( args ));
  },
  notToBeAbove: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeAbove()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be above" ].concat( args ));
  },
  toBeGreaterThan: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeGreaterThan()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be greater than" ].concat( args ));
  },
  toBeAbove: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeAbove()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be above" ].concat( args ));
  },
  notToBeGreaterThanOrEqualTo: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToBeGreaterThanOrEqualTo()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to be greater than or equal to" ].concat( args ));
  },
  toBeGreaterThanOrEqualTo: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeGreaterThanOrEqualTo()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be greater than or equal to" ].concat( args ));
  },
  notToBePositive: function (subject) {
    return expect(subject, "not to be positive");
  },
  toBePositive: function (subject) {
    return expect(subject, "to be positive");
  },
  notToBeNegative: function (subject) {
    return expect(subject, "not to be negative");
  },
  toBeNegative: function (subject) {
    return expect(subject, "to be negative");
  },
  toEqual: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toEqual()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to equal" ].concat( args ));
  },
  notToEqual: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToEqual()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to equal" ].concat( args ));
  },
  toError: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toError()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to error" ].concat( args ));
  },
  toErrorWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toErrorWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to error with" ].concat( args ));
  },
  notToError: function (subject) {
    return expect(subject, "not to error");
  },
  notToThrow: function (subject) {
    return expect(subject, "not to throw");
  },
  toThrow: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toThrow()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to throw" ].concat( args ));
  },
  toThrowError: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toThrowError()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to throw error" ].concat( args ));
  },
  toThrowException: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toThrowException()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to throw exception" ].concat( args ));
  },
  toSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to satisfy", valueOrItPlaceholder);
  },
  toThrowA: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toThrowA()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to throw a" ].concat( args ));
  },
  toThrowAn: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toThrowAn()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to throw an" ].concat( args ));
  },
  toHaveArity: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveArity()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have arity" ].concat( args ));
  },
  toHaveValuesExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to have values exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveValuesSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to have values satisfying", valueOrItPlaceholder);
  },
  toBeAMapWhoseValuesExhaustivelySatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a map whose values exhaustively satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAMapWhoseValuesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a map whose values satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAHashWhoseValuesExhaustivelySatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a hash whose values exhaustively satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAHashWhoseValuesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a hash whose values satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAnObjectWhoseValuesExhaustivelySatisfy: function (
    subject,
    valueOrItPlaceholder
  ) {
    return expect(
      subject,
      "to be an object whose values exhaustively satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAnObjectWhoseValuesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be an object whose values satisfy",
      valueOrItPlaceholder
    );
  },
  toHaveItemsExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to have items exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveItemsSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to have items satisfying", valueOrItPlaceholder);
  },
  toBeAnArrayWhoseItemsExhaustivelySatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be an array whose items exhaustively satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAnArrayWhoseItemsSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be an array whose items satisfy",
      valueOrItPlaceholder
    );
  },
  toHaveKeysSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to have keys satisfying", valueOrItPlaceholder);
  },
  toBeAMapWhoseKeysSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a map whose keys satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAMapWhosePropertiesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a map whose properties satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAHashWhoseKeysSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a hash whose keys satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAHashWhosePropertiesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be a hash whose properties satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAnObjectWhoseKeysSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be an object whose keys satisfy",
      valueOrItPlaceholder
    );
  },
  toBeAnObjectWhosePropertiesSatisfy: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to be an object whose properties satisfy",
      valueOrItPlaceholder
    );
  },
  notToHaveAValueExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "not to have a value exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  notToHaveAValueSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "not to have a value satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveAValueExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to have a value exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveAValueSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to have a value satisfying", valueOrItPlaceholder);
  },
  notToHaveAnItemExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "not to have an item exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  notToHaveAnItemSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "not to have an item satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveAnItemExhaustivelySatisfying: function (subject, valueOrItPlaceholder) {
    return expect(
      subject,
      "to have an item exhaustively satisfying",
      valueOrItPlaceholder
    );
  },
  toHaveAnItemSatisfying: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to have an item satisfying", valueOrItPlaceholder);
  },
  toBeCanonical: function (subject) {
    return expect(subject, "to be canonical");
  },
  toHaveMessage: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toHaveMessage()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to have message" ].concat( args ));
  },
  toExhaustivelySatisfy: function (subject, valueOrItPlaceholder) {
    return expect(subject, "to exhaustively satisfy", valueOrItPlaceholder);
  },
  notToExhaustivelySatisfy: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToExhaustivelySatisfy()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to exhaustively satisfy" ].concat( args ));
  },
  notToSatisfy: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .notToSatisfy()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "not to satisfy" ].concat( args ));
  },
  toBeRejected: function (subject) {
    return expect(subject, "to be rejected");
  },
  toBeRejectedWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeRejectedWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be rejected with" ].concat( args ));
  },
  toBeRejectedWithErrorExhaustivelySatisfying: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeRejectedWithErrorExhaustivelySatisfying()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(
      void 0, [ subject,
      "to be rejected with error exhaustively satisfying" ].concat( args )
    );
  },
  toBeRejectedWithErrorSatisfying: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeRejectedWithErrorSatisfying()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be rejected with error satisfying" ].concat( args ));
  },
  toBeFulfilled: function (subject) {
    return expect(subject, "to be fulfilled");
  },
  toBeFulfilledWith: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeFulfilledWith()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be fulfilled with" ].concat( args ));
  },
  toBeFulfilledWithValueExhaustivelySatisfying: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeFulfilledWithValueExhaustivelySatisfying()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(
      void 0, [ subject,
      "to be fulfilled with value exhaustively satisfying" ].concat( args )
    );
  },
  toBeFulfilledWithValueSatisfying: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toBeFulfilledWithValueSatisfying()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to be fulfilled with value satisfying" ].concat( args ));
  },
  toCallTheCallback: function (subject) {
    return expect(subject, "to call the callback");
  },
  toCallTheCallbackWithoutError: function (subject) {
    return expect(subject, "to call the callback without error");
  },
  toCallTheCallbackWithError: function (subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    var value = rest.length === 1 ? rest[0] : undefined;
    if (value && value.__itPlaceholder) {
      throw new Error(
        "unassessed: nested assertions are not supported by .toCallTheCallbackWithError()"
      );
    }

    // TODO: type detection may need to be extended to record
    //       an empty argument type so we can restore being able
    //       to enforce the number of arguments where needed
    var args = rest.length === 1 ? [value] : [];

    return expect.apply(void 0, [ subject, "to call the callback with error" ].concat( args ));
  }
}); };

/* global weknowhow:false, afterEach: false */
var unexpected =
  typeof weknowhow !== "undefined" ? weknowhow.expect : require("unexpected");





function remainingInArray(arr1, arr2) {
  var a = [];
  var finalLength = arr2.length;
  for (var i = arr1.length; i < finalLength; i++) {
    a.push(arr2[i]);
  }
  return a;
}

var afterEachAttached = false;
var onAfterEach = null;

function ensureAfterEachIsRegistered() {
  if (typeof afterEach === "function" && !afterEachAttached) {
    afterEachAttached = true;
    afterEach(function() {
      var callable = onAfterEach;
      onAfterEach = null;
      if (callable) { callable(); }
    });
  }
}

var ItPlaceholder = function ItPlaceholder(name, assertion, args) {
  this.name = name;
  this.assertion = assertion;
  this.args = args;
};

ItPlaceholder.prototype.__itPlaceholder = true;

function attachBoundFunctions(ctx, casedDefinitions, casedFuntions, subject) {
  Object.keys(casedFuntions).forEach(function (fnName) {
    var definition = casedDefinitions[fnName];

    if (definition.isMiddleRocket) {
      return;
    }

    ctx[fnName] = function () {
      var vals = [], len = arguments.length;
      while ( len-- ) vals[ len ] = arguments[ len ];

      return casedFuntions[fnName].apply(casedFuntions, [ subject ].concat( vals ));
    };
  });
}

function attachItFunctions(ctx, casedDefinitions, casedFuntions, decrementFn) {
  Object.keys(casedFuntions).forEach(function (fnName) {
    var ref = casedDefinitions[fnName];
    var assertionString = ref.assertionString;
    var isMiddleRocket = ref.isMiddleRocket;
    var isNestingAllowed = ref.isNestingAllowed;

    if (isMiddleRocket) {
      return;
    }

    if (isNestingAllowed) {
      // this assertion has a non-terminating form that takes
      // a value of type <assertion>. Given that .it. functions
      // must terminate an assertion call we will disallow this.
      ctx[fnName] = function () {
        var vals = [], len = arguments.length;
        while ( len-- ) vals[ len ] = arguments[ len ];

        if (vals.length > 0 && vals[0].__itPlaceholder) {
          throw new Error(
            "unassessed: nested assertions are not supported with .it. functions."
          );
        }
        decrementFn();
        return new ItPlaceholder(fnName, assertionString, vals);
      };
      return;
    }

    ctx[fnName] = function () {
      var vals = [], len = arguments.length;
      while ( len-- ) vals[ len ] = arguments[ len ];

      decrementFn();
      return new ItPlaceholder(fnName, assertionString, vals);
    };
  });
}

function unwrapItPlaceholder(expect, itPlaceholder) {
  var itAssertion = itPlaceholder.assertion;
  var itArgs = itPlaceholder.args;
  var value; // eslint-disable-next-line prefer-const
  value = expect.it(function (thing) { return expect.apply(void 0, [ thing, itAssertion ].concat( itArgs )); });
  value.__itReference = itPlaceholder;
  return value;
}

function _createAssessed(expect, makeCasedFunctions) {
  var executingAssertionCount = 0;

  expect.hook(function (next) {
    return function expectWatcher(context, args) {
      var rest = args.slice(2);
      if (rest.length === 1 && rest[0] instanceof ItPlaceholder) {
        // replace current value argument with the unwapped ItPlaceholder
        args.splice(2, 1, unwrapItPlaceholder(expect, rest[0]));
      }

      executingAssertionCount -= 1;

      var returnValue;
      try {
        returnValue = next(context, args);
      } catch (error) {
        executingAssertionCount = 0;
        throw error;
      }
      if (returnValue.isPending()) {
        returnValue.finally(function () { return (executingAssertionCount = 0); });
      }
      return returnValue;
    };
  });

  expect.addType({
    name: "itFunction",
    base: "expect.it",
    identify: function identify(f) {
      return (
        this.baseType.identify(f) && f.__itReference instanceof ItPlaceholder
      );
    },
    inspect: function inspect(value, _, output, inspect$1) {
      var ref = value.__itReference;
      var assertion = ref.assertion;
      var args = ref.args;

      var argsOutput = output.clone();
      args.forEach(function (arg) {
        argsOutput.sp().append(inspect$1(arg));
      });

      output.error(assertion).append(argsOutput);
    }
  });

  expect.addType({
    name: "ItPlaceholder",
    base: "wrapperObject",
    identify: function identify(v) {
      return v instanceof ItPlaceholder;
    },
    inspect: function inspect(value, depth, output, inspect$1) {
      output.append(this.prefix(output.clone(), value));
      if (value.args.length > 0) {
        value.args.forEach(function (arg, index) {
          if (index > 0) {
            output.text(", ");
          }
          output.appendInspected.apply(output, value.args);
        });
      }
      output.append(this.suffix(output.clone(), value));
      return output;
    },
    unwrap: function unwrap(value) {
      return unwrapItPlaceholder(expect, value);
    },
    prefix: function prefix(output, value) {
      var name = value.name;
      return output.text(("assess.it." + name + "("));
    },
    suffix: function suffix(output) {
      return output.text(")");
    }
  });

  expect.addAssertion(
    "<any> to [exhaustively] satisfy <ItPlaceholder>",
    function (expect, subject, value) {
      var valueType = expect.argTypes[0];

      return expect(
        subject,
        "to [exhaustively] satisfy",
        valueType.unwrap(value)
      );
    }
  );

  makeCasedFunctions = makeCasedFunctions || createCasedFunctions_1;
  var assertions = prepareAssertions_1(expect);
  var casedDefinitions = processUnexpectedInstance_1(expect, assertions);
  var casedFunctions = makeCasedFunctions(expect, casedDefinitions);

  function unassessed(subject) {
    var rest = [], len = arguments.length - 1;
    while ( len-- > 0 ) rest[ len ] = arguments[ len + 1 ];

    if (rest.length > 0) {
      throw new Error("unassessed: at most one subject argument accepted");
    }

    executingAssertionCount += 1;

    if (!onAfterEach) {
      onAfterEach = function() {
        var currentAssertionCount = executingAssertionCount;
        executingAssertionCount = 0;
        if (currentAssertionCount > 0) {
          throw new Error("unassessed: dangling assertion created");
        }
      };
    }

    var assess = {};

    attachBoundFunctions(assess, casedDefinitions, casedFunctions, subject);

    return assess;
  }

  function assessIt() {
    executingAssertionCount = 0;

    throw new Error(
      "unassessed: asssess.it was called directly. Please use its methods instead."
    );
  }

  attachItFunctions(assessIt, casedDefinitions, casedFunctions, function () {
    executingAssertionCount -= 1;
  });

  unassessed.it = assessIt;

  unassessed.setOutputWidth = function (width) {
    // eslint-disable-next-line no-self-compare
    if (!(typeof width === "number" && width === width && width > 0)) {
      throw new Error("unassessed: invalid output width");
    }

    expect.output.preferredWidth = width;
  };

  unassessed.withPlugins = function () {
    var plugins = [], len = arguments.length;
    while ( len-- ) plugins[ len ] = arguments[ len ];

    var expectWithPlugins = unexpected.clone();
    plugins.forEach(function (plugin) {
      expectWithPlugins.use(plugin);
    });

    // determine if a plugin exposed any properties at the top-level
    var baseExpectKeys = Object.getOwnPropertyNames(unexpected);
    var pluginExpectKeys = Object.getOwnPropertyNames(expectWithPlugins);
    var extraKeys = remainingInArray(baseExpectKeys, pluginExpectKeys);

    var assessWithPlugins = _createAssessed(expectWithPlugins);
    extraKeys.forEach(function (key) { return (assessWithPlugins[key] = expectWithPlugins[key]); });
    return assessWithPlugins;
  };

  unassessed.withUnexpectedPlugins = function () {
    var plugins = [], len = arguments.length;
    while ( len-- ) plugins[ len ] = arguments[ len ];

    return unassessed.withPlugins.apply(unassessed, plugins);
  };

  ensureAfterEachIsRegistered();

  return unassessed;
}

function createAssessed(expect) {
  return _createAssessed(expect.clone(), casedFunctions);
}

var unassessed = createAssessed(unexpected);

export default unassessed;
//# sourceMappingURL=unassessed.esm.js.map