SpecFormula AI
ISABackendSymbol System

CAS-System

Declarative constraint assertions

CAS-System (Constraint Assertion System) lets you express validation logic with declarative syntax, replacing traditional imperative assertion code.

Basic Syntax

&constraintName                    # No parameter
&constraintName(parameter)         # Single parameter
&constraintName(param1, param2)    # Multiple parameters
&constraint1 &constraint2          # Multiple constraints (AND)

Usage Positions

DataTable Format

Then response, with table:
  | id     | name             | age             |
  | &isNum | &contains("Wang") | &between(18,65) |

DocString JSON Format

Then response, with JSON:
  """json
  {
    "id": &isNum &gt(0),
    "name": &isStr &contains(Wang)
  }
  """

Note: Symbol system expressions must NOT be placed inside JSON string quotes "", otherwise they are treated as plain strings.

Constraint List

Type Checks

ConstraintMeaning
&isNumIs numeric
&isStrIs string
&isBoolIs boolean
&isNullIs null
&isNotNullIs not null

Numeric Comparisons

ConstraintMeaningExample
&eq(value)Equals&eq(100)
&ne(value)Not equals&ne(0)
&gt(value)Greater than&gt(0)
&lt(value)Less than&lt(100)
&ge(value)Greater than or equal&ge(18)
&le(value)Less than or equal&le(65)

String Operations

ConstraintExample
&contains(substring)&contains("Wang")
&startsWith(prefix)&startsWith("Mr.")
&endsWith(suffix)&endsWith(".com")
&matches(regex)&matches("\\d{4}-\\d{2}-\\d{2}")
&length(min,max)&length(2,10)

Array Operations

ConstraintExample
&hasItem(item)&hasItem("admin")
&hasNoItem(item)&hasNoItem("guest")
&size(count)&size(5)
&isEmpty&isEmpty
&isNotEmpty&isNotEmpty

Existence Checks

ConstraintExample
&hasField(fieldName)&hasField("createdAt")
&noField(fieldName)&noField("password")

Range Checks

ConstraintExample
&between(min,max)&between(18,65)
&notBetween(min,max)&notBetween(0,17)
&oneOf(val1,val2,...)&oneOf("admin","user")
&noneOf(val1,val2,...)&noneOf("banned")
ConstraintExample
&sameTime(datetime)&sameTime("2025-11-04T08:00:00")
&before(datetime)&before("2025-12-31")
&after(datetime)&after("2025-01-01")
&sameDay(date)&sameDay("2025-11-04")
&timeRange(start,end)&timeRange("09:00","17:00")
&withinDays(days)&withinDays(7)

Time constraint parameters support the now keyword and relative time syntax, which resolve to the MockTime set by TimeControl.

Supported relative time units:

UnitSymbolExample
Secondss (lowercase)now-30s
Minutesm (lowercase)now+5m
Hoursh (lowercase)now-2h
Daysd (lowercase)now+7d
MonthsM (uppercase)now-1M
| createdAt      | expiresAt      | updatedAt        |
| &sameTime("now") | &after("now+7d") | &before("now-30m") |

Multiple Constraint Combination

Multiple constraints separated by spaces form an AND relationship:

| field | &isNum &gt(0) &lt(100) &ne(50) |
# Must simultaneously: be numeric, greater than 0, less than 100, not equal to 50

With Variables

CAS parameters can reference variables:

| &eq($expectedValue)    |  # Use variable as comparison value
| &gt($minThreshold)     |  # Dynamic lower bound
| &between($min, $max)   |  # Dynamic range

Usage Restrictions

CAS cannot be mixed with >contextKey in the same column:

# ❌ Wrong: same column has both extraction (>) and validation (&)
| >recordId |
| &isNum    |

# ✅ Correct: use separately
When punch, call table:
  | >recordId |
  | <id       |

Then response, with table:
  | recordId              |
  | &eq($recordId) &isNum |

Complete Example

Feature: Order Validation

  Example: Validate order response
    When (UID="$Alice.id") create order, call table:
      | >order1.id | productId | quantity |
      | <orderId   | 123       | 2        |
    Then create order(201) response, with table:
      | orderId       | status                     | amount     | createdAt                        |
      | &isNum &gt(0) | &oneOf("pending","active") | &ge(1000)  | &sameTime("2026-01-27T10:00:00") |

On this page