Skip to content

Commit 3231354

Browse files
Merge pull request #51 from ainefairbrother/add-unit-tests
Add unit testing
2 parents 6c483eb + 11e5704 commit 3231354

File tree

86 files changed

+19255
-1
lines changed

Some content is hidden

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

86 files changed

+19255
-1
lines changed

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,8 @@ venv.bak/
6767

6868
# editor cruft
6969
.vscode
70-
.idea
70+
.idea
71+
72+
# mac os
73+
.DS_Store
74+
common/.DS_Store
-180 KB
Binary file not shown.
1.26 KB
Binary file not shown.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Script to generate gold standard query results for a list of test-case variants.
4+
5+
Description:
6+
This script reads a list of variant IDs (one per line) from a text file and a genome ID string from the command line.
7+
For each variant, it executes the master GraphQL query against the in-memory schema and saves the query result
8+
as a JSON file in the specified output directory.
9+
10+
Example usage:
11+
python -m graphql_service.tests.get_gold_std_query_results \
12+
/app/graphql_service/tests/gold_std_test_cases.txt \
13+
"a7335667-93e7-11ec-a39d-005056b38ce3" \
14+
/app/graphql_service/tests/gold_std_query_results
15+
"""
16+
17+
import argparse
18+
import asyncio
19+
import json
20+
from graphql_service.tests.test_utils import execute_query, build_schema_context
21+
import os
22+
23+
schema_and_context = build_schema_context()
24+
25+
async def main(variant_file, genome_id, output_dir):
26+
"""
27+
Run master query against schema for all test cases.
28+
"""
29+
30+
with open(variant_file, "r") as f:
31+
variants = [line.strip() for line in f if line.strip()]
32+
33+
os.makedirs(output_dir, exist_ok=True)
34+
35+
# Run master query for each test case
36+
for variant_id in variants:
37+
query, success, result = await execute_query(schema_and_context, genome_id, variant_id)
38+
if success:
39+
print(f"Query executed successfully for variant {variant_id}")
40+
output_file = f"{output_dir}/{variant_id}.json"
41+
with open(output_file, "w") as f_out:
42+
json.dump(result, f_out, indent=4)
43+
print(f"Result saved to {output_file}")
44+
else:
45+
print(f"Query execution failed for variant {variant_id}.\nQuery: {query}\nResult: {result}")
46+
47+
if __name__ == "__main__":
48+
parser = argparse.ArgumentParser(description="Generate JSON files from GraphQL query results for variants")
49+
parser.add_argument("variant_file", help="Path to text file with variant IDs (one per line, format CHR:POS:ID)")
50+
parser.add_argument("genome_id", help="Genome ID string to use in the query")
51+
parser.add_argument("output_dir", help="Directory to save JSON result files")
52+
args = parser.parse_args()
53+
54+
asyncio.run(main(args.variant_file, args.genome_id, args.output_dir))

graphql_service/tests/conftest.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
.. See the NOTICE file distributed with this work for additional information
3+
regarding copyright ownership.
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
Unless required by applicable law or agreed to in writing, software
9+
distributed under the License is distributed on an "AS IS" BASIS,
10+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
See the License for the specific language governing permissions and
12+
limitations under the License.
13+
"""
14+
15+
import pytest
16+
from .test_utils import build_schema_context
17+
import os
18+
import json
19+
20+
@pytest.fixture(scope="session")
21+
def schema_context():
22+
"""
23+
Session-scoped fixture reused by all tests.
24+
"""
25+
return build_schema_context()
26+
27+
@pytest.fixture(scope="session")
28+
def gold_standard_loader():
29+
"""
30+
Returns a function that, given a variant_id, will read
31+
and parse the corresponding JSON gold-standard file.
32+
"""
33+
def _loader(path: str, genome_id: str, variant_id: str) -> dict:
34+
path = os.path.join(path, genome_id, f"{variant_id}.json")
35+
with open(path, "r") as f:
36+
return json.load(f)
37+
return _loader
Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
{
2+
"data": {
3+
"variant": {
4+
"name": "rs1360968155",
5+
"alternative_names": [],
6+
"primary_source": {
7+
"__typename": "ExternalReference"
8+
},
9+
"type": "Variant",
10+
"allele_type": {
11+
"__typename": "OntologyTermMetadata"
12+
},
13+
"slice": {
14+
"__typename": "Slice"
15+
},
16+
"alleles": [
17+
{
18+
"name": "11:19518426:C:G",
19+
"allele_sequence": "G",
20+
"reference_sequence": "C",
21+
"alternative_names": [],
22+
"type": "VariantAllele",
23+
"allele_type": {
24+
"__typename": "OntologyTermMetadata"
25+
},
26+
"slice": {
27+
"__typename": "Slice"
28+
},
29+
"phenotype_assertions": [],
30+
"prediction_results": [],
31+
"population_frequencies": [],
32+
"predicted_molecular_consequences": [
33+
{
34+
"allele_name": "G",
35+
"stable_id": "ENST00000360655",
36+
"feature_type": {
37+
"__typename": "OntologyTermMetadata"
38+
},
39+
"consequences": [
40+
{
41+
"__typename": "OntologyTermMetadata"
42+
}
43+
],
44+
"prediction_results": [],
45+
"gene_stable_id": "ENSG00000166833",
46+
"gene_symbol": "NAV2",
47+
"protein_stable_id": null,
48+
"transcript_biotype": "protein_coding",
49+
"cdna_location": null,
50+
"cds_location": null,
51+
"protein_location": null
52+
},
53+
{
54+
"allele_name": "G",
55+
"stable_id": "ENST00000532874",
56+
"feature_type": {
57+
"__typename": "OntologyTermMetadata"
58+
},
59+
"consequences": [
60+
{
61+
"__typename": "OntologyTermMetadata"
62+
}
63+
],
64+
"prediction_results": [],
65+
"gene_stable_id": "ENSG00000254622",
66+
"gene_symbol": "NAV2-AS4",
67+
"protein_stable_id": null,
68+
"transcript_biotype": "lncRNA",
69+
"cdna_location": {
70+
"relation": null,
71+
"start": 317,
72+
"end": 317,
73+
"length": 1,
74+
"percentage_overlap": null,
75+
"ref_sequence": "-",
76+
"alt_sequence": "G"
77+
},
78+
"cds_location": null,
79+
"protein_location": null
80+
},
81+
{
82+
"allele_name": "G",
83+
"stable_id": "ENST00000837121",
84+
"feature_type": {
85+
"__typename": "OntologyTermMetadata"
86+
},
87+
"consequences": [
88+
{
89+
"__typename": "OntologyTermMetadata"
90+
}
91+
],
92+
"prediction_results": [],
93+
"gene_stable_id": "ENSG00000254622",
94+
"gene_symbol": "NAV2-AS4",
95+
"protein_stable_id": null,
96+
"transcript_biotype": "lncRNA",
97+
"cdna_location": {
98+
"relation": null,
99+
"start": 513,
100+
"end": 513,
101+
"length": 1,
102+
"percentage_overlap": null,
103+
"ref_sequence": "-",
104+
"alt_sequence": "G"
105+
},
106+
"cds_location": null,
107+
"protein_location": null
108+
},
109+
{
110+
"allele_name": "G",
111+
"stable_id": "ENST00000837122",
112+
"feature_type": {
113+
"__typename": "OntologyTermMetadata"
114+
},
115+
"consequences": [
116+
{
117+
"__typename": "OntologyTermMetadata"
118+
},
119+
{
120+
"__typename": "OntologyTermMetadata"
121+
}
122+
],
123+
"prediction_results": [],
124+
"gene_stable_id": "ENSG00000254622",
125+
"gene_symbol": "NAV2-AS4",
126+
"protein_stable_id": null,
127+
"transcript_biotype": "lncRNA",
128+
"cdna_location": null,
129+
"cds_location": null,
130+
"protein_location": null
131+
},
132+
{
133+
"allele_name": "G",
134+
"stable_id": "ENST00000837123",
135+
"feature_type": {
136+
"__typename": "OntologyTermMetadata"
137+
},
138+
"consequences": [
139+
{
140+
"__typename": "OntologyTermMetadata"
141+
},
142+
{
143+
"__typename": "OntologyTermMetadata"
144+
}
145+
],
146+
"prediction_results": [],
147+
"gene_stable_id": "ENSG00000254622",
148+
"gene_symbol": "NAV2-AS4",
149+
"protein_stable_id": null,
150+
"transcript_biotype": "lncRNA",
151+
"cdna_location": null,
152+
"cds_location": null,
153+
"protein_location": null
154+
}
155+
],
156+
"ensembl_website_display_data": {
157+
"count_transcript_consequences": 2,
158+
"count_overlapped_genes": 2,
159+
"count_regulatory_consequences": 1,
160+
"count_variant_phenotypes": 0,
161+
"count_gene_phenotypes": 0,
162+
"representative_population_allele_frequency": null
163+
}
164+
},
165+
{
166+
"name": "11:19518426:C:C",
167+
"allele_sequence": "C",
168+
"reference_sequence": "C",
169+
"alternative_names": [],
170+
"type": "VariantAllele",
171+
"allele_type": {
172+
"__typename": "OntologyTermMetadata"
173+
},
174+
"slice": {
175+
"__typename": "Slice"
176+
},
177+
"phenotype_assertions": [],
178+
"prediction_results": [],
179+
"population_frequencies": [],
180+
"predicted_molecular_consequences": [],
181+
"ensembl_website_display_data": {
182+
"count_transcript_consequences": 0,
183+
"count_overlapped_genes": 0,
184+
"count_regulatory_consequences": 0,
185+
"count_variant_phenotypes": 0,
186+
"count_gene_phenotypes": 0,
187+
"representative_population_allele_frequency": null
188+
}
189+
}
190+
],
191+
"prediction_results": [
192+
{
193+
"score": null,
194+
"result": "splice_donor_variant",
195+
"classification": null,
196+
"analysis_method": {
197+
"__typename": "AnalysisMethod"
198+
}
199+
}
200+
],
201+
"ensembl_website_display_data": {
202+
"count_citations": 0
203+
}
204+
}
205+
}
206+
}

0 commit comments

Comments
 (0)