CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-should

Expressive, readable, framework-agnostic BDD-style assertion library for JavaScript testing.

Pending
Overview
Eval results
Files

property-assertions.mddocs/

Object and Property Assertions

Methods for testing object properties, structure, ownership, and collection characteristics.

Property Existence and Values

property()

Test that an object has a property, optionally with a specific value. Changes assertion target to the property value.

/**
 * Assert that object has the specified property, optionally with a value
 * Changes the assertion target to the property value for chaining
 * @param name - Property name to check
 * @param value - Optional expected property value
 * @returns This assertion for chaining (now targeting the property value)
 */
property(name: string, value?: any): Assertion;

Usage:

import should from 'should';

const user = { name: 'john', age: 30, active: true };

// Test property existence
user.should.have.property('name');
user.should.have.property('age');

// Test property with specific value
user.should.have.property('name', 'john');
user.should.have.property('age', 30);

// Chain assertions on the property value
user.should.have.property('name').which.is.a.String();
user.should.have.property('age').which.is.above(18);

// Nested objects
const config = { database: { host: 'localhost', port: 5432 } };
config.should.have.property('database').which.is.an.Object();
config.database.should.have.property('host', 'localhost');

properties()

Test that an object has multiple properties.

/**
 * Assert that object has all specified properties
 * @param names - Property names as individual arguments or array
 * @returns This assertion for chaining
 */
properties(...names: string[]): Assertion;
properties(names: string[]): Assertion;
properties(props: object): Assertion;

Usage:

const user = { name: 'john', age: 30, email: 'john@test.com' };

// Multiple properties as arguments  
user.should.have.properties('name', 'age', 'email');

// Properties as array
user.should.have.properties(['name', 'age']);

// Properties with values (as object)
user.should.have.properties({
  name: 'john',
  age: 30
});

// Partial property checking
const response = { status: 200, data: {}, headers: {} };
response.should.have.properties('status', 'data');

ownProperty() / hasOwnProperty()

Test that an object has its own property (not inherited).

/**
 * Assert that object has the property as its own (not inherited)
 * @param name - Property name to check
 * @param description - Optional error message
 * @returns This assertion for chaining
 */
ownProperty(name: string, description?: string): Assertion;
hasOwnProperty(name: string, description?: string): Assertion;

Usage:

const obj = { name: 'test' };

obj.should.have.ownProperty('name');
obj.should.have.hasOwnProperty('name');

// Won't match inherited properties
obj.should.not.have.ownProperty('toString'); // toString is inherited
obj.should.not.have.ownProperty('constructor');

// With description
const config = { timeout: 5000 };
config.should.have.ownProperty('timeout', 'Config should have timeout setting');

propertyWithDescriptor()

Test that an object has a property with specific descriptor attributes.

/**
 * Assert that object has property with matching descriptor attributes
 * @param name - Property name to check
 * @param descriptor - Expected descriptor properties (enumerable, configurable, etc.)
 * @returns This assertion for chaining
 */
propertyWithDescriptor(name: string, descriptor: object): Assertion;

Usage:

const obj = {};
Object.defineProperty(obj, 'hidden', {
  value: 'secret',
  enumerable: false,
  configurable: true
});

obj.should.have.propertyWithDescriptor('hidden', {
  enumerable: false,
  configurable: true
});

// Partial descriptor matching
obj.should.have.propertyWithDescriptor('hidden', {
  enumerable: false
});

Collection Properties

length() / lengthOf()

Test the length property of arrays, strings, or array-like objects.

/**
 * Assert that object has a length property with the specified value
 * @param value - Expected length value
 * @param description - Optional error message
 * @returns This assertion for chaining
 */
length(value: number, description?: string): Assertion;
lengthOf(value: number, description?: string): Assertion;

Usage:

[1, 2, 3].should.have.length(3);
'hello'.should.have.length(5);
''.should.have.length(0);

// Array-like objects
const arrayLike = { 0: 'a', 1: 'b', length: 2 };
arrayLike.should.have.length(2);

// With description
const items = ['a', 'b', 'c'];
items.should.have.lengthOf(3, 'Should have 3 items');

// Chaining with other assertions
const users = [{ name: 'john' }, { name: 'jane' }];
users.should.have.length(2).and.be.an.Array();

empty()

Test that a collection or string is empty.

/**
 * Assert that the value is empty (array, string, object with no own properties)
 * @returns This assertion for chaining
 */
empty(): Assertion;

Usage:

[].should.be.empty();
''.should.be.empty();
{}.should.be.empty();

// Maps and Sets
new Map().should.be.empty();
new Set().should.be.empty();

