Skip to content

feat: add MockNow option for deterministic now() in tests - #986

Open
ChrisJr404 wants to merge 1 commit into
expr-lang:masterfrom
ChrisJr404:feat/mock-now-patcher
Open

feat: add MockNow option for deterministic now() in tests#986
ChrisJr404 wants to merge 1 commit into
expr-lang:masterfrom
ChrisJr404:feat/mock-now-patcher

Conversation

@ChrisJr404

Copy link
Copy Markdown

Fixes #754.

now() makes expressions hard to test because it returns a different value on every run. As suggested in the issue, this adds a small patcher (following the WithTimezone pattern) plus a public option so now() can be pinned to a fixed time.

Usage

program, err := expr.Compile(`now().Sub(StartTime) >= 40*duration("24h")`,
    expr.Env(env),
    expr.MockNow(time.Date(2024, 5, 7, 23, 0, 0, 0, time.UTC)),
)

The compiled program now always sees that fixed time for now(), so tests are deterministic. No boilerplate patcher and no need to DisableBuiltin("now") + re-register a function.

What's included

  • patcher.WithNow — replaces now() builtin calls with a constant time node while patching the AST.
  • expr.MockNow(t time.Time) — the public option wiring the patcher, mirroring expr.Timezone.
  • It composes with Timezone: if a location was injected into now(), the fixed time is returned in that location.
  • Docs section under docs/configuration.md.

Notes

  • Purely additive; no existing builtins or tests changed, default behavior unchanged.
  • Tests cover the basic case, a deterministic derived value (now().Year()), and the Timezone + MockNow combination.
  • go build, go vet, and go test ./ ./patcher/ ./builtin/ ./checker/ pass. (test/examples fails to build on a clean master too — unrelated to this change.)

Add a WithNow patcher that replaces now() calls with a fixed time, exposed
via the expr.MockNow option. This makes it easy to test expressions that
depend on now() by getting deterministic results, without having to write a
custom patcher or disable the builtin. It composes with Timezone.

Closes expr-lang#754
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow mockable/predictable now()

1 participant