For the complete documentation index, see llms.txt. This page is also available as Markdown.

Data Navigator Expectations

Assert against deeply nested data structures by path

Asserting against a deeply nested structure usually means a chain of intermediate variables and structKeyExists() guards before you reach the value you actually care about. The data navigator matchers collapse that into a single path expression, built on BoxLang's dataNavigate() built-in.

Paths are JSONPath-style expressions, supporting dot notation, array indexing, recursive descent, wildcards, slices and filters. The full syntax is listed under Path Syntax below.

These matchers require BoxLang. On CFML engines they throw TestBox.BoxLangFeatureNotAvailable.

The examples below all assume this structure:

var data = {
    "app"   : { "name" : "TestApp", "settings" : { "debug" : true, "port" : 8080 } },
    "users" : [ { "name" : "Alice", "age" : 30 } ]
}

Path Syntax

Every matcher on this page takes the same path expression, handed straight to BoxLang's dataNavigate().

Syntax
Example
Matches

Dot notation

app.settings.port

The value at that key path

Array index

users[1]

The first user — indexing is 1-based

Recursive descent

..name

Every name key at any depth

Wildcard, keys

app.settings.*

Every value under settings

Wildcard, array

users[*].name

The name of every user

Slice

primes[1:3]

Elements 1 through 3, inclusive

Open-ended slice

primes[2:]

Element 2 through the end

Filter

users[?(@.age > 18)].name

The name of every user over 18

Array indexing is 1-based, following the language convention rather than JSONPath's usual 0-based indexing. users[1] is the first element, not the second.

Filters use @ to refer to the current element and support ==, !=, >, <, >= and <=. Whitespace inside the filter is tolerated, so [?(@.active==true)] and [?( @.active == true )] are equivalent.

Existence

toHavePath()

Asserts a path resolves.

The browser matchers also define toHavePath(), for the URL path of a bx-playwright page. When they are registered, as in every browser bundle, pages get the browser check and every other value still gets this Data Navigator matcher.

Values

toHavePathValue()

Asserts the value at a path equals an expected value.

toHavePathType()

Asserts the type at a path. Accepts standard types (string, numeric, boolean, struct, array) and the aliases str, num, bool, arr, obj and map.

toHavePathSatisfying()

Asserts the value at a path satisfies a predicate closure, for anything equality cannot express.

Chaining

path()

Navigates to a path and hands back a normal Expectation on the value there, so you can chain any matcher you like rather than being limited to the path matchers above.

queryPath()

Navigates to a path and hands back an Expectation on an array of every match. This is the one to use with wildcards, slices, filters and recursive descent, where a path resolves to many values rather than one.

Slices take an inclusive, 1-based window into an array:

A Real Example

Validating an API response is where this earns its keep:

Last updated

Was this helpful?