Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions src/jsonata.js
Original file line number Diff line number Diff line change
Expand Up @@ -2137,12 +2137,11 @@ var jsonata = (function() {
}
var environment = createFrame(staticFrame);

var timestamp = new Date(); // will be overridden on each call to evalute()
environment.bind('now', defineFunction(function(picture, timezone) {
return datetime.fromMillis(timestamp.getTime(), picture, timezone);
return datetime.fromMillis(this.environment.timestamp.getTime(), picture, timezone);
}, '<s?s?:s>'));
environment.bind('millis', defineFunction(function() {
return timestamp.getTime();
return this.environment.timestamp.getTime();
}, '<:n>'));

return {
Expand All @@ -2169,8 +2168,7 @@ var jsonata = (function() {

// capture the timestamp and put it in the execution environment
// the $now() and $millis() functions will return this value - whenever it is called
timestamp = new Date();
exec_env.timestamp = timestamp;
exec_env.timestamp = new Date();
exec_env.options = options;

exec_env.createSequence = function() {
Expand Down
31 changes: 31 additions & 0 deletions test/implementation-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,37 @@ describe("Functions with side-effects", () => {
});
});

describe("$millis() and $now() are not affected by an overlapping evaluate() call", function() {
it("should return the same value within each evaluation", async function() {
var expr = jsonata("($m := $millis(); $n := $now(); $pause($m); [$m = $millis(), $n = $now()])");
var paused, release;
var reached = new Promise((resolve) => { paused = resolve; });
var resume = new Promise((resolve) => { release = resolve; });
// the first evaluation suspends part way through, until released
var first = expr.evaluate(testdata2, {
pause: function(millis) {
paused(millis);
return resume;
}
});
var firstMillis = await reached;
// make sure the overlapping evaluation captures a later timestamp
while (Date.now() <= firstMillis) {
await new Promise((resolve) => setTimeout(resolve, 1));
}
var secondMillis;
var second = await expr.evaluate(testdata2, {
pause: function(millis) {
secondMillis = millis;
}
});
release();
expect(secondMillis).to.be.above(firstMillis);
expect(second).to.deep.equal([true, true]);
expect(await first).to.deep.equal([true, true]);
});
});

describe("$millis() returns milliseconds since the epoch", function() {
it("should return result object", function() {
var expr = jsonata("$millis()");
Expand Down
Loading