Skip to content

Commit 8e10527

Browse files
author
Jon Belyeu
committed
include tests
1 parent be36994 commit 8e10527

72 files changed

Lines changed: 6621 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

tests/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Tests package

tests/conftest.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
Pytest configuration and common fixtures
3+
"""
4+
5+
import tempfile
6+
from pathlib import Path
7+
8+
import pytest
9+
10+
11+
@pytest.fixture
12+
def temp_dir():
13+
"""Create a temporary directory for testing"""
14+
with tempfile.TemporaryDirectory() as tmp_dir:
15+
yield Path(tmp_dir)
16+
17+
18+
@pytest.fixture
19+
def sample_data():
20+
"""Sample data for testing"""
21+
return {
22+
"samples": ["sample1", "sample2", "sample3"],
23+
"include_list": ["sample1", "sample2"],
24+
"exclude_list": ["sample3"],
25+
"file_paths": [
26+
"/path/to/file1.txt",
27+
"/path/to/file2.txt",
28+
"/path/to/dir/file3.txt",
29+
],
30+
}
31+
32+
33+
@pytest.fixture(autouse=True)
34+
def setup_test_environment(monkeypatch):
35+
"""Setup test environment variables and paths"""
36+
# Set up test-specific environment
37+
monkeypatch.setenv("TESTING", "true")
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8">
5+
<title>Orographer Plot</title>
6+
<style>
7+
html, body {
8+
box-sizing: border-box;
9+
display: flow-root;
10+
height: 100%;
11+
margin: 0;
12+
padding: 0;
13+
}
14+
</style>
15+
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-3.9.0.min.js"></script>
16+
<script src="https://cdn.bokeh.org/bokeh/release/bokeh-widgets-3.9.0.min.js"></script>
17+
<script>
18+
Bokeh.set_log_level("info");
19+
</script>
20+
</head>
21+
<body>
22+
<div id="dbc693e8-6d13-4a46-8f1f-88fdc58db67e" data-root-id="p1249" style="display: contents;"></div>
23+
24+
25+
<script>
26+
(function() {
27+
const fn = function() {
28+
Bokeh.safely(function() {
29+
(function(root) {
30+
function embed_document(root) {
31+
// Load JSON data from external .json.gz file and decompress in browser
32+
const jsonFile = "chr2_130592001_130605000_bokeh.json.gz?v=1774040304";
33+
const headerBreakpoint = 825;
34+
const centerOffsetWide = 20;
35+
const centerOffsetNarrow = 0;
36+
const centerOffsetFullWidthAt = 1500;
37+
38+
function getScaledCenterOffset(windowWidth) {
39+
if (windowWidth <= headerBreakpoint) return centerOffsetNarrow;
40+
if (windowWidth >= centerOffsetFullWidthAt) return centerOffsetWide;
41+
const span = centerOffsetFullWidthAt - headerBreakpoint;
42+
const ratio = (windowWidth - headerBreakpoint) / span;
43+
return Math.round(centerOffsetNarrow + ratio * (centerOffsetWide - centerOffsetNarrow));
44+
}
45+
46+
function updateResponsiveHeaderByModel() {
47+
if (!root || !root.Bokeh || !root.Bokeh.documents) return false;
48+
const docs = root.Bokeh.documents;
49+
const useWide = window.innerWidth > headerBreakpoint;
50+
for (let i = 0; i < docs.length; i++) {
51+
const doc = docs[i];
52+
const wide = doc.get_model_by_name("orographer_original_region_wide");
53+
const narrow = doc.get_model_by_name("orographer_original_region_narrow_row");
54+
const centerOffsetSpacer = doc.get_model_by_name("orographer_center_offset_spacer");
55+
if (wide && narrow && centerOffsetSpacer) {
56+
wide.visible = useWide;
57+
narrow.visible = !useWide;
58+
centerOffsetSpacer.width = getScaledCenterOffset(window.innerWidth);
59+
wide.change.emit();
60+
narrow.change.emit();
61+
centerOffsetSpacer.change.emit();
62+
return true;
63+
}
64+
}
65+
return false;
66+
}
67+
68+
(async function () {
69+
try {
70+
const response = await fetch(jsonFile);
71+
if (!response.ok) {
72+
throw new Error(
73+
"Failed to load JSON file: " + response.status + " " + response.statusText
74+
);
75+
}
76+
const stream = response.body.pipeThrough(new DecompressionStream("gzip"));
77+
const streamResponse = await new Response(stream);
78+
const data = await streamResponse.json();
79+
const docs_json = data.docs_json;
80+
const render_items = data.render_items;
81+
root.Bokeh.embed.embed_items(docs_json, render_items);
82+
let tries = 0;
83+
const maxTries = 80;
84+
function tryUpdateHeader() {
85+
tries += 1;
86+
if (updateResponsiveHeaderByModel()) return;
87+
if (tries < maxTries) setTimeout(tryUpdateHeader, 100);
88+
}
89+
setTimeout(tryUpdateHeader, 200);
90+
window.addEventListener("resize", function () {
91+
updateResponsiveHeaderByModel();
92+
});
93+
} catch (error) {
94+
const errorDiv = document.createElement("div");
95+
errorDiv.style.cssText =
96+
"position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); " +
97+
"background: #f44336; color: white; padding: 20px; border-radius: 5px; " +
98+
"z-index: 10000; font-family: Arial, sans-serif; max-width: 500px;";
99+
errorDiv.innerHTML =
100+
"<h3 style=\"margin-top: 0;\">Error Loading Plot Data</h3>" +
101+
"<p style=\"margin: 10px 0;\">" + error.message + "</p>" +
102+
"<p style=\"font-size: 12px; margin-top: 10px;\">" +
103+
"Make sure you are serving files from a web server (not opening file:// directly).</p>" +
104+
"<p style=\"font-size: 12px;\">Try: <code>orographer deploy --output-dir ./output</code> " +
105+
"or any static file server.</p>" +
106+
"<p style=\"font-size: 12px; margin-top: 10px;\">" +
107+
"Then open: <code>http://localhost:8000/chr2_130592001_130605000_bokeh.html</code></p>";
108+
document.body.appendChild(errorDiv);
109+
console.error("Error loading JSON:", error);
110+
}
111+
})();
112+
113+
114+
}
115+
if (root.Bokeh !== undefined) {
116+
embed_document(root);
117+
} else {
118+
let attempts = 0;
119+
const timer = setInterval(function(root) {
120+
if (root.Bokeh !== undefined) {
121+
clearInterval(timer);
122+
embed_document(root);
123+
} else {
124+
attempts++;
125+
if (attempts > 100) {
126+
clearInterval(timer);
127+
console.log("Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing");
128+
}
129+
}
130+
}, 10, root)
131+
}
132+
})(window);
133+
});
134+
};
135+
if (document.readyState != "loading") fn();
136+
else document.addEventListener("DOMContentLoaded", fn);
137+
})();
138+
</script>
139+
140+
<!-- Modal for details (alignments and variants) -->
141+
<div id="alignmentModal" style="display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgba(0,0,0,0.4);align-items:center;justify-content:center;">
142+
<div id="alignmentModalWrapper" style="display:flex;align-items:center;justify-content:center;max-height:90vh;">
143+
<div id="alignmentModalDialog" style="background:#fefefe;padding:20px;border:1px solid #888;width:400px;">
144+
<span id="closeModal" style="color:#aaa;float:right;font-size:28px;font-weight:bold;cursor:pointer;">&times;</span>
145+
<h2 style="margin-top: 0; color: #333;">Details</h2>
146+
<div id="modalContent" style="font-size: 14px; line-height: 1.8;"></div>
147+
</div>
148+
</div>
149+
</div>
150+
151+
<script>
152+
// Modal close handlers and fitAlignmentModalToPlot
153+
const modal = document.getElementById("alignmentModal");
154+
const closeBtn = document.getElementById("closeModal");
155+
window.fitAlignmentModalToPlot = function () {
156+
const wrapper = document.getElementById("alignmentModalWrapper");
157+
const dialog = document.getElementById("alignmentModalDialog");
158+
const root = document.querySelector(".bk-root");
159+
if (!wrapper || !dialog) return;
160+
const maxH = root
161+
? Math.max(120, 0.9 * root.getBoundingClientRect().height)
162+
: 0.9 * window.innerHeight;
163+
dialog.style.maxHeight = "";
164+
dialog.style.transform = "";
165+
const naturalH = dialog.scrollHeight;
166+
const naturalW = dialog.offsetWidth || 400;
167+
if (naturalH > maxH) {
168+
if (maxH > 0) {
169+
const scale = maxH / naturalH;
170+
dialog.style.transform = "scale(" + scale + ")";
171+
dialog.style.transformOrigin = "top left";
172+
wrapper.style.width = naturalW * scale + "px";
173+
wrapper.style.height = naturalH * scale + "px";
174+
wrapper.style.overflow = "hidden";
175+
}
176+
} else {
177+
dialog.style.transformOrigin = "";
178+
wrapper.style.width = "";
179+
wrapper.style.height = "";
180+
wrapper.style.overflow = "";
181+
}
182+
};
183+
if (closeBtn) closeBtn.onclick = function () { modal.style.display = "none"; };
184+
window.onclick = function (e) {
185+
if (e.target === modal) modal.style.display = "none";
186+
};
187+
document.addEventListener("keydown", function (e) {
188+
if (e.key === "Escape") modal.style.display = "none";
189+
});
190+
191+
</script>
192+
</body>
193+
</html>

0 commit comments

Comments
 (0)