diff --git a/executors/cpp/datetime_fmt.cpp b/executors/cpp/datetime_fmt.cpp
index 473e1d52..f54b3a0e 100644
--- a/executors/cpp/datetime_fmt.cpp
+++ b/executors/cpp/datetime_fmt.cpp
@@ -132,23 +132,26 @@ const string test_datetime_fmt(json_object *json_in) {
timezone_str = json_object_get_string(option_item);
UnicodeString u_tz(timezone_str.c_str());
tz = TimeZone::createTimeZone(u_tz);
- cout << "# Created timezone " << tz << " for " << timezone_str << endl;
+ // cout << "# Created timezone " << tz << " for " << timezone_str << endl;
}
}
json_object *date_skeleton_obj =
- json_object_object_get(json_in, "datetime_skeleton");
+ json_object_object_get(json_in, "skeleton");
if (date_skeleton_obj) {
// Data specifies a date time skeleton. Make a formatter based on this.
string skeleton_string = json_object_get_string(date_skeleton_obj);
+ cout << "# Skeleton = " << skeleton_string << endl;
UnicodeString u_skeleton(skeleton_string.c_str());
if (cal) {
+ cout << " Cal defined " << endl;
df = DateFormat::createInstanceForSkeleton(cal,
u_skeleton,
displayLocale,
status);
} else {
+ cout << " NO CAL DEFINED " << endl;
df = DateFormat::createInstanceForSkeleton(u_skeleton,
displayLocale,
status);
@@ -163,6 +166,12 @@ const string test_datetime_fmt(json_object *json_in) {
}
} else {
// Create default formatter
+ cout << "# createDateTimeInstance: dstyle " <<
+ date_style << ", tstyle " <<
+ time_style << " locale " <<
+ locale_string <<
+ endl;
+
df = DateFormat::createDateTimeInstance(
date_style,
time_style,
@@ -180,10 +189,7 @@ const string test_datetime_fmt(json_object *json_in) {
}
if (tz) {
- cout <<
- "# Setting TZ " <<
- tz <<
- endl;
+ // cout << "# Setting TZ " << tz << endl;
df->setTimeZone(*tz);
}
diff --git a/executors/test_strings.txt b/executors/test_strings.txt
index ed6248ab..8601a03b 100644
--- a/executors/test_strings.txt
+++ b/executors/test_strings.txt
@@ -313,3 +313,18 @@
{"test_type": "rdt_fmt", "label": "100", "unit":"day" "day", "count": 1, "locale": "en-US", "options": {}}
{"test_type": "rdt_fmt", "label": "100", "unit":"day", "count": 1, "locale": "es", "options": {}}
+
+
+// Testing skeleton options
+{"test_type": "datetime_fmt", "label":"10","input_string":"2001-09-09T01:46:40.000Z","locale":"en-US","options":{"calendar":"gregory","numberingSystem":"latn"}}
+ {"test_type": "datetime_fmt", "label":"10","input_string":"2001-09-09T01:46:40.000Z","locale":"en-US","options":{"calendar":"gregory","numberingSystem":"latn"}}
+
+{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"hh","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
+{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"h","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
+{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"H","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
+{"test_type": "datetime_fmt", "label":"101","input_string":"2000-01-01T21:00:00.000Z","skeleton":"hhh","locale":"en-US","options":{"hour":"2-digit","calendar":"gregory","timeZone":"America/Los_Angeles","numberingSystem":"latn"}}
+{"test_type": "datetime_fmt", "label":"1265","input_string":"2024-03-17T07:00:00.000Z","skeleton":"hhhm","locale":"en-US","options":{"hour":"2-digit","minute":"numeric","calendar":"chinese","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}
+
+{"test_type": "datetime_fmt", "label":"3812","input_string":"1969-07-16T07:00:00.000Z","skeleton":"HHm","locale":"en-GB","options":{"hour":"2-digit","minute":"numeric","calendar":"buddhist","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}
+
+{"test_type": "datetime_fmt", "label":"3812","input_string":"1969-07-16T07:00:00.000Z","locale":"en-GB","options":{"dateStyle": "short", "timeStyle": "short", "hour":"2-digit","minute":"numeric","calendar":"buddhist","timeZone":"Australia/Brisbane","numberingSystem":"latn"}}
diff --git a/testgen/generators/datetime_fmt.py b/testgen/generators/datetime_fmt.py
index 99eca134..fd8c64a6 100644
--- a/testgen/generators/datetime_fmt.py
+++ b/testgen/generators/datetime_fmt.py
@@ -32,7 +32,8 @@ def process_test_data(self):
# Set up Node version and call the generator
nvm_version = icu_nvm_versions[self.icu_version]
- generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/datetime_gen.js' % (nvm_version, nvm_version)
+ generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/datetime_gen.js %s %s' % (
+ nvm_version, nvm_version, '-run_limit', self.run_limit)
logging.info('Running this command: %s', generate_command)
result = result = subprocess.run(generate_command, shell=True)
diff --git a/testgen/generators/datetime_gen.js b/testgen/generators/datetime_gen.js
index d36308f3..a01dee76 100644
--- a/testgen/generators/datetime_gen.js
+++ b/testgen/generators/datetime_gen.js
@@ -100,8 +100,10 @@ const dates = [
new Date('Mar 17, 2024'),
new Date('AD 1'),
new Date('AD 0, 13:00'),
+ //new Date('1066, December 16, 7:17'), // Expect Sunday
new Date('1066, December 16, 7:17'),
- new Date('1454, May 29, 16:47'),
+ // new Date('1454, May 29, 16:47'), // Expect Monday
+ new Date('1754, May 29, 16:47'),
new Date('BCE 753, April 21'),
new Date('1969, July 16'),
new Date(0),
@@ -188,7 +190,7 @@ function optionsToSkeleton(options) {
return skeleton_array.join('');
}
-function generateAll() {
+function generateAll(run_limit) {
let test_obj = {
'Test scenario': 'datetime_fmt',
@@ -256,7 +258,7 @@ function generateAll() {
try {
formatter = new Intl.DateTimeFormat(locale, all_options);
} catch (error) {
- console.log(error, ' with locale ',
+ console.error(error, ' with locale ',
locale, ' and options: ', all_options);
continue;
}
@@ -268,7 +270,7 @@ function generateAll() {
const parts = formatter.formatToParts(d);
result = parts.map((x) => x.value).join("");
} catch (error) {
- console.log('FORMATTER CREATION FAILS! ', error);
+ console.error('FORMATTER CREATION FAILS! ', error);
}
// format this date
// get the milliseconds
@@ -297,7 +299,7 @@ function generateAll() {
}
if (debug) {
- console.log("TEST CASE :", test_case);
+ console.debug("TEST CASE :", test_case);
}
test_cases.push(test_case);
@@ -309,7 +311,7 @@ function generateAll() {
console.log(' expected = ', result);
}
} catch (error) {
- console.log('!!! error ', error, ' in label ', label_num,
+ console.error('!!! error ', error, ' in label ', label_num,
' for date = ', d);
}
label_num ++;
@@ -318,11 +320,10 @@ function generateAll() {
}
}
-
- console.log('Number of date/time tests generated for ',
+ console.log('Total date/time tests generated for ',
process.versions.icu, ': ', label_num);
- test_obj['tests'] = test_cases;
+ test_obj['tests'] = sample_tests(test_cases, run_limit);
try {
fs.writeFileSync('datetime_fmt_test.json', JSON.stringify(test_obj, null, 2));
// file written successfully
@@ -330,7 +331,10 @@ function generateAll() {
console.error(err);
}
- verify_obj['verifications'] = verify_cases;
+ console.log('Number of date/time sampled tests ',
+ process.versions.icu, ': ', test_obj['tests'] .length);
+
+ verify_obj['verifications'] = sample_tests(verify_cases, run_limit);
try {
fs.writeFileSync('datetime_fmt_verify.json', JSON.stringify(verify_obj, null, 2));
// file written successfully
@@ -338,5 +342,30 @@ function generateAll() {
console.error(err);
}
}
+
+function sample_tests(all_tests, run_limit) {
+ // Gets a sampling of the data based on total and the expected number.
+
+ if (run_limit < 0 || all_tests.length <= run_limit) {
+ return all_tests;
+ }
+
+ let size_all = all_tests.length;
+ let increment = Math.floor(size_all / run_limit);
+ let samples = [];
+ for (let index = 0; index < size_all; index += increment) {
+ samples.push(all_tests[index]);
+ }
+ return samples;
+}
+
/* Call the generator */
-generateAll();
+let run_limit = -1;
+if (process.argv.length >= 5) {
+ if (process.argv[3] == '-run_limit') {
+ run_limit = Number(process.argv[4]);
+ }
+}
+
+// Call the generator
+generateAll(run_limit);
diff --git a/testgen/generators/relativedatetime_fmt.py b/testgen/generators/relativedatetime_fmt.py
index 76103a07..5a3ad837 100644
--- a/testgen/generators/relativedatetime_fmt.py
+++ b/testgen/generators/relativedatetime_fmt.py
@@ -35,7 +35,7 @@ def process_test_data(self):
generate_command = 'source ~/.nvm/nvm.sh; nvm install %s; nvm use %s; node generators/rdt_fmt_gen.js' % (nvm_version, nvm_version)
logging.info('Running this command: %s', generate_command)
- result = result = subprocess.run(generate_command, shell=True)
+ result = subprocess.run(generate_command, shell=True)
# Move results to the right directory
mv_command = 'mv rdt_fmt*.json %s' % self.icu_version
diff --git a/verifier/detail_template.html b/verifier/detail_template.html
index 42ce3f83..0a0f7db4 100644
--- a/verifier/detail_template.html
+++ b/verifier/detail_template.html
@@ -33,7 +33,11 @@
cursor: pointer;
font-size:20px;
}
-
+
+ #diff_area {
+ font-size: 24px;
+ font-color: blue;
+ }
h1, h2, h3, p {
font-family: Arial, Helvetica, sans-serif;
}
@@ -350,7 +354,7 @@
} else {
output = item[key];
}
- html.push('
' + output +' | ');
+ html.push('' + output +' | ');
}
}
html.push("");
@@ -609,7 +613,31 @@
navigator.clipboard.writeText(output);
}
+ // On hover, show the differen between expected and actual result.
+ function hoverDiffText(element) {
+ // First, get the row of this item.
+ const row = element.parentNode;
+ const text1 = row.children[1].innerHTML;
+ const text2 = row.children[2].innerHTML;
+ if (text1 == text2) {
+ return;
+ }
+ const dmp = new diff_match_patch();
+ const diff_text = dmp.diff_main(text1, text2);
+ dmp.diff_cleanupSemantic(diff_text);
+ // And show the difference nicely.
+ const ds = dmp.diff_prettyHtml(diff_text);
+ const diff_area = document.getElementById("diff_area");
+ diff_area.innerHTML = ds;
+ }
+
+
+
+
Verification report: $test_type on $library_name
@@ -628,6 +656,10 @@ $platform_info
Test details
$test_environment
+
@@ -660,6 +692,7 @@
Test details
Failing tests ($failing_tests)
+
diff --git a/verifier/diff_match_patch.js b/verifier/diff_match_patch.js
new file mode 100644
index 00000000..2fe320a1
--- /dev/null
+++ b/verifier/diff_match_patch.js
@@ -0,0 +1,55 @@
+var diff_match_patch=function(){this.Diff_Timeout=1;this.Diff_EditCost=4;this.Match_Threshold=.5;this.Match_Distance=1E3;this.Patch_DeleteThreshold=.5;this.Patch_Margin=4;this.Match_MaxBits=32},DIFF_DELETE=-1,DIFF_INSERT=1,DIFF_EQUAL=0;diff_match_patch.Diff=function(a,b){this[0]=a;this[1]=b};diff_match_patch.Diff.prototype.length=2;diff_match_patch.Diff.prototype.toString=function(){return this[0]+","+this[1]};
+diff_match_patch.prototype.diff_main=function(a,b,c,d){"undefined"==typeof d&&(d=0>=this.Diff_Timeout?Number.MAX_VALUE:(new Date).getTime()+1E3*this.Diff_Timeout);if(null==a||null==b)throw Error("Null input. (diff_main)");if(a==b)return a?[new diff_match_patch.Diff(DIFF_EQUAL,a)]:[];"undefined"==typeof c&&(c=!0);var e=c,f=this.diff_commonPrefix(a,b);c=a.substring(0,f);a=a.substring(f);b=b.substring(f);f=this.diff_commonSuffix(a,b);var g=a.substring(a.length-f);a=a.substring(0,a.length-f);b=b.substring(0,
+b.length-f);a=this.diff_compute_(a,b,e,d);c&&a.unshift(new diff_match_patch.Diff(DIFF_EQUAL,c));g&&a.push(new diff_match_patch.Diff(DIFF_EQUAL,g));this.diff_cleanupMerge(a);return a};
+diff_match_patch.prototype.diff_compute_=function(a,b,c,d){if(!a)return[new diff_match_patch.Diff(DIFF_INSERT,b)];if(!b)return[new diff_match_patch.Diff(DIFF_DELETE,a)];var e=a.length>b.length?a:b,f=a.length>b.length?b:a,g=e.indexOf(f);return-1!=g?(c=[new diff_match_patch.Diff(DIFF_INSERT,e.substring(0,g)),new diff_match_patch.Diff(DIFF_EQUAL,f),new diff_match_patch.Diff(DIFF_INSERT,e.substring(g+f.length))],a.length>b.length&&(c[0][0]=c[2][0]=DIFF_DELETE),c):1==f.length?[new diff_match_patch.Diff(DIFF_DELETE,
+a),new diff_match_patch.Diff(DIFF_INSERT,b)]:(e=this.diff_halfMatch_(a,b))?(b=e[1],f=e[3],a=e[4],e=this.diff_main(e[0],e[2],c,d),c=this.diff_main(b,f,c,d),e.concat([new diff_match_patch.Diff(DIFF_EQUAL,a)],c)):c&&100
c);t++){for(var v=-t+p;v<=t-x;v+=2){var n=f+v;var r=v==-t||v!=t&&h[n-1]d)x+=2;else if(y>e)p+=2;else if(m&&(n=f+k-v,0<=n&&n=
+u)return this.diff_bisectSplit_(a,b,r,y,c)}}for(v=-t+w;v<=t-q;v+=2){n=f+v;u=v==-t||v!=t&&l[n-1]d)q+=2;else if(r>e)w+=2;else if(!m&&(n=f+k-v,0<=n&&n=u)))return this.diff_bisectSplit_(a,b,r,y,c)}}return[new diff_match_patch.Diff(DIFF_DELETE,a),new diff_match_patch.Diff(DIFF_INSERT,b)]};
+diff_match_patch.prototype.diff_bisectSplit_=function(a,b,c,d,e){var f=a.substring(0,c),g=b.substring(0,d);a=a.substring(c);b=b.substring(d);f=this.diff_main(f,g,!1,e);e=this.diff_main(a,b,!1,e);return f.concat(e)};
+diff_match_patch.prototype.diff_linesToChars_=function(a,b){function c(a){for(var b="",c=0,g=-1,h=d.length;gd?a=a.substring(c-d):c=a.length?[h,k,l,m,g]:null}if(0>=this.Diff_Timeout)return null;
+var d=a.length>b.length?a:b,e=a.length>b.length?b:a;if(4>d.length||2*e.lengthd[4].length?g:d:d:g;else return null;if(a.length>b.length){d=g[0];e=g[1];var h=g[2];var l=g[3]}else h=g[0],l=g[1],d=g[2],e=g[3];return[d,e,h,l,g[4]]};
+diff_match_patch.prototype.diff_cleanupSemantic=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=0,h=0,l=0,k=0;f=e){if(d>=b.length/2||d>=c.length/2)a.splice(f,0,new diff_match_patch.Diff(DIFF_EQUAL,c.substring(0,d))),a[f-1][1]=b.substring(0,b.length-d),a[f+1][1]=c.substring(d),f++}else if(e>=b.length/2||e>=c.length/2)a.splice(f,0,new diff_match_patch.Diff(DIFF_EQUAL,b.substring(0,e))),a[f-1][0]=DIFF_INSERT,a[f-1][1]=c.substring(0,c.length-e),a[f+1][0]=DIFF_DELETE,
+a[f+1][1]=b.substring(e),f++;f++}f++}};
+diff_match_patch.prototype.diff_cleanupSemanticLossless=function(a){function b(a,b){if(!a||!b)return 6;var c=a.charAt(a.length-1),d=b.charAt(0),e=c.match(diff_match_patch.nonAlphaNumericRegex_),f=d.match(diff_match_patch.nonAlphaNumericRegex_),g=e&&c.match(diff_match_patch.whitespaceRegex_),h=f&&d.match(diff_match_patch.whitespaceRegex_);c=g&&c.match(diff_match_patch.linebreakRegex_);d=h&&d.match(diff_match_patch.linebreakRegex_);var k=c&&a.match(diff_match_patch.blanklineEndRegex_),l=d&&b.match(diff_match_patch.blanklineStartRegex_);
+return k||l?5:c||d?4:e&&!g&&h?3:g||h?2:e||f?1:0}for(var c=1;c=k&&(k=m,g=d,h=e,l=f)}a[c-1][1]!=g&&(g?a[c-1][1]=g:(a.splice(c-
+1,1),c--),a[c][1]=h,l?a[c+1][1]=l:(a.splice(c+1,1),c--))}c++}};diff_match_patch.nonAlphaNumericRegex_=/[^a-zA-Z0-9]/;diff_match_patch.whitespaceRegex_=/\s/;diff_match_patch.linebreakRegex_=/[\r\n]/;diff_match_patch.blanklineEndRegex_=/\n\r?\n$/;diff_match_patch.blanklineStartRegex_=/^\r?\n\r?\n/;
+diff_match_patch.prototype.diff_cleanupEfficiency=function(a){for(var b=!1,c=[],d=0,e=null,f=0,g=!1,h=!1,l=!1,k=!1;fb)break;e=c;f=d}return a.length!=g&&a[g][0]===DIFF_DELETE?f:f+(b-e)};
+diff_match_patch.prototype.diff_prettyHtml=function(a){for(var b=[],c=/&/g,d=//g,f=/\n/g,g=0;g");switch(h){case DIFF_INSERT:b[g]=''+l+"";break;case DIFF_DELETE:b[g]=''+l+"";break;case DIFF_EQUAL:b[g]=""+l+""}}return b.join("")};
+diff_match_patch.prototype.diff_text1=function(a){for(var b=[],c=0;cl)throw Error("Invalid number in diff_fromDelta: "+h);h=a.substring(e,e+=l);"="==f[g].charAt(0)?c[d++]=new diff_match_patch.Diff(DIFF_EQUAL,h):c[d++]=
+new diff_match_patch.Diff(DIFF_DELETE,h);break;default:if(f[g])throw Error("Invalid diff operation in diff_fromDelta: "+f[g]);}}if(e!=a.length)throw Error("Delta length ("+e+") does not equal source text length ("+a.length+").");return c};diff_match_patch.prototype.match_main=function(a,b,c){if(null==a||null==b||null==c)throw Error("Null input. (match_main)");c=Math.max(0,Math.min(c,a.length));return a==b?0:a.length?a.substring(c,c+b.length)==b?c:this.match_bitap_(a,b,c):-1};
+diff_match_patch.prototype.match_bitap_=function(a,b,c){function d(a,d){var e=a/b.length,g=Math.abs(c-d);return f.Match_Distance?e+g/f.Match_Distance:g?1:e}if(b.length>this.Match_MaxBits)throw Error("Pattern too long for this browser.");var e=this.match_alphabet_(b),f=this,g=this.Match_Threshold,h=a.indexOf(b,c);-1!=h&&(g=Math.min(d(0,h),g),h=a.lastIndexOf(b,c+b.length),-1!=h&&(g=Math.min(d(0,h),g)));var l=1<=k;q--){var t=e[a.charAt(q-1)];m[q]=0===w?(m[q+1]<<1|1)&t:(m[q+1]<<1|1)&t|(x[q+1]|x[q])<<1|1|x[q+1];if(m[q]&l&&(t=d(w,q-1),t<=g))if(g=t,h=q-1,h>c)k=Math.max(1,2*c-h);else break}if(d(w+1,c)>g)break;x=m}return h};
+diff_match_patch.prototype.match_alphabet_=function(a){for(var b={},c=0;c=2*this.Patch_Margin&&e&&(this.patch_addContext_(a,h),c.push(a),a=new diff_match_patch.patch_obj,e=0,h=d,f=g)}k!==DIFF_INSERT&&(f+=m.length);k!==DIFF_DELETE&&(g+=m.length)}e&&(this.patch_addContext_(a,h),c.push(a));return c};
+diff_match_patch.prototype.patch_deepCopy=function(a){for(var b=[],c=0;cthis.Match_MaxBits){var k=this.match_main(b,h.substring(0,this.Match_MaxBits),g);-1!=k&&(l=this.match_main(b,h.substring(h.length-this.Match_MaxBits),g+h.length-this.Match_MaxBits),-1==l||k>=l)&&(k=-1)}else k=this.match_main(b,h,
+g);if(-1==k)e[f]=!1,d-=a[f].length2-a[f].length1;else if(e[f]=!0,d=k-g,g=-1==l?b.substring(k,k+h.length):b.substring(k,l+this.Match_MaxBits),h==g)b=b.substring(0,k)+this.diff_text2(a[f].diffs)+b.substring(k+h.length);else if(g=this.diff_main(h,g,!1),h.length>this.Match_MaxBits&&this.diff_levenshtein(g)/h.length>this.Patch_DeleteThreshold)e[f]=!1;else{this.diff_cleanupSemanticLossless(g);h=0;var m;for(l=0;le[0][1].length){var f=b-e[0][1].length;e[0][1]=c.substring(e[0][1].length)+e[0][1];d.start1-=f;d.start2-=f;d.length1+=f;d.length2+=f}d=a[a.length-1];e=d.diffs;
+0==e.length||e[e.length-1][0]!=DIFF_EQUAL?(e.push(new diff_match_patch.Diff(DIFF_EQUAL,c)),d.length1+=b,d.length2+=b):b>e[e.length-1][1].length&&(f=b-e[e.length-1][1].length,e[e.length-1][1]+=c.substring(0,f),d.length1+=f,d.length2+=f);return c};
+diff_match_patch.prototype.patch_splitMax=function(a){for(var b=this.Match_MaxBits,c=0;c2*b?(h.length1+=k.length,e+=k.length,l=!1,h.diffs.push(new diff_match_patch.Diff(g,k)),d.diffs.shift()):(k=k.substring(0,b-h.length1-this.Patch_Margin),h.length1+=k.length,e+=k.length,g===DIFF_EQUAL?(h.length2+=k.length,f+=k.length):l=!1,h.diffs.push(new diff_match_patch.Diff(g,k)),k==d.diffs[0][1]?d.diffs.shift():d.diffs[0][1]=d.diffs[0][1].substring(k.length))}g=this.diff_text2(h.diffs);
+g=g.substring(g.length-this.Patch_Margin);k=this.diff_text1(d.diffs).substring(0,this.Patch_Margin);""!==k&&(h.length1+=k.length,h.length2+=k.length,0!==h.diffs.length&&h.diffs[h.diffs.length-1][0]===DIFF_EQUAL?h.diffs[h.diffs.length-1][1]+=k:h.diffs.push(new diff_match_patch.Diff(DIFF_EQUAL,k)));l||a.splice(++c,0,h)}}};diff_match_patch.prototype.patch_toText=function(a){for(var b=[],c=0;c