-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Serialisation Support #31
Changes from 17 commits
9d6c130
50f1ba9
efea9a8
94c9126
9b943df
a7c4bf0
824a5b9
8ba5166
06e148b
c697fa0
5163e5f
aeef6e7
9d95e78
06b56fa
3c1faed
91dba9c
1c3cfec
626d83f
496a0cb
b167d16
6cf462d
9642592
fd3b202
4e97c7e
e094186
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -14,3 +14,10 @@ sourmash = "0.15.1" | |
anyhow = "1.0.89" | ||
log = "0.4.22" | ||
env_logger = "0.11.5" | ||
|
||
# For JSON serialization/deserialization | ||
serde = { version = "1.0", features = ["derive"] } | ||
serde_json = "1.0" | ||
|
||
# For Gzip compression/decompression | ||
flate2 = "1.0" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggest niffler, which allows sniffing/auto-determination of file formats. but we can backport that in if we need. (I'm using it over in #10) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will look into niffler 👍 Only ever expecting gzipped JSON as input. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import gzip | ||
import json | ||
import tempfile | ||
import pytest | ||
|
||
from oxli import KmerCountTable | ||
from os import remove | ||
from test_attr import get_version_from_cargo_toml | ||
|
||
CURRENT_VERSION = get_version_from_cargo_toml() | ||
|
||
@pytest.fixture | ||
def sample_kmer_table(): | ||
"""Fixture that provides a sample KmerCountTable object.""" | ||
table = KmerCountTable(ksize=4) | ||
table.count("AAAA") | ||
table.count("TTTT") | ||
return table | ||
|
||
@pytest.fixture | ||
def temp_file(): | ||
"""Fixture that provides a temporary file path for testing.""" | ||
with tempfile.NamedTemporaryFile(delete=False, suffix='.json.gz') as temp: | ||
yield temp.name | ||
# Remove the file after the test is done | ||
remove(temp.name) | ||
|
||
def test_serialize_json(sample_kmer_table): | ||
""" | ||
Test case for the `serialize_json` function. | ||
|
||
This test verifies that the `serialize_json` function correctly serializes a | ||
KmerCountTable object into a JSON string. | ||
""" | ||
# Serialize the KmerCountTable object to JSON | ||
json_data = sample_kmer_table.serialize_json() | ||
|
||
# Convert back to dict to verify correctness | ||
json_dict = json.loads(json_data) | ||
|
||
# Check that essential attributes exist | ||
assert "counts" in json_dict, "Counts should be serialized." | ||
assert json_dict["ksize"] == 4, "Ksize should be correctly serialized." | ||
assert sample_kmer_table.version == json_dict["version"], "Version should be serialized." | ||
|
||
def test_save_load_roundtrip(sample_kmer_table, temp_file): | ||
""" | ||
Test the save and load functionality. | ||
|
||
This test saves a KmerCountTable object to a file, then loads it back and | ||
verifies that the data in the loaded object matches the original. | ||
""" | ||
# Save the sample KmerCountTable to a Gzip file | ||
sample_kmer_table.save(temp_file) | ||
|
||
# Load the KmerCountTable from the file | ||
loaded_table = KmerCountTable.load(temp_file) | ||
|
||
# Verify that the loaded data matches the original | ||
assert loaded_table.get("AAAA") == sample_kmer_table.get("AAAA"), "Counts should be preserved after loading." | ||
assert loaded_table.get("TTTT") == sample_kmer_table.get("TTTT"), "Counts for reverse complement should be preserved." | ||
assert list(loaded_table) == list(sample_kmer_table), "All records in same order." | ||
|
||
def test_version_warning_on_load_stderr(sample_kmer_table, temp_file, capfd): | ||
""" | ||
Test that a warning is issued if the loaded object's version is different from the current Oxli version. | ||
|
||
Uses pytest's capsys fixture to capture stderr output. | ||
""" | ||
# Save the table to a file | ||
sample_kmer_table.save(temp_file) | ||
|
||
# Mock the current version to simulate a version mismatch | ||
mock_json = sample_kmer_table.serialize_json().replace(CURRENT_VERSION, "0.0.1") | ||
with gzip.open(temp_file, 'wt') as f: | ||
json.dump(json.loads(mock_json), f) | ||
|
||
# Capture stderr output | ||
loaded_table = KmerCountTable.load(temp_file) | ||
captured = capfd.readouterr() | ||
|
||
# Check stderr for the version mismatch warning | ||
assert "Version mismatch" in captured.err | ||
assert f"loaded version is 0.0.1, but current version is {CURRENT_VERSION}" in captured.err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why version 1? latest is 1.0.210. (presumably dependabot will upgrade, just curious.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No good reason, just inherited from example code.