Skip to content

Commit 0b8c780

Browse files
committed
test(gcta/removerelatedsubjects): harden basename contract coverage
1 parent 6f7692d commit 0b8c780

3 files changed

Lines changed: 113 additions & 99 deletions

File tree

modules/nf-core/gcta/removerelatedsubjects/meta.yml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,24 @@ input:
1616
- - meta:
1717
type: map
1818
description: |
19-
Groovy map containing dense GRM metadata
20-
e.g. `[ id:'plink_simulated' ]`
19+
Groovy map containing dense GRM metadata.
20+
`meta.id` is the required GRM basename consumed by `--grm` and must match
21+
the staged dense GRM files.
22+
e.g. `[ id:'tiny_dense' ]` requires
23+
`tiny_dense.grm.id`, `tiny_dense.grm.bin`, and `tiny_dense.grm.N.bin`.
2124
- grm_id:
2225
type: file
23-
description: Dense GRM sample identifier file
26+
description: Dense GRM sample identifier file with basename `${meta.id}`
2427
pattern: "*.grm.id"
2528
ontologies: []
2629
- grm_bin:
2730
type: file
28-
description: Dense GRM binary matrix file
31+
description: Dense GRM binary matrix file with basename `${meta.id}`
2932
pattern: "*.grm.bin"
3033
ontologies: []
3134
- grm_n_bin:
3235
type: file
33-
description: Dense GRM sample-count matrix file
36+
description: Dense GRM sample-count matrix file with basename `${meta.id}`
3437
pattern: "*.grm.N.bin"
3538
ontologies: []
3639

@@ -39,8 +42,8 @@ output:
3942
- - meta:
4043
type: map
4144
description: |
42-
Groovy map containing dense GRM metadata
43-
e.g. `[ id:'plink_simulated' ]`
45+
Groovy map containing dense GRM metadata.
46+
`meta.id` remains the dense-GRM basename contract used for `--grm`.
4447
- "*_unrel05.grm.id":
4548
type: file
4649
description: Relatedness-filtered GRM sample identifier file
@@ -60,8 +63,8 @@ output:
6063
- - meta:
6164
type: map
6265
description: |
63-
Groovy map containing dense GRM metadata
64-
e.g. `[ id:'plink_simulated' ]`
66+
Groovy map containing dense GRM metadata.
67+
`meta.id` remains the dense-GRM basename contract used for `--grm`.
6568
- "*_unrel05.grm.id":
6669
type: file
6770
description: Keep file of unrelated individuals emitted by GCTA

modules/nf-core/gcta/removerelatedsubjects/tests/main.nf.test

