openrosa-xpath-evaluator
Advanced tools
Comparing version 2.0.6 to 2.0.7
@@ -6,2 +6,8 @@ Change Log | ||
[2.0.7] - 2021-07-13 | ||
--------------------- | ||
##### Fixed | ||
- Inconsistencies with date-as-string result formats. | ||
- Result of if() is no longer cast to a string (recently updated ODK XForms spec). | ||
[2.0.6] - 2021-04-20 | ||
@@ -8,0 +14,0 @@ --------------------- |
{ | ||
"name": "openrosa-xpath-evaluator", | ||
"version": "2.0.6", | ||
"version": "2.0.7", | ||
"description": "Wrapper for browsers' XPath evaluator with added support for OpenRosa extensions.", | ||
@@ -30,13 +30,13 @@ "homepage": "https://enketo.org", | ||
"chai": "^4.3.4", | ||
"eslint": "^7.22.0", | ||
"karma": "^6.2.0", | ||
"eslint": "^7.30.0", | ||
"karma": "^6.3.4", | ||
"karma-chrome-launcher": "^3.1.0", | ||
"karma-firefox-launcher": "^2.1.0", | ||
"karma-firefox-launcher": "^2.1.1", | ||
"karma-mocha": "^2.0.1", | ||
"karma-webpack": "^5.0.0", | ||
"lodash": "^4.17.21", | ||
"mocha": "^8.3.2", | ||
"mocha": "^8.4.0", | ||
"node-forge": "^0.10.0", | ||
"puppeteer": "^8.0.0", | ||
"webpack": "^5.26.3" | ||
"webpack": "^5.44.0" | ||
}, | ||
@@ -43,0 +43,0 @@ "peerDependencies": { |
@@ -5,3 +5,3 @@ require('./date-extensions'); | ||
const { randomToken } = require('./random-token'); | ||
const { DATE_STRING, dateToDays, dateStringToDays, isValidDate} = require('./utils/date'); | ||
const { DATE_STRING, dateStringToDays, isValidDate } = require('./utils/date'); | ||
const shuffle = require('./utils/shuffle'); | ||
@@ -205,3 +205,3 @@ const { asBoolean, asNumber, asString } = require('./utils/xpath-cast'); | ||
if: function(con, a, b) { | ||
return XPR.string(asBoolean(con) ? asString(a) : asString(b)); | ||
return asBoolean(con) ? a : b; | ||
}, | ||
@@ -442,6 +442,6 @@ 'ends-with': function(a, b) { | ||
case XPathResult.BOOLEAN_TYPE: return { resultType, booleanValue:!isNaN(r.v) }; | ||
case XPathResult.NUMBER_TYPE: return { resultType, numberValue:dateToDays(r.v) }; | ||
case XPathResult.NUMBER_TYPE: return { resultType, numberValue:asNumber(r) }; | ||
case XPathResult.ANY_TYPE: | ||
case XPathResult.STRING_TYPE: | ||
return { resultType, stringValue:r.v.toISOLocalString().replace(/T00:00:00.000.*/, '') }; | ||
return { resultType, stringValue:asString(r) }; | ||
default: throw new Error(`toExternalResult() doesn't know how to convert a date to ${resultType}`); | ||
@@ -448,0 +448,0 @@ } |
@@ -35,7 +35,8 @@ const { DATE_STRING, dateToDays, dateStringToDays } = require('./date'); | ||
switch(r.t) { | ||
case 'str': return r.v; | ||
case 'arr': return r.v.length ? r.v[0].textContent || '' : ''; | ||
case 'str': return r.v; | ||
case 'arr': return r.v.length ? r.v[0].textContent || '' : ''; | ||
case 'date': return r.v.toISOLocalString().replace(/T00:00:00.000.*/, ''); // TODO should be handled in an extension rather than core code | ||
case 'num': | ||
case 'bool': | ||
default: return r.v.toString(); | ||
default: return r.v.toString(); | ||
} | ||
@@ -42,0 +43,0 @@ } |
@@ -5,3 +5,3 @@ const _ = require('lodash'); | ||
const FULL_DATE_MATCH = /(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d \d{4} \d\d:\d\d:\d\d GMT([+-]\d\d\d\d \(.+\))?/; | ||
const SIMPLE_DATE_MATCH = /^\d{4}-[0-1]\d-[0-3]\d$/; | ||
@@ -16,5 +16,5 @@ describe('some complex examples', () => { | ||
"'raw-string'" : 'raw-string', | ||
'format-date-time(date-time(decimal-date-time("2003-03-12") + 280), "%b %e, %Y")': /Dec 17, 2003/, | ||
'format-date-time(date-time(decimal-date-time("2003-03-12") + 280), "%b %e, %Y")': /^Dec 17, 2003$/, | ||
"decimal-date-time(today()- 60 )": /^-?[0-9]+(\.[0-9]+)?$/, | ||
"date-time(decimal-date-time(today()- 60 ))": /\d{4}-\d{2}-\d{2}/, | ||
"date-time(decimal-date-time(today()- 60 ))": SIMPLE_DATE_MATCH, | ||
"if(selected('date' ,'date'), 'first' ,'second')": /^first$/, | ||
@@ -24,13 +24,13 @@ "if(selected('approx' ,'date'), 'first' ,'second')": /^second$/, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, concat('testing', '1', '2', '3', '...'))": /testing/, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(0))": FULL_DATE_MATCH, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(decimal-date-time(today() - 60)))": FULL_DATE_MATCH, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method ,'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date ,date-time(decimal-date-time(today()- 60 )))": FULL_DATE_MATCH, | ||
'if(true(), today(), today())': FULL_DATE_MATCH, | ||
'if(false(), today(), today())': FULL_DATE_MATCH, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(0))": SIMPLE_DATE_MATCH, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method, 'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date, date-time(decimal-date-time(today() - 60)))": SIMPLE_DATE_MATCH, | ||
"if(selected(/model/instance[1]/pregnancy/group_lmp/lmp_method ,'date'), /model/instance[1]/pregnancy/group_lmp/lmp_date ,date-time(decimal-date-time(today()- 60 )))": SIMPLE_DATE_MATCH, | ||
'if(true(), today(), today())': SIMPLE_DATE_MATCH, | ||
'if(false(), today(), today())': SIMPLE_DATE_MATCH, | ||
'if(true(), "", today())': /^$/, | ||
'if(false(), "", today())': FULL_DATE_MATCH, | ||
'if(true(), today(), "")': FULL_DATE_MATCH, | ||
'if(false(), "", today())': SIMPLE_DATE_MATCH, | ||
'if(true(), today(), "")': SIMPLE_DATE_MATCH, | ||
'if(false(), today(), "")': /^$/, | ||
'coalesce(today(), "")': FULL_DATE_MATCH, | ||
'coalesce("", today())': FULL_DATE_MATCH, | ||
'coalesce(today(), "")': SIMPLE_DATE_MATCH, | ||
'coalesce("", today())': SIMPLE_DATE_MATCH, | ||
'true() or true() or true()': true, | ||
@@ -37,0 +37,0 @@ 'true() or true() or false()': true, |
@@ -36,2 +36,14 @@ const {initDoc, nsResolver, assertMatch, assertFalse, assertString, | ||
describe('dates as number', () => { | ||
it('example 1', () => { | ||
assertNumberRounded('"2018-01-01" + 1', 17533.29167, 100000); | ||
}); | ||
describe('with explicit number() call', () => { | ||
it('example 1', () => { | ||
assertNumberRounded('number("2018-01-01" + 1)', 17533.29167, 100000); | ||
}); | ||
}); | ||
}); | ||
describe('dates as string', () => { | ||
@@ -45,5 +57,2 @@ it('example 1', () => { | ||
it('example 3', () => { | ||
assertNumberRounded('"2018-01-01" + 1', 17533.29167, 100000); | ||
}); | ||
it('example 4', () => { | ||
assertStringValue('date("2018-01-01" + 1)', '2018-01-02'); | ||
@@ -61,2 +70,24 @@ }); | ||
}); | ||
describe('with explicit string() call', () => { | ||
it('example 1', () => { | ||
assertStringValue('string("2018-01-01")', '2018-01-01'); | ||
}); | ||
it('example 2', () => { | ||
assertStringValue('string(date("2018-01-01"))', '2018-01-01'); | ||
}); | ||
it('example 3', () => { | ||
assertStringValue('string(date("2018-01-01" + 1))', '2018-01-02'); | ||
}); | ||
[ | ||
'string(today())', | ||
'string(date(today() + 10))', | ||
'string(date(10 + today()))', | ||
].forEach( expr => { | ||
it(`should convert ${expr} to a date string`, () => { | ||
assertMatch(expr, /([0-9]{4}-[0-9]{2}-[0-9]{2})$/ ); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -63,0 +94,0 @@ }); |
@@ -1,2 +0,2 @@ | ||
const { initDoc, assertStringValue } = require('../helpers'); | ||
const { initDoc, assertBoolean, assertStringValue, assertNumberValue } = require('../helpers'); | ||
@@ -141,2 +141,30 @@ describe('#if()', () => { | ||
}); | ||
describe('deviation from the XForms spec', () => { | ||
let doc; | ||
before(() => { | ||
doc = initDoc(`<data><a/><b/><b/></data>`); | ||
}); | ||
describe('it should NOT coerce the result to a string', () => { | ||
[ | ||
[ 'if(true(), true(), false())', 'true', true ], | ||
[ 'if(false(), true(), false())', 'false', false ], | ||
].forEach(([ expr, expectedString, expectedBoolean ]) => { | ||
it(`should return string value '${expectedString}' and boolean value '${expectedBoolean}' for expression '${expr}'`, () => { | ||
assertStringValue(doc, null, expr, expectedString); | ||
assertBoolean (doc, null, expr, expectedBoolean); | ||
}); | ||
}); | ||
[ | ||
['count( if(true(), //b, //a ))', 2 ] | ||
].forEach(([expr, expectedNumber]) => { | ||
it(`should return node-set values for if() expression '${expr}'`, () => { | ||
assertNumberValue(doc, null, expr, expectedNumber); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
376000
9073