Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/wet-icons-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@getodk/xpath': patch
---

Fixed decimal-date-time function to accept a node as a parameter
21 changes: 9 additions & 12 deletions packages/xpath/src/functions/xforms/datetime.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { DAY_MILLISECONDS } from '@getodk/common/constants/datetime.ts';
import { Temporal } from 'temporal-polyfill';
import type { XPathNode } from '../../adapter/interface/XPathNode.ts';
import { EvaluationContext } from '../../context/EvaluationContext.ts';
Expand All @@ -8,7 +9,6 @@ import { FunctionImplementation } from '../../evaluator/functions/FunctionImplem
import { NumberFunction } from '../../evaluator/functions/NumberFunction.ts';
import { StringFunction } from '../../evaluator/functions/StringFunction.ts';
import { dateTimeFromNumber, dateTimeFromString } from '../../lib/datetime/coercion.ts';
import { DAY_MILLISECONDS } from '@getodk/common/constants/datetime.ts';
import { now } from '../../lib/datetime/functions.ts';
import { isValidTimeString } from '../../lib/datetime/predicates.ts';

Expand Down Expand Up @@ -228,20 +228,19 @@ const evaluateDateTime = <T extends XPathNode>(
}

const milliseconds = days * DAY_MILLISECONDS;

return dateTimeFromNumber(timeZone, milliseconds);
}

case 'STRING': {
const stringValue = evaluation.toString();

return dateTimeFromString(timeZone, stringValue);
}

default:
case 'BOOLEAN': {
throw new Error(
'Expected a NUMBER or STRING evaluation type for date-time conversion, but received an invalid type.'
);
}

default: {
const stringValue = evaluation.toString();
return dateTimeFromString(timeZone, stringValue);
}
}
};

Expand All @@ -263,6 +262,7 @@ export const date = new FunctionImplementation(
case 'BOOLEAN':
return new StringEvaluation(context, '');

case 'NODE':
case 'STRING': {
const string = results.toString();

Expand Down Expand Up @@ -290,9 +290,6 @@ export const date = new FunctionImplementation(

case 'NUMBER':
break;

default:
throw new Error('Invalid input type for date function: expected STRING or NUMBER.');
}

const dateTime = evaluateDateTime(context, results);
Expand Down
30 changes: 27 additions & 3 deletions packages/xpath/test/xforms/date.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ describe('#date()', () => {
{ expression: 'date(1.5)', expected: '1970-01-02T05:00:00.000-07:00' },
{ expression: 'date(-1)', expected: '1969-12-30T17:00:00.000-07:00' },
].forEach(({ expression, expected }) => {
it(expression + ' should be converted to ' + expected, () => {
it(`${expression} should be converted to ${expected}`, () => {
testContext.assertStringValue(expression, expected);
});
});
Expand Down Expand Up @@ -166,7 +166,7 @@ describe('#date()', () => {
{ expression: 'date("2100-01-02") > 1', expected: true },
{ expression: 'date("1970-01-02") < 3', expected: true },
].forEach(({ expression, expected }) => {
it("should evaluate '" + expression + "' to: " + expected, () => {
it(`should evaluate '${expression}' to '${expected}'`, () => {
testContext.assertBooleanValue(expression, expected);
});
});
Expand All @@ -181,7 +181,7 @@ describe('#date()', () => {
{ expression: '3 + date("2001-12-26") + 5', expected: '11690.291666666666' },
{ expression: '3 + date("2001-12-26") - 5', expected: '11680.291666666666' },
].forEach(({ expression, expected }) => {
it("should evaluate '" + expression + "' to: " + expected, () => {
it(`should evaluate '${expression}' to '${expected}'`, () => {
testContext.assertStringValue(expression, expected);
});
});
Expand Down Expand Up @@ -210,6 +210,30 @@ describe('#date()', () => {
});
});

describe('with node reference', () => {
beforeEach(() => {
testContext = createXFormsTestContext(`
<div id="TestCase">
<div id="DateField">1970-01-01</div>
<div id="DateTimeField">1970-01-02T03:00:00</div>
</div>`);
});

it('date field', () => {
const contextNode = testContext.document.getElementById('DateField');
testContext.assertNumberRounded('date(.)', 0.291667, 1000000, {
contextNode,
});
});

it('datetime field', () => {
const contextNode = testContext.document.getElementById('DateTimeField');
testContext.assertNumberRounded('date(.)', 1.416667, 1000000, {
contextNode,
});
});
});

describe('for nodes (where the date datatype is guessed)', () => {
beforeEach(() => {
testContext = createXFormsTestContext(
Expand Down
25 changes: 24 additions & 1 deletion packages/xpath/test/xforms/decimal-date-time.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,33 @@ describe('#decimal-date-time()', () => {
});

it('different format', () => {
// testContext.assertNumberRounded('decimal-date-time("2018-04-24T15:30:00.000+06:00")', 17645.396, 1000);
testContext.assertNumberValue(
'decimal-date-time("2018-04-24T15:30:00.000+06:00")',
17645.395833333332
);
});

describe('with node reference', () => {
beforeEach(() => {
testContext = createXFormsTestContext(`
<div id="TestCase">
<div id="DateField">1970-01-01</div>
<div id="DateTimeField">1970-01-02T03:00:00</div>
</div>`);
});

it('date field', () => {
const contextNode = testContext.document.getElementById('DateField');
testContext.assertNumberRounded('decimal-date-time(.)', 0.291667, 1000000, {
contextNode,
});
});

it('datetime field', () => {
const contextNode = testContext.document.getElementById('DateTimeField');
testContext.assertNumberRounded('decimal-date-time(.)', 1.416667, 1000000, {
contextNode,
});
});
});
});
Loading