Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
30b0a18
Adding ICU4C running collation tests - first try
Dec 5, 2023
3663d79
Cache ICU4C binaries in GH and locally, only if they don't exist
echeran Dec 6, 2023
8f1a829
Install JSON-C dependency if not installed at beginning of CI or e2e …
echeran Dec 6, 2023
4277048
Fix bash if condition syntax
echeran Dec 6, 2023
3e7a734
Merge branch 'main' of github.com:sven-oly/conformance
Jan 4, 2024
8eca805
Merge branch 'main' into main
Jan 4, 2024
7091b62
Merge branch 'main' of github.com:unicode-org/conformance
Jan 4, 2024
350165f
Merge branch 'main' of github.com:unicode-org/conformance
Jan 9, 2024
3c1068a
Merge branch 'main' of github.com:unicode-org/conformance
Jan 11, 2024
8ca0ed9
Merge branch 'main' of github.com:unicode-org/conformance
Jan 17, 2024
0af99f4
Merge branch 'main' of github.com:unicode-org/conformance
Jan 19, 2024
67ce396
Merge branch 'main' of github.com:unicode-org/conformance
Jan 19, 2024
943accd
Making compare report files
Jan 20, 2024
d3b4fe2
Compare UI prototype
Jan 23, 2024
9709f35
Merge branch 'main' of github.com:unicode-org/conformance into compar…
Jan 24, 2024
72041f9
Compare: Moving toward comparison with hash_id
Jan 25, 2024
68c0c97
Merge remote-tracking branch 'upstream/main' into compare_results
Jan 3, 2025
0e21261
Merge remote-tracking branch 'upstream/main' into compare_results
sven-oly May 1, 2025
5a9f819
more preparation for comparing test sets
sven-oly May 6, 2025
d7522fc
Merge remote-tracking branch 'upstream/main' into compare_results
sven-oly May 9, 2025
caa2b84
Update testreport for comparing test groups
sven-oly May 12, 2025
08c34cd
Merge remote-tracking branch 'upstream/main' into compare_results
sven-oly Aug 22, 2025
c35f28e
Merge remote-tracking branch 'upstream/main' into compare_results
sven-oly Sep 2, 2025
ab1e004
Merge remote-tracking branch 'upstream/main' into compare_results
sven-oly Sep 3, 2025
a3a208b
Removing unneeded changes
sven-oly Sep 3, 2025
ea7b22a
More reverting
sven-oly Sep 3, 2025
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
281 changes: 281 additions & 0 deletions verifier/compare_template.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
<html>
<!--
Build a comparison page for test results on the same test suite,
including graphics and other tools to better understand differences
in results between platforms and different test data versions.
E.g., NodeJS v 21.6.0 number format with ICU 74 vs.
ICU4C 74.2 with ICU74 test data.

Started 19-Jan-2024, cwc.

https://www.freecodecamp.org/news/interactive-heatmap-in-javascript/
-->
<head>
<title>Heatmap in JavaScript</title>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-heatmap.min.js"></script>


<!-- JQuery -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>

<script>

// Pointers to the data directories
const data_dirs = $data_dirs;
const test_names = $test_names;
let compare_directories = ['', '']; // Two data directories for comparison

let results = {};

let heat_map_data = {
};

let states = ['pass', 'fail', 'error', 'unsupported'];

for (let state1 of states) {
for (let state2 of states) {
let data_item = {x:state1, y:state2, heat:0}
}
}
function load_and_update() {
// Get the values from the selectors.
const checked1 = document.querySelector(
"input[type='radio'][name='select1']:checked");
if (checked1 == null) {
alert('Pick 2 items');
return;
}

const checked2 = document.querySelector(
"input[type='radio'][name='select2']:checked");
if (checked2 == null) {
alert('Pick 2 items');
return;
}

// loadRawData for each.
const dir1 = checked1.value;
const dir2 = checked2.value;

let results1 = loadRawData(dir1);

let results2 = loadRawData(dir2);

// update the heat map.
Promise.all([results1, results2])
.then(([results1, results2]) => {
reloadHeatMap(results1, results2);
}
)
}

function loadRawData(data_dir) {
// Get the pass, fail, etc. JSON data from this directory.
// Via fetch
// TODO: Open the files and the JSON data for each status.

let load_results = {};
// Return these data pointers
let p1 = fetch(data_dir + '/pass.json');
let p2 = fetch(data_dir + '/failing_tests.json');
let p3 = fetch(data_dir + '/test_errors.json');
let p4 = fetch(data_dir + '/unsupported.json');

// Synchronize all the data loading and charts / pagination

// Wait for results, then return data
let all_promises = Promise.all([
p1.then((response) => response.json())
.then((data) => {
load_results['pass'] = data}),
p2.then((response) => response.json())
.then((data) => {
load_results['fail'] = data}),
p3.then((response) => response.json())
.then((data) => {
load_results['error'] = data}),
p4.then((response) => response.json())
.then((data) => {
load_results['unsupported'] = data}),
new Promise((resolve, reject) => {
$(document).ready(resolve);
})
]).
then(([p1, p2, p3, p4, _ready]) => {
return load_results;
}
)
return all_promises;
}

function setOfIdentifiers(test_list) {
let result = new Set();
for (let test of test_list) {
let input_data = test['input_data'];
result.add(input_data['hash_id']);
}
return result;
}

function reloadHeatMap(result1, result2) {
// Compute intersections of test identifiers
// Redo the heat map.
heat_map_data = [];
for (let state1 of states) {
let id_set1 = setOfIdentifiers(result1[state1]);

for (let state2 of states) {
let id_set2 = setOfIdentifiers(result2[state2]);

let inter_set =
new Set([...id_set1].filter((x) => id_set2.has(x)));
let data_item = {x:state1, y:state2, heat:inter_set.size}
heat_map_data.push(data_item);

}
}

draw_heat_map();
}

function build_page() {
build_radio_buttons('select1', 'select1');
build_radio_buttons('select2', 'select2');
}

function build_radio_buttons(div_id, rb_name) {
const div = document.getElementById(div_id);
for (const index in test_names) {
const name = test_names[index];
const data_dir = data_dirs[index];
let rb = document.createElement("INPUT");
rb.setAttribute("type", "radio");
rb.name = rb_name;
rb.value = data_dir;

let html_label = document.createElement("label");
html_label.appendChild(document.createTextNode(name));

div.appendChild(html_label);
html_label.appendChild(rb);
}
}


// Global chart;
let chart = null;

// Set up a heat map
function draw_heat_map() {
// anychart.onDocumentReady(function () {
// create a heatmap
const heat_data = getData();
chart = anychart.heatMap(heat_data);
// set a custom color scale
var colorScale = anychart.scales.ordinalColor();
// TODO: Compute max and scale the values as greyscale
let max_val = 0
for (let item of heat_data) {
max_val = Math.max(item.heat, max_val);
}

colorScale.ranges([
{ less: max_val / 100, color: "#B0D8A4" },
{ from: max_val / 100, to: max_val / 20, color: "#FEE191" },
{ from: max_val / 20, to: max_val * 0.90, color: "#FD8060" },
{ greater: max_val * 0.90, color: "#CC333F" }
]);
chart.colorScale(colorScale);

var customColorScale = anychart.scales.linearColor();
customColorScale.colors(["#222222", "#eeeeee"]);

// set the color scale as the color scale of the chart
chart.colorScale(customColorScale);
// Not defined? chart.palette(anychart.palettes.monochrome);


// style the coloring in the hovered state
chart
.hovered()
.fill(function () {
return anychart.color.darken(this.sourceColor, 0.25);
});

// TODO: decide on this hide the item labels
chart.labels(true);
// customize the axes
chart.xAxis().stroke(null);
chart.yAxis().stroke(null);
chart.yAxis().labels().padding([0, 10, 0, 0]);
chart.xAxis().labels().padding([0, 0, 10, 0]);
// set the tooltip
chart.tooltip().title().useHtml(true);
chart
.tooltip()
.useHtml(true)
.titleFormat(function () {
return this.x + "," + this.y + ': ' +this.heat;
})
.format(function () {
return (
'<span style="color: #CECECE">Test 1: </span>' +
this.x +
"<br/>" +
'<span style="color: #CECECE">Test 2:: </span>' +
this.y
);
});
// name the heatmap
chart
.title()
.enabled(true)
.text('$title')
.padding([0, 0, 20, 0]);
// set the container for the heatmap
chart.container("heat_map_container");
// draw the heatmap
chart.draw();
// });

}

// All the code for the JS heatmap will come here
// add the data
function getData() {
// TODO: Fill this in
return heat_map_data;
}


</script>
<style type="text/css">
html, body, #head_map_container_ container {
width: 80%; height: 80%; margin: 0; padding: 0;
}
</style>
<style>
.main div {
float: left;
clear: none;
}
</style>
</head>

<body onLoad="build_page()">
<h2>Compare test results for $test_type</h2>
<div if="instance_selection">
<p>Instances for test $test_type. Pick 2!</p>
<div id="instance_selectors">
<div id="select1"><label for='select1: '>Select 1:</label></div>
<div id="select2"><label for='select2: '>Select 2: </label></div>
<div id="choose_items">
<button type="button" onclick="load_and_update();">Load data</button>
</div>
</div>
</div>
<div id="heat_map_container"></div>

</body>
</html>
31 changes: 31 additions & 0 deletions verifier/compare_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Templates for creating comparison pages in verifier
import glob
import json
import logging
import logging.config
from string import Template
import sys

class compareTemplate():
def __init__(self):
logging.config.fileConfig("../logging.conf")

# Read the template data
compare_template = ''
filename = 'compare_template.html'
try:
template_file = open(filename, mode='r')
compare_template = template_file.read()
template_file.close()
except:
logging.error('Cannot open compare_template %s', filename)

self.html_template = Template(compare_template)

# Template for picking tests - will be replaced by html generated in detail_template.html
self.checkbox_test_template = Template(
'<div id="$id_div"><input type=checkbox class="test_id" id="$id" name="$name" value="$value" onclick="checkboxChanged(this);"</input><label for="$id">$test_name</div>'
)

def reportOutline(self):
return self.html_template
24 changes: 21 additions & 3 deletions verifier/summary_template.html
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,19 @@
let background_color;
for (const test_type of test_types) {
tr = table.insertRow();
td = tr.insertCell();
td.innerHTML = test_type

test_type_td = tr.insertCell();

// Create a link to the page to compare
const a_ref = document.createElement('a');
const link = document.createTextNode('Compare ' + test_type);
a_ref.title = "Compare " + test_type;
test_type.innerHTML = test_type;
// Assemble the data for the instances
let compare_list = [];
let test_names = [];

<!-- put link to comparison selection for the test type -->

const tests = exec_summary_json[test_type];
for (const exec of executed_platforms) {
Expand Down Expand Up @@ -307,6 +318,7 @@
details.push(link);
}
}

td = tr.insertCell();
if (reports.length > 0) {
// Create the data for the reports
Expand Down Expand Up @@ -344,7 +356,13 @@
}
td = tr.insertCell();
td.innerHTML = details.join('');
}
}
// Set the compare link for this test type.
const compare_link_text = "compare_" + test_type + ".html";
test_type_td.innerHTML = "<a href=\'" + compare_link_text + "'" +
" target='_blank'>" + test_type + "</a>";


}
}
</script>
Expand Down
Loading
Loading