// Non-empty examples
[1, 2, 3].should.not.be.empty();
'hello'.should.not.be.empty();
{ name: 'john' }.should.not.be.empty();

size()

Test the size property of Maps, Sets, and other collections.

/**
 * Assert that object has a size property with the specified value
 * @param value - Expected size value
 * @returns This assertion for chaining
 */
size(value: number): Assertion;

Usage:

const map = new Map([['a', 1], ['b', 2]]);
map.should.have.size(2);

const set = new Set([1, 2, 3, 3]); // Duplicates ignored
set.should.have.size(3);

// Custom objects with size property
const collection = { 
  items: ['a', 'b', 'c'],
  get size() { return this.items.length; }
};
collection.should.have.size(3);

Object Keys and Values

keys() / key()

Test object keys.

/**
 * Assert that object has the specified keys
 * @param keys - Expected keys as individual arguments or array
 * @returns This assertion for chaining
 */
keys(...keys: any[]): Assertion;
key(key: any): Assertion;

Usage:

const obj = { name: 'john', age: 30, active: true };

// All keys (order doesn't matter)
obj.should.have.keys('name', 'age', 'active');
obj.should.have.keys(['name', 'age', 'active']);

// Single key
obj.should.have.key('name');

// Subset of keys (using .any modifier)
obj.should.have.any.keys('name', 'email'); // Has 'name', missing 'email' is ok

// Exact key matching
obj.should.have.only.keys('name', 'age', 'active');

// Array key testing
const arr = ['a', 'b', 'c'];
arr.should.have.keys('0', '1', '2', 'length');

value()

Test that an object has a key with a specific value.

/**
 * Assert that object has the specified key with the given value
 * @param key - Property key to check
 * @param value - Expected value for the key
 * @returns This assertion for chaining
 */
value(key: any, value: any): Assertion;

Usage:

const obj = { name: 'john', age: 30 };

obj.should.have.value('name', 'john');
obj.should.have.value('age', 30);

// Works with arrays
const arr = ['a', 'b', 'c'];
arr.should.have.value(0, 'a');
arr.should.have.value(2, 'c');

// Maps
const map = new Map([['key1', 'value1'], ['key2', 'value2']]);
map.should.have.value('key1', 'value1');

propertyByPath()

Test nested property access using a path.

/**
 * Assert that object has a property accessible by the given path
 * @param path - Property path as individual arguments or array
 * @returns This assertion for chaining (targeting the nested value)
 */
propertyByPath(...path: string[]): Assertion;
propertyByPath(path: string[]): Assertion;

Usage:

const obj = {
  user: {
    profile: {
      name: 'john',
      settings: {
        theme: 'dark'
      }
    }
  }
};

// Path as arguments
obj.should.have.propertyByPath('user', 'profile', 'name');

// Path as array
obj.should.have.propertyByPath(['user', 'profile', 'settings', 'theme']);

// Chain assertions on nested value
obj.should.have.propertyByPath('user', 'profile', 'name').which.equals('john');

// Array indices in path
const data = {
  items: [
    { id: 1, name: 'first' },
    { id: 2, name: 'second' }
  ]
};
data.should.have.propertyByPath('items', 0, 'name').which.equals('first');

Complex Object Testing

Chaining Property Assertions

Property assertions can be chained for complex object validation:

const user = {
  id: 123,
  profile: {
    name: 'john',
    email: 'john@test.com',
    preferences: {
      theme: 'dark',
      notifications: true
    }
  },
  roles: ['user', 'admin']
};

// Complex chaining
user.should.have.property('id').which.is.a.Number().and.be.above(0);
user.should.have.property('profile').which.is.an.Object()
  .and.have.properties('name', 'email');
user.should.have.property('roles').which.is.an.Array()
  .and.have.length(2)
  .and.containEql('admin');

// Nested property testing
user.profile.should.have.property('preferences').which.is.an.Object();
user.profile.preferences.should.have.property('theme', 'dark');

Negation

All property assertions support negation:

const obj = { name: 'john' };

obj.should.not.have.property('age');
obj.should.not.have.properties('email', 'phone');
obj.should.not.have.ownProperty('toString'); // inherited property
obj.should.not.be.empty();
obj.should.not.have.keys('age', 'email');

Install with Tessl CLI

npx tessl i tessl/npm-should

docs

basic-assertions.md

configuration.md

containment-assertions.md

error-assertions.md

index.md

number-assertions.md

pattern-matching.md

promise-assertions.md

property-assertions.md

string-assertions.md

type-assertions.md

tile.json