Lines changed: 75 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -8,46 +8,18 @@ nextflow_process {
88
tag "modules_nfcore"
99
tag "gcta"
1010
tag "gcta/removerelatedsubjects"
11-
tag "gcta/makegrmpart"
12-
13-
setup {
14-
run("GCTA_MAKEGRMPART", alias: "GCTA_MAKEGRMPART_DENSE") {
15-
script "../../makegrmpart/main.nf"
16-
process {
17-
"""
18-
file('plink_simulated.mbfile').text = 'plink_simulated\\n'
19-
20-
input[0] = [
21-
[ id:'plink_simulated_dense', part_gcta_job:1, nparts_gcta:1 ],
22-
file('plink_simulated.mbfile'),
23-
[
24-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.bed', checkIfExists: true)
25-
],
26-
[
27-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.bim', checkIfExists: true)
28-
],
29-
[
30-
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.fam', checkIfExists: true)
31-
]
32-
]
33-
input[1] = [[ id:'all_variants' ], []]
34-
"""
35-
}
36-
}
37-
}
3811

3912
test("homo_sapiens popgen - remove related individuals from dense GRM") {
4013
config "./nextflow.config"
4114

4215
when {
4316
process {
4417
"""
45-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
46-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
47-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
48-
}
18+
file('tiny_dense.grm.id').text = 'sample1 sample1\\n'
19+
file('tiny_dense.grm.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(1.0f).array()
20+
file('tiny_dense.grm.N.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(100.0f).array()
4921

50-
input[0] = dense_grm
22+
input[0] = [[ id:'tiny_dense' ], file('tiny_dense.grm.id'), file('tiny_dense.grm.bin'), file('tiny_dense.grm.N.bin')]
5123
"""
5224
}
5325
}
@@ -57,7 +29,15 @@ nextflow_process {
5729
{ assert process.success },
5830
{ assert process.out.grm_files.size() == 1 },
5931
{ assert process.out.keep_file.size() == 1 },
60-
{ assert process.out.grm_files.get(0).get(0).id == "plink_simulated_dense.part_1_1" },
32+
{ assert process.out.grm_files.get(0).get(0).id == "tiny_dense" },
33+
{
34+
def grm_row = process.out.grm_files.get(0)
35+
def expected_prefix = "${grm_row.get(0).id}_unrel05"
36+
assert file(grm_row.get(1)).name == "${expected_prefix}.grm.id"
37+
assert file(grm_row.get(2)).name == "${expected_prefix}.grm.bin"
38+
assert file(grm_row.get(3)).name == "${expected_prefix}.grm.N.bin"
39+
assert file(process.out.keep_file.get(0).get(1)).name == "${expected_prefix}.grm.id"
40+
},
6141
{
6242
assert snapshot(
6343
process.out.grm_files,
@@ -69,27 +49,83 @@ nextflow_process {
6949
}
7050
}
7151

52+
test("homo_sapiens popgen - remove related individuals fails when meta.id is not GRM basename") {
53+
config "./nextflow.config"
54+
55+
when {
56+
process {
57+
"""
58+
file('tiny_dense.grm.id').text = 'sample1 sample1\\n'
59+
file('tiny_dense.grm.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(1.0f).array()
60+
file('tiny_dense.grm.N.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(100.0f).array()
61+
62+
input[0] = [[ id:'tiny_dense_mismatched' ], file('tiny_dense.grm.id'), file('tiny_dense.grm.bin'), file('tiny_dense.grm.N.bin')]
63+
"""
64+
}
65+
}
66+
67+
then {
68+
assertAll(
69+
{ assert !process.success },
70+
{ assert process.exitStatus != 0 }
71+
)
72+
}
73+
}
74+
75+
test("homo_sapiens popgen - remove related individuals fails for malformed GRM tuple") {
76+
config "./nextflow.config"
77+
78+
when {
79+
process {
80+
"""
81+
file('tiny_dense.grm.id').text = 'sample1 sample1\\n'
82+
file('tiny_dense.grm.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(1.0f).array()
83+
84+
input[0] = [[ id:'tiny_dense' ], file('tiny_dense.grm.id'), file('tiny_dense.grm.bin')]
85+
"""
86+
}
87+
}
88+
89+
then {
90+
assert !process.success
91+
}
92+
}
93+
7294
test("homo_sapiens popgen - remove related individuals from dense GRM - stub") {
7395
options "-stub"
7496
config "./nextflow.config"
7597

7698
when {
7799
process {
78100
"""
79-
dense_grm = GCTA_MAKEGRMPART_DENSE.out.grm_files.map { meta, grm_id, grm_bin, grm_n_bin ->
80-
def prefix = meta.id + '.part_' + meta.nparts_gcta + '_' + meta.part_gcta_job
81-
[[ id:prefix ], grm_id, grm_bin, grm_n_bin]
82-
}
101+
file('tiny_dense.grm.id').text = 'sample1 sample1\\n'
102+
file('tiny_dense.grm.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(1.0f).array()
103+
file('tiny_dense.grm.N.bin').bytes = java.nio.ByteBuffer.allocate(4).order(java.nio.ByteOrder.LITTLE_ENDIAN).putFloat(100.0f).array()
83104

84-
input[0] = dense_grm
105+
input[0] = [[ id:'tiny_dense' ], file('tiny_dense.grm.id'), file('tiny_dense.grm.bin'), file('tiny_dense.grm.N.bin')]
85106
"""
86107
}
87108
}
88109

89110
then {
90111
assertAll(
91112
{ assert process.success },
92-
{ assert snapshot(process.out).match() }
113+
{ assert process.out.grm_files.get(0).get(0).id == "tiny_dense" },
114+
{
115+
def grm_row = process.out.grm_files.get(0)
116+
def expected_prefix = "${grm_row.get(0).id}_unrel05"
117+
assert file(grm_row.get(1)).name == "${expected_prefix}.grm.id"
118+
assert file(grm_row.get(2)).name == "${expected_prefix}.grm.bin"
119+
assert file(grm_row.get(3)).name == "${expected_prefix}.grm.N.bin"
120+
assert file(process.out.keep_file.get(0).get(1)).name == "${expected_prefix}.grm.id"
121+
},
122+
{
123+
assert snapshot(
124+
process.out.grm_files,
125+
process.out.keep_file,
126+
process.out.findAll { key, val -> key.startsWith('versions') }
127+
).match()
128+
}
93129
)
94130
}
95131
}

modules/nf-core/gcta/removerelatedsubjects/tests/main.nf.test.snap

Lines changed: 26 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
[
55
[
66
{
7-
"id": "plink_simulated_dense.part_1_1"
7+
"id": "tiny_dense"
88
},
9-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,ca8c0bded6951fdd3bf0dddc97b6df6b",
10-
"plink_simulated_dense.part_1_1_unrel05.grm.bin:md5,b1f124463eecbae86840a6651eec372d",
11-
"plink_simulated_dense.part_1_1_unrel05.grm.N.bin:md5,06b73ea8bae8f1e5f5d4de33dbd2c75e"
9+
"tiny_dense_unrel05.grm.id:md5,822e827e7c1bf900290ef807f514b94d",
10+
"tiny_dense_unrel05.grm.bin:md5,429d81ed2795e3c586906c6c335aa136",
11+
"tiny_dense_unrel05.grm.N.bin:md5,a5d1e9463fae706307f90b05e9e6db9a"
1212
]
1313
],
1414
[
1515
[
1616
{
17-
"id": "plink_simulated_dense.part_1_1"
17+
"id": "tiny_dense"
1818
},
19-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,ca8c0bded6951fdd3bf0dddc97b6df6b"
19+
"tiny_dense_unrel05.grm.id:md5,822e827e7c1bf900290ef807f514b94d"
2020
]
2121
],
2222
{
@@ -33,54 +33,29 @@
3333
"nf-test": "0.9.3",
3434
"nextflow": "25.10.4"
3535
},
36-
"timestamp": "2026-03-13T15:36:41.961471309"
36+
"timestamp": "2026-03-21T00:36:33.212296305"
3737
},
3838
"homo_sapiens popgen - remove related individuals from dense GRM - stub": {
3939
"content": [
40+
[
41+
[
42+
{
43+
"id": "tiny_dense"
44+
},
45+
"tiny_dense_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e",
46+
"tiny_dense_unrel05.grm.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
47+
"tiny_dense_unrel05.grm.N.bin:md5,d41d8cd98f00b204e9800998ecf8427e"
48+
]
49+
],
50+
[
51+
[
52+
{
53+
"id": "tiny_dense"
54+
},
55+
"tiny_dense_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e"
56+
]
57+
],
4058
{
41-
"0": [
42-
[
43-
{
44-
"id": "plink_simulated_dense.part_1_1"
45-
},
46-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e",
47-
"plink_simulated_dense.part_1_1_unrel05.grm.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
48-
"plink_simulated_dense.part_1_1_unrel05.grm.N.bin:md5,d41d8cd98f00b204e9800998ecf8427e"
49-
]
50-
],
51-
"1": [
52-
[
53-
{
54-
"id": "plink_simulated_dense.part_1_1"
55-
},
56-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e"
57-
]
58-
],
59-
"2": [
60-
[
61-
"GCTA_REMOVERELATEDSUBJECTS",
62-
"gcta",
63-
"1.94.1"
64-
]
65-
],
66-
"grm_files": [
67-
[
68-
{
69-
"id": "plink_simulated_dense.part_1_1"
70-
},
71-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e",
72-
"plink_simulated_dense.part_1_1_unrel05.grm.bin:md5,d41d8cd98f00b204e9800998ecf8427e",
73-
"plink_simulated_dense.part_1_1_unrel05.grm.N.bin:md5,d41d8cd98f00b204e9800998ecf8427e"
74-
]
75-
],
76-
"keep_file": [
77-
[
78-
{
79-
"id": "plink_simulated_dense.part_1_1"
80-
},
81-
"plink_simulated_dense.part_1_1_unrel05.grm.id:md5,d41d8cd98f00b204e9800998ecf8427e"
82-
]
83-
],
8459
"versions_gcta": [
8560
[
8661
"GCTA_REMOVERELATEDSUBJECTS",
@@ -94,6 +69,6 @@
9469
"nf-test": "0.9.3",
9570
"nextflow": "25.10.4"
9671
},
97-
"timestamp": "2026-03-13T15:36:48.571305038"
72+
"timestamp": "2026-03-21T00:37:24.069976205"
9873
}
9974
}

0 commit comments

Comments
 (0)