1
1
pub const TEST_VCF: &str = "tests/test.vcf.gz";
2
pub const OUTDIR: &str = "tests/results";
3
pub const TEST_CONTRA: &str = "tests/test_contrahomozygote.vcf.gz";
4
pub const ALTS: hatk::args::Selection = hatk::args::Selection::OnlyAlts;
5
pub const COORDS: &str = "chr9:32";
6

            
7
#[cfg(test)]
8
#[rustfmt::skip]
9
mod integration_tests {
10
    use super::*;
11
    use std::path::PathBuf;
12

            
13
    use hatk::structs::{Coord, PhasedMatrix, HapVariant};
14
    use hatk::args::StandardArgs;
15
    use hatk::subcommands::recursive_mbah::LocDirection;
16
    use hatk::subcommands::rwc::{read_vcf_to_rwc_vec, rwc_vec_to_btreemap};
17
    use hatk::subcommands::shared_haplotype;
18

            
19
    use rust_htslib::bcf::Read;
20
    use ndarray::Array2;
21

            
22

            
23
18
    fn create_test_matrix(nsamples: usize, variants: usize, step_size: usize) -> PhasedMatrix {
24
18
        let variant_idx = variants / 2;
25
18
        let mut matrix = Array2::<u8>::from_elem((nsamples * 2, variants), 0);
26
18
        assert!(variants > nsamples * step_size * 2);
27

            
28
1134
        let pos_coords: Vec<i64> = (1..variants+1).map(|i| i as i64).collect();
29
1134
        let phase_coords: Vec<bool> = (0..variants).map(|_| true).collect();
30
18

            
31
18
        let ref_coords: Vec<String> = (1..variants+1)
32
1131
            .map(|i| if i % 2 == 0 { "G".to_string() } else { "A".to_string() })
33
18
            .collect();
34
18

            
35
18
        let alt_coords: Vec<String> = (1..variants+1)
36
1130
            .map(|i| if i % 2 == 0 { "T".to_string() } else { "C".to_string() })
37
18
            .collect();
38
18

            
39
18
        let samples: Vec<String> = (1..nsamples+1).cycle().take(nsamples * 2)
40
504
            .map(|s| format!("SAMPLE{s}"))
41
18
            .collect();
42
18

            
43
18
        let coords: Vec<Coord> = (0..variants)
44
1133
            .map(|i| Coord {
45
1133
                contig: String::from("chr9"),
46
1133
                phase: phase_coords[i],
47
1133
                pos: pos_coords[i],
48
1133
                reference: ref_coords[i].clone(),
49
1133
                alt: alt_coords[i].clone(),
50
1133
            }).collect();
51

            
52
504
        for i in 0..nsamples * 2 {
53
504
            if i >= nsamples {
54
252
                matrix[[i, variant_idx]] = 1;
55
252
            }
56
504
            matrix[[i, variant_idx - (i+2) * step_size]] = 1;
57
504
            matrix[[i, variant_idx + (i+2) * step_size]] = 1;
58
        }
59

            
60
126
        for i in (0..nsamples).step_by(2) {
61
126
            let (row1, row2) = matrix.multi_slice_mut((ndarray::s![i,..], ndarray::s![i+nsamples, ..]));
62
126
            ndarray::Zip::from(row1).and(row2).for_each(::std::mem::swap);
63
126
        }
64

            
65
18
        PhasedMatrix::new(variant_idx, matrix, samples, coords)
66
18
    }
67

            
68
1
    #[test]
69
1
    fn select_rows() {
70
1
        let mut vcf = create_test_matrix(14, 63, 1);
71
1
        vcf.select_rows(vec![0, 3, 20]);
72
1
        assert_eq!(vcf.samples(), &vec!["SAMPLE1".to_string(), "SAMPLE4".to_string(), "SAMPLE7".to_string()]);
73
1
    }
74

            
75
1
    #[test]
76
1
    fn select_columns_by_range() {
77
1
        let mut vcf = create_test_matrix(14, 63, 1);
78
1
        let pos = vcf.variant_idx_pos();
79
1
        let idx = vcf.variant_idx();
80
1
        vcf.select_columns_by_range(10..50);
81
1

            
82
1
        let pos2 = vcf.variant_idx_pos();
83
1
        let idx2 = vcf.variant_idx();
84
1

            
85
1
        assert_ne!(idx, idx2);
86
1
        assert_eq!(pos, pos2);
87
1
    }
88

            
89
1
    #[test]
90
1
    fn select_columns() {
91
1
        let mut vcf = create_test_matrix(14, 63, 1);
92
1
        vcf.select_columns_by_idx(&mut [0, 3, 20]);
93
3
        assert_eq!(vcf.coords().iter().map(|c| c.pos).collect::<Vec<i64>>(), vec![1, 4, 21]);
94
1
    }
95

            
96
1
    #[test]
97
1
    fn select_alt_carriers() {
98
1
        let nsamples = 14;
99
1
        let vcf = create_test_matrix(nsamples, 63, 1);
100
1

            
101
1
        let pos = vcf.variant_idx_pos();
102
1
        let vcf = hatk::utils::select_carrier_haplotypes(vcf, pos, &format!("chr9:{pos}"), &ALTS);
103
1

            
104
1
        let samples = vec![
105
1
            "SAMPLE1", "SAMPLE3", "SAMPLE5", "SAMPLE7", "SAMPLE9", "SAMPLE11", "SAMPLE13",
106
1
            "SAMPLE2", "SAMPLE4", "SAMPLE6", "SAMPLE8", "SAMPLE10", "SAMPLE12", "SAMPLE14"
107
1
        ];
108
1

            
109
1
        assert_eq!(&samples, vcf.samples());
110
1
    }
111

            
112
1
    #[test]
113
1
    fn select_ref_carriers() {
114
1
        let nsamples = 14;
115
1
        let vcf = create_test_matrix(nsamples, 63, 1);
116
1

            
117
1
        let pos = vcf.variant_idx_pos();
118
1

            
119
1
        let vcf = hatk::utils::select_carrier_haplotypes(
120
1
            vcf, pos, &format!("chr9:{pos}"), &hatk::args::Selection::OnlyRefs
121
1
        );
122
1

            
123
1
        let samples = vec![
124
1
            "SAMPLE2", "SAMPLE4", "SAMPLE6", "SAMPLE8", "SAMPLE10", "SAMPLE12", "SAMPLE14",
125
1
            "SAMPLE1", "SAMPLE3", "SAMPLE5", "SAMPLE7", "SAMPLE9", "SAMPLE11", "SAMPLE13"
126
1
        ];
127
1

            
128
1
        assert_eq!(&samples, vcf.samples());
129
1
    }
130

            
131
1
    #[test]
132
1
    fn get_sample_names_from_phased_matrix() {
133
1
        let nsamples = 14;
134
1
        let vcf = create_test_matrix(nsamples, 63, 1);
135
1
        let names = vcf.get_sample_names(&[0, 3, 20]);
136
1
        assert_eq!(names, vec!["SAMPLE1".to_string(), "SAMPLE4".to_string(), "SAMPLE7".to_string()]);
137

            
138
1
        let name = vcf.get_sample_name(0);
139
1
        assert_eq!("SAMPLE1".to_string(), name);
140
1
    }
141

            
142
1
    #[test]
143
1
    fn phased_matrix_setters_and_getters() {
144
1
        let mut vcf = create_test_matrix(14, 63, 1);
145
1
        vcf.set_coords(vec![]);
146
1
        assert_eq!(&Vec::<Coord>::new(), vcf.coords());
147

            
148
1
        vcf.set_variant_idx(99);
149
1
        assert_eq!(99, vcf.variant_idx());
150

            
151
1
        vcf.set_variant_idx(0);
152
1
        assert_eq!(0, vcf.variant_idx());
153

            
154
1
        let coords = vcf.coords_mut();
155
1
        coords.push(hatk::structs::Coord { 
156
1
            contig: "".to_string(),
157
1
            pos: 10,
158
1
            reference: "".to_string(),
159
1
            alt: "".to_string(),
160
1
            phase: false,
161
1
        });
162
1

            
163
1
        assert_eq!(10, vcf.variant_idx_pos());
164
1
        assert_eq!(1, vcf.ncoords());
165
1
        assert_eq!(14 * 2, vcf.nsamples());
166
1
    }
167

            
168
1
    #[test]
169
1
    fn test_by_pos_idx_getters() {
170
1
        let mut vcf = create_test_matrix(14, 63, 1);
171
1
        let coords = vcf.coords_mut();
172
1

            
173
63
        coords.iter_mut().for_each(|c| c.pos = c.pos.pow(2));
174
1

            
175
1
        assert_eq!(4, vcf.get_nearest_idx_by_pos(26));
176
1
        assert_eq!(4, vcf.get_nearest_idx_by_pos(23));
177
1
        assert_eq!(5, vcf.get_nearest_idx_by_pos(31));
178
1
        assert_eq!(vcf.ncoords(), vcf.get_nearest_idx_by_pos(9999999));
179

            
180
1
        let coord  = hatk::structs::Coord { 
181
1
            contig: "chr9".to_string(),
182
1
            pos: 25,
183
1
            reference: "A".to_string(),
184
1
            alt: "C".to_string(),
185
1
            phase: true,
186
1
        };
187
1

            
188
1
        assert_eq!(4, vcf.idx_by_coord(&coord).unwrap());
189

            
190
1
    }
191

            
192
1
    #[test]
193
1
    fn carrier_vs_only_longest() {
194
1
        let nsamples = 14;
195
1

            
196
1
        let vcf = create_test_matrix(nsamples, 63, 1);
197
1
        let pos = vcf.variant_idx_pos();
198
1
        let vcf = hatk::utils::select_carrier_haplotypes(vcf, pos, &format!("chr9:{pos}"), &ALTS);
199
1

            
200
1
        let vcf2 = create_test_matrix(nsamples, 63, 1);
201
28
        for row in vcf2.matrix.rows() {
202
28
            println!(
203
1764
                "{}", row.to_vec().iter().fold(String::new(), |cur, nxt| format!("{cur}{nxt}") )
204
28
            );
205
28
        }
206

            
207
1
        let lengths = hatk::utils::shared_lengths_by_majority(&vcf2, vcf2.variant_idx());
208
1
        let vcf2 = hatk::utils::select_only_longest_haplotypes(&lengths, vcf2);
209
1

            
210
1

            
211
1
        assert_eq!(vcf.samples(), vcf2.samples())
212
1
    }
213

            
214
1
    #[test]
215
1
    fn select_only_longest_haplotypes() {
216
1
        let nsamples = 14;
217
1
        let vcf = create_test_matrix(nsamples, 63, 1);
218
1
        let lengths = hatk::utils::shared_lengths_by_majority(&vcf, vcf.variant_idx());
219
1
        let vcf = hatk::utils::select_only_longest_haplotypes(&lengths, vcf);
220
1

            
221
1
        let samples = vec![
222
1
            "SAMPLE1", "SAMPLE3", "SAMPLE5", "SAMPLE7", "SAMPLE9", "SAMPLE11", "SAMPLE13",
223
1
            "SAMPLE2", "SAMPLE4", "SAMPLE6", "SAMPLE8", "SAMPLE10", "SAMPLE12", "SAMPLE14"
224
1
        ];
225
1

            
226
1
        assert_eq!(&samples, vcf.samples());
227
1
    }
228

            
229
1
    #[test]
230
1
    fn select_only_longest_alleles() {
231
1
        let nsamples = 14;
232
1
        let vcf = create_test_matrix(nsamples, 63, 1);
233
1
        let shared_lengths = hatk::utils::shared_lengths_by_majority(&vcf, vcf.variant_idx());
234
1
        let only_longest_lengths = hatk::utils::select_only_longest_alleles(&shared_lengths);
235
14
        let indexes: Vec<usize> = only_longest_lengths.iter().map(|l| l.index).collect();
236
1
        let correct_indexes = vec![
237
1
            0, 15, 2, 17, 4, 19, 6,
238
1
            21, 8, 23, 10, 25, 12, 27
239
1
        ];
240
1
        assert_eq!(indexes, correct_indexes)
241
1
    }
242

            
243
1
    #[test]
244
1
    fn longest_common_haplotype() {
245
1
        let vcf = create_test_matrix(14, 63, 1);
246
1
        let pos = vcf.variant_idx_pos();
247
1
        let vcf = hatk::utils::select_carrier_haplotypes(vcf, pos, &format!("chr9:{pos}"), &ALTS);
248
1
        let range = shared_haplotype::find_shared_haplotype_phased(&vcf);
249
1
        assert_eq!((16..47), range);
250

            
251
1
        let vcf = create_test_matrix(14, 63, 1);
252
1
        let range = shared_haplotype::find_shared_haplotype_phased(&vcf);
253
1
        assert_eq!((31..31), range);
254
1
    }
255

            
256
1
    #[test]
257
1
    fn gt_matrix_to_match_matrix() {
258
1
        let file = PathBuf::from("tests/test_haplotype_carriers.csv");
259
1
        let ht = hatk::io::read_haplotype_file(file).unwrap();
260
1
        let start = ht.first().unwrap();
261
1
        let end = ht.last().unwrap();
262
1

            
263
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
264
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, Some((start.pos as u64, end.pos as u64))).unwrap();
265
1

            
266
1
        let vcf = hatk::subcommands::ref_ht_comparison::transform_gt_matrix_to_match_matrix(vcf, &ht);
267
1
        let homozygous_variants = vec![
268
1
            vcf.matrix.slice(ndarray::s![.., 14]).to_vec(),
269
1
            vcf.matrix.slice(ndarray::s![.., 16]).to_vec()
270
1
        ];
271
3
        for col in homozygous_variants {
272
2
            assert_eq!(vec![1; 28], col)
273
        }
274
28
        for row in vcf.matrix.rows() {
275
28
            println!(
276
868
                "{}", row.to_vec().iter().fold(String::new(), |cur, nxt| format!("{cur}{nxt}") )
277
28
            );
278
28
        }
279
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, Some((start.pos as u64, end.pos as u64))).unwrap();
280
1
        let vcf = hatk::utils::select_carrier_haplotypes(vcf, 32, COORDS, &ALTS);
281
1
        let vcf = hatk::subcommands::ref_ht_comparison::transform_gt_matrix_to_match_matrix(vcf, &ht);
282
14
        for row in vcf.matrix.rows() {
283
434
            assert_eq!((16..47).map(|_| 1).collect::<Vec<u8>>(), row.to_vec())
284
        }
285
1
    }
286

            
287
1
    #[test]
288
1
    fn graph_to_svg() {
289
1
        let vcf = create_test_matrix(14, 63, 1);
290
1

            
291
1
        let g = hatk::subcommands::recursive_mbah::tree_petgraph(&vcf, &LocDirection::Left, &None, true).unwrap();
292
1
        let mut dg = hatk::graphs::DecayGraph::new(&g, &vcf, hatk::args::GraphArgs::default());
293
1
        dg.draw_graph().unwrap();
294
1
        svg::save("tests/results/test_run.svg", &dg.document).unwrap();
295
1
    }
296

            
297

            
298

            
299
1
    #[test]
300
1
    fn read_vcf_to_phased_matrix() {
301
1
        let vcf1 = create_test_matrix(14, 63, 1);
302
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
303
1
        let vcf2 = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
304
1

            
305
1
        assert_eq!(vcf1.samples(), vcf2.samples());
306
1
        assert_eq!(vcf1.variant_idx(), vcf2.variant_idx());
307
1
        assert_eq!(vcf1.coords(), vcf2.coords());
308
1
    }
309

            
310
1
    #[test]
311
1
    fn vcf_info_filtering() {
312
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), info_limit: Some(0.9), ..Default::default() };
313
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
314
1

            
315
1
        assert_eq!(vcf.ncoords(), 31);
316
1
    }
317

            
318
1
    #[test]
319
1
    fn read_vcf_to_contra_matrix() {
320
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
321
1
        let (matrix, _pos_coords) = hatk::read_vcf::read_vcf_to_contra_matrix(&args, "chr9", None).unwrap();
322
1
        let mut one_counter = 0;
323
14
        for row in matrix.rows() {
324
896
            for value in row {
325
                // None of the values in the vcf should be alt homozygotes
326
882
                assert_ne!(&2, value);
327

            
328
                // Count all heterozygotes
329
882
                if value == &1 {
330
70
                    one_counter += 1;
331
812
                }
332
            }
333
        }
334
1
        assert_eq!(70, one_counter);
335
1
    }
336

            
337
1
    #[test]
338
1
    fn read_vcf_to_missing_matrix() {
339
1
        let args = StandardArgs { file: PathBuf::from("tests/test_missing.vcf.gz"), ..Default::default() };
340
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix_missing_allowed(&args, "chr9", 32, None).unwrap();
341
1
        let mut missing_counter = 0;
342
28
        for row in vcf.matrix.rows() {
343
1792
            for value in row {
344
                // Count all missing
345
1764
                if value == &99 {
346
3
                    missing_counter += 1;
347
1761
                }
348
            }
349
        }
350
1
        assert_eq!(3, missing_counter);
351
1
    }
352

            
353
1
    #[test]
354
1
    fn read_vcf_to_phased_matrix_by_coords() {
355
1
        let vcf1 = create_test_matrix(14, 63, 1);
356
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
357
1
        let vcf2 = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 16, Some((1,32))).unwrap();
358
1

            
359
1
        assert_eq!(&vcf1.coords().iter().take(32).cloned().collect::<Vec<Coord>>(), vcf2.coords());
360
1
    }
361

            
362
1
    #[test]
363
1
    fn read_vcf_to_phased_matrix_filter_info() {
364
1
        let args = StandardArgs { 
365
1
            file: PathBuf::from(TEST_VCF),  info_limit: Some(0.9), ..Default::default()
366
1
        };
367
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
368
1

            
369
1
        assert_eq!(vcf.ncoords(), 31);
370
1
    }
371

            
372
1
    #[test]
373
1
    fn error_on_not_normalized_vcf() {
374
1
        let args = StandardArgs { 
375
1
            file: PathBuf::from("tests/test_not_normalized.vcf.gz"), ..Default::default()
376
1
        };
377
1

            
378
1
        let res = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None);
379
1
        assert!(res.is_err());
380

            
381
1
        let res = hatk::read_vcf::read_vcf_to_matrix_missing_allowed(&args, "chr9", 32, None);
382
1
        assert!(res.is_err());
383

            
384
1
        let res = hatk::read_vcf::read_vcf_to_contra_matrix(&args, "chr9", None);
385
1
        assert!(res.is_err());
386
1
    }
387

            
388
1
    #[test]
389
1
    fn contrahomozygote() {
390
1
        let test = PathBuf::from(TEST_VCF);
391
1
        let index_vec: Vec<usize> = (0..14).collect();
392
1
        let mut reader = hatk::read_vcf::get_reader(&test, "chr9", None).unwrap();
393
1
        let records = reader.records();
394
1
        let (merged_gt_vec, _) = read_vcf_to_rwc_vec(records, &index_vec, None).unwrap();
395
1
        assert_eq!(vec![0; 63], merged_gt_vec);
396

            
397
1
        let test_contra = PathBuf::from("tests/test_contrahomozygote.vcf.gz");
398
1
        let mut reader = hatk::read_vcf::get_reader(&test_contra, "chr9", None).unwrap();
399
1
        let records = reader.records();
400
1
        let (merged_gt_vec, _) = read_vcf_to_rwc_vec(records, &index_vec, None).unwrap();
401
1
        let mut test_vec = vec![0; 63];
402
1
        test_vec[2] = 1;
403
1
        test_vec[60] = 1;
404
1

            
405
1
        assert_eq!(test_vec, merged_gt_vec);
406
1
    }
407

            
408
1
    #[test]
409
1
    fn contrahomozygote_sequence_length() {
410
1
        let index_vec: Vec<usize> = (0..14).collect();
411
1
        let test_contra = PathBuf::from("tests/test_contrahomozygote.vcf.gz");
412
1
        let mut reader = hatk::read_vcf::get_reader(&test_contra, "chr9", None).unwrap();
413
1
        let records = reader.records();
414
1
        let (merged_gt_vec, _) = read_vcf_to_rwc_vec(records, &index_vec, None).unwrap();
415
1
        let map = rwc_vec_to_btreemap(merged_gt_vec);
416
1
        let value = map.get(&3).unwrap();
417
1
        assert_eq!(value.0, 57);
418

            
419
1
    }
420

            
421
1
    #[test]
422
1
    fn check_for_haplotype() {
423
1
        let vcf = create_test_matrix(14, 63, 1);
424
1

            
425
1
        let ht = vec![
426
1
            HapVariant{ pos: 32, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
427
1
            HapVariant{ pos: 33, contig: "chr9".into(), reference: "A".into(), alt: "C".into(), gt: 0 }
428
1
        ];
429
1

            
430
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
431
1
        assert_eq!(matches.len(), 14);
432

            
433
1
        let ht = vec![
434
1
            HapVariant{ pos: 32, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
435
1
            HapVariant{ pos: 33, contig: "chr9".into(), reference: "A".into(), alt: "C".into(), gt: 0 },
436
1
            HapVariant{ pos: 34, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 1 },
437
1
        ];
438
1

            
439
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
440
1
        assert_eq!(matches.len(), 1);
441

            
442
1
        let ht = vec![
443
1
            HapVariant{ pos: 32, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
444
1
            HapVariant{ pos: 34, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 1 },
445
1
        ];
446
1

            
447
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
448
1
        assert_eq!(matches.len(), 1);
449

            
450
1
        let ht = vec![
451
1
            HapVariant{ pos: 32, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
452
1
            HapVariant{ pos: 34, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 1 },
453
1
            // This does not exist in the test matrix so it will not be taken into account
454
1
            HapVariant{ pos: 35, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 1 }
455
1
        ];
456
1

            
457
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
458
1
        assert_eq!(matches.len(), 1);
459

            
460
1
        let ht = vec![
461
1
            HapVariant{ pos: 32, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
462
1
            HapVariant{ pos: 34, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 1 },
463
1
            HapVariant{ pos: 35, contig: "chr9".into(), reference: "A".into(), alt: "C".into(), gt: 1 }
464
1
        ];
465
1

            
466
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
467
1
        assert_eq!(matches.len(), 0);
468

            
469
1
        let ht = vec![
470
1
            HapVariant{ pos: 9999, contig: "chr9".into(), reference: "G".into(), alt: "T".into(), gt: 0 },
471
1
        ];
472
1

            
473
1
        let matches = hatk::subcommands::check_for_haplotype::identical_haplotype_count(&vcf, &ht);
474
1
        assert!(matches.is_empty());
475
1
    }
476

            
477
1
    #[test]
478
1
    fn set_vcf_variable_data() {
479
1
        let path = PathBuf::from("tests/clinical_data.csv");
480
1
        let df = hatk::io::read_variable_data_file(path).unwrap();
481
1

            
482
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
483
1
        let mut vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
484
1
        vcf.set_variable_data(df).unwrap();
485
1

            
486
1
        // Make sure NA is calculated right in the average
487
1
        let means = vcf.get_variable_data_mean(&[0,1,2,3], &["aoo".to_string(), "dur".to_string()]).unwrap().unwrap();
488
1
        assert_eq!(60.75, means[0]);
489
1
        assert_eq!(7.0, means[1]);
490

            
491
1
        let means = vcf.get_variable_data_mean(
492
1
            &[0,1,2,3,4,5,6,7,8,9,10,11,12,13],
493
1
            &["aoo".to_string(), "dur".to_string()
494
1
        ]).unwrap().unwrap();
495
1

            
496
1
        assert_eq!("62.69", format!("{:.2}", means[0]));
497
1
        assert_eq!("4.00", format!("{:.2}", means[1]));
498

            
499
        // Request variable data on a sample that has no variable data
500
1
        let result = vcf.get_variable_data_mean(&[13], &["aoo".to_string()]);
501
1
        assert!(result.is_err());
502

            
503
1
        let vecs = vcf.get_variable_data_vecs(&[0,1], &["aoo".to_string(), "dur".to_string()]).unwrap().unwrap();
504
1
        assert_eq!(vec![88.0, 49.0], vecs[0]);
505
1
        assert_eq!(vec![2.0, 10.0], vecs[1]);
506
1
    }
507
}
508

            
509
#[cfg(test)]
510
#[rustfmt::skip]
511
mod subcommands {
512
    use super::*;
513

            
514
    use std::path::PathBuf;
515
    use std::io::Write;
516

            
517
    use hatk::args::GraphArgs;
518
    use hatk::args::Selection;
519
    use hatk::args::StandardArgs;
520
    use hatk::graphs::DecayGraph;
521
    use hatk::subcommands::read_sample_names::get_sample_names;
522
    use hatk::subcommands::{
523
        rwc, read_sample_names, shared_haplotype, recursive_mbah, mbah 
524
    };
525
    use hatk::subcommands::recursive_mbah::LocDirection;
526

            
527
13
    fn standard_args(selection: Selection) -> StandardArgs {
528
13
        StandardArgs {
529
13
            file: PathBuf::from(TEST_VCF),
530
13
            output: PathBuf::from("tests/results"),
531
13
            coords: String::from(COORDS),
532
13
            selection,
533
13
            ..Default::default()
534
13
        }
535
13
    }
536

            
537

            
538
    #[cfg(feature = "clap")]
539
16
    fn clap_standard_args(select: hatk::clap::ClapSelection) -> hatk::clap::ClapStandardArgs {
540
16
        hatk::clap::ClapStandardArgs {
541
16
            file: PathBuf::from(TEST_VCF),
542
16
            outdir: PathBuf::from("tests/results"),
543
16
            coords: String::from(COORDS),
544
16
            select,
545
16
            ..Default::default()
546
16
        }
547
16
    }
548

            
549
1
    #[test]
550
1
    fn sample_names_subcommand() {
551
1
        let path = PathBuf::from(TEST_VCF);
552
1
        let ids = get_sample_names(path).unwrap();
553
14
        let vec: Vec<_> = (1..15).map(|v| format!("SAMPLE{v}")).collect();
554
1
        assert_eq!(vec, ids);
555

            
556
1
        let path = PathBuf::from("tests/samples.fam");
557
1
        let ids = get_sample_names(path).unwrap();
558
1
        let vec = vec!["SAMPLE1", "SAMPLE2", "SAMPLE3", "SAMPLE4",];
559
1
        assert_eq!(vec, ids);
560

            
561
1
        let path = PathBuf::from("tests/samples.fam");
562
1
        let res = read_sample_names::run(path);
563
1
        assert!(res.is_ok());
564
1
    }
565

            
566
1
    #[test]
567
1
    fn shared_haplotype() {
568
1
        let args = standard_args(Selection::OnlyLongest);
569
1
        shared_haplotype::run(args, false).unwrap();
570
1

            
571
1
        let res = std::fs::read_to_string("tests/results/shared_haplotype_only_longest.csv").unwrap();
572
1
        insta::assert_yaml_snapshot!(res);
573
1
    }
574

            
575
1
    #[test]
576
1
    fn shared_haplotype_unphased() {
577
1
        let args = standard_args(Selection::Unphased);
578
1
        shared_haplotype::run(args, false).unwrap();
579
1

            
580
1
        let res = std::fs::read_to_string("tests/results/shared_haplotype_rwc.csv").unwrap();
581
1
        insta::assert_yaml_snapshot!(res);
582
1
    }
583

            
584

            
585

            
586
1
    #[test]
587
1
    fn mbah() {
588
1
        let args = standard_args(Selection::All);
589
1

            
590
1
        mbah::run(args, GraphArgs::default(), None, None).unwrap();
591
1

            
592
1
        let res = std::fs::read_to_string("tests/results/mbah.csv").unwrap();
593
1
        insta::assert_yaml_snapshot!(res);
594
1
    }
595

            
596
1
    #[test]
597
1
    fn rwc() {
598
1
        let file = PathBuf::from(TEST_CONTRA);
599
1
        let output = PathBuf::from("tests/results");
600
1
        rwc::run(file, None, output, None, false, 10, None).unwrap();
601
1

            
602
1
        let res = std::fs::read_to_string("tests/results/genome_wide_rwc.csv").unwrap();
603
1
        insta::assert_yaml_snapshot!(res);
604
1
    }
605

            
606
1
    #[test]
607
    #[cfg(feature = "clap")]
608
1
    fn compare_haplotypes() {
609
1
        let args = standard_args(Selection::All);
610
1
        mbah::run(args, GraphArgs::default(), None, None).unwrap();
611
1

            
612
1
        let args = standard_args(Selection::OnlyLongest);
613
1
        shared_haplotype::run(args, false).unwrap();
614
1

            
615
1
        let files = vec![
616
1
            PathBuf::from("tests/results/mbah.csv"),
617
1
            PathBuf::from("tests/results/shared_haplotype_only_longest.csv"),
618
1
        ];
619
1
        let outdir = PathBuf::from(OUTDIR);
620
1
        let cmd = hatk::clap::SubCommand::CompareHaplotypes {
621
1
            haplotypes: files,
622
1
            outdir,
623
1
            prefix: None,
624
1
            csv: true,
625
1
            hide_missing: false,
626
1
            tag_rows: false,
627
1
        };
628
1

            
629
1
        hatk::clap::run_cmd(cmd).unwrap();
630
1

            
631
1
        let res = std::fs::read_to_string("tests/results/ht_comparison.csv").unwrap();
632
1
        insta::assert_yaml_snapshot!(res);
633
1
    }
634

            
635
    #[cfg(feature = "clap")]
636
3
    fn check_for_haplotype(selection: hatk::clap::ClapSelection) {
637
3
        let args = standard_args(Selection::OnlyLongest);
638
3
        shared_haplotype::run(args, false).unwrap();
639
3

            
640
3
        let args = clap_standard_args(selection);
641
3
        let cmd = hatk::clap::SubCommand::CheckForHaplotype {
642
3
            args,
643
3
            haplotype: PathBuf::from("tests/results/shared_haplotype_only_longest.csv"),
644
3
        };
645
3

            
646
3
        hatk::clap::run_cmd(cmd).unwrap();
647
3
    }
648

            
649
1
    #[test]
650
    #[cfg(feature = "clap")]
651
1
    fn check_for_haplotype_all() {
652
1
        check_for_haplotype(hatk::clap::ClapSelection::All);
653
1

            
654
1
        let res = std::fs::read_to_string("tests/results/haplotype_check.csv").unwrap();
655
1
        insta::assert_yaml_snapshot!(res);
656
1
    }
657

            
658
1
    #[test]
659
    #[cfg(feature = "clap")]
660
1
    fn check_for_haplotype_only_longest() {
661
1
        check_for_haplotype(hatk::clap::ClapSelection::OnlyLongest);
662
1

            
663
1
        let res = std::fs::read_to_string("tests/results/haplotype_check_only_longest.csv").unwrap();
664
1
        insta::assert_yaml_snapshot!(res);
665
1
    }
666

            
667
1
    #[test]
668
    #[cfg(feature = "clap")]
669
1
    fn check_for_haplotype_only_refs() {
670
1
        check_for_haplotype(hatk::clap::ClapSelection::OnlyRefs);
671
1

            
672
1
        let res = std::fs::read_to_string("tests/results/haplotype_check_only_refs.csv").unwrap();
673
1
        insta::assert_yaml_snapshot!(res);
674
1
    }
675

            
676
    #[cfg(feature = "clap")]
677
5
    fn ref_ht_comparison(selection: hatk::clap::ClapSelection, mark: bool, png: bool) {
678
5
        let args = standard_args(Selection::OnlyLongest);
679
5
        shared_haplotype::run(args, false).unwrap();
680
5

            
681
5
        let args = clap_standard_args(selection);
682
5

            
683
5
        let cmd = hatk::clap::SubCommand::CompareToHaplotype {
684
5
            args,
685
5
            haplotype: PathBuf::from("tests/results/shared_haplotype_only_longest.csv"),
686
5
            threads: 8,
687
5
            decoy_samples: None,
688
5
            mark_shorter_alleles: mark,
689
5
            png,
690
5
            graph_args: hatk::clap::ClapGraphArgs::default(),
691
5
        };
692
5
        assert_eq!(8, cmd.threads());
693
5
        hatk::clap::run_cmd(cmd).unwrap();
694
5

            
695
5
    }
696

            
697
1
    #[test]
698
    #[cfg(feature = "clap")]
699
1
    fn ref_ht_comparison_all() {
700
1
        ref_ht_comparison(hatk::clap::ClapSelection::All, true, false);
701
1
        let res = std::fs::read_to_string("tests/results/differences.csv").unwrap();
702
1
        insta::assert_yaml_snapshot!(res);
703
1
    }
704

            
705
1
    #[test]
706
    #[cfg(feature = "clap")]
707
1
    fn ref_ht_comparison_only_refs() {
708
1
        ref_ht_comparison(hatk::clap::ClapSelection::OnlyRefs, false, false);
709
1
        let res = std::fs::read_to_string("tests/results/differences_only_refs.csv").unwrap();
710
1
        insta::assert_yaml_snapshot!(res);
711
1
    }
712

            
713
1
    #[test]
714
    #[cfg(feature = "clap")]
715
1
    fn ref_ht_comparison_only_alts() {
716
1
        ref_ht_comparison(hatk::clap::ClapSelection::OnlyAlts, false, false);
717
1
        let res = std::fs::read_to_string("tests/results/differences_only_alts.csv").unwrap();
718
1
        insta::assert_yaml_snapshot!(res);
719
1
    }
720

            
721
1
    #[test]
722
    #[cfg(feature = "clap")]
723
1
    fn ref_ht_comparison_only_longest() {
724
1
        ref_ht_comparison(hatk::clap::ClapSelection::OnlyLongest, false, false);
725
1
        let res = std::fs::read_to_string("tests/results/differences_only_longest.csv").unwrap();
726
1
        insta::assert_yaml_snapshot!(res);
727
1
    }
728

            
729
1
    #[test]
730
    #[cfg(feature = "clap")]
731
1
    fn ref_ht_comparison_png() {
732
1
        ref_ht_comparison(hatk::clap::ClapSelection::All, false, false);
733
1
        let res = std::fs::read_to_string("tests/results/differences.csv").unwrap();
734
1
        insta::assert_yaml_snapshot!(res);
735
1
    }
736

            
737
1
    #[test]
738
    #[cfg(feature = "clap")]
739
1
    fn ref_ht_comparison_fail() {
740
1
        let args = clap_standard_args(hatk::clap::ClapSelection::Unphased);
741
1

            
742
1
        let cmd = hatk::clap::SubCommand::CompareToHaplotype {
743
1
            args,
744
1
            haplotype: PathBuf::from("tests/results/shared_haplotype_only_longest.csv"),
745
1
            threads: 8,
746
1
            decoy_samples: None,
747
1
            mark_shorter_alleles: false,
748
1
            png: false,
749
1
            graph_args: hatk::clap::ClapGraphArgs::default(),
750
1
        };
751
1
        assert!(hatk::clap::run_cmd(cmd).is_err());
752
1
    }
753

            
754
1
    #[test]
755
    #[cfg(feature = "clap")]
756
1
    fn mrca() {
757
1
        let args = clap_standard_args(hatk::clap::ClapSelection::OnlyLongest);
758
1

            
759
1
        let cmd = hatk::clap::SubCommand::Mrca {
760
1
            args,
761
1
            recombination_rates: PathBuf::from("tests/recombination_rates.tsv"),
762
1
        };
763
1
        hatk::clap::run_cmd(cmd).unwrap();
764
1

            
765
1
        let res = std::fs::read_to_string("tests/results/mrca_gamma_method.txt").unwrap();
766
1
        insta::assert_yaml_snapshot!(res);
767
1
    }
768

            
769
1
    #[test]
770
    #[cfg(feature = "clap")]
771
1
    fn mrca_scan() {
772
1
        let args = clap_standard_args(hatk::clap::ClapSelection::All);
773
1

            
774
1
        let cmd = hatk::clap::SubCommand::MrcaScan {
775
1
            args,
776
1
            recombination_rates: PathBuf::from("tests/recombination_rates.tsv"),
777
1
            threads: 8,
778
1
            start: None,
779
1
            stop: None,
780
1
            no_csv: false,
781
1
            plot: true,
782
1
            graph_args: hatk::clap::ClapGraphArgs::default(),
783
1
            mark_centromere: false,
784
1
            step_size: 5,
785
1
        };
786
1
        assert_eq!(8, cmd.threads());
787
1
        hatk::clap::run_cmd(cmd).unwrap();
788
1

            
789
1
        let res = std::fs::read_to_string("tests/results/mrca_scan.csv").unwrap();
790
1
        insta::assert_yaml_snapshot!(res);
791
1
    }
792

            
793

            
794
1
    #[test]
795
    #[cfg(feature = "clap")]
796
1
    fn mrca_scan_only_longest_mark_centromere() {
797
1
        let args = clap_standard_args(hatk::clap::ClapSelection::OnlyLongest);
798
1

            
799
1
        let cmd = hatk::clap::SubCommand::MrcaScan {
800
1
            args,
801
1
            recombination_rates: PathBuf::from("tests/recombination_rates.tsv"),
802
1
            threads: 8,
803
1
            start: None,
804
1
            stop: None,
805
1
            no_csv: false,
806
1
            plot: true,
807
1
            graph_args: hatk::clap::ClapGraphArgs::default(),
808
1
            mark_centromere: true,
809
1
            step_size: 5,
810
1
        };
811
1
        hatk::clap::run_cmd(cmd).unwrap();
812
1

            
813
1
        let res = std::fs::read_to_string("tests/results/mrca_scan.csv").unwrap();
814
1
        insta::assert_yaml_snapshot!(res);
815
1
    }
816

            
817
1
    #[test]
818
    #[cfg(feature = "clap")]
819
1
    fn recursive_mbah() {
820
1
        let args = clap_standard_args(hatk::clap::ClapSelection::OnlyLongest);
821
1

            
822
1
        let cmd = hatk::clap::SubCommand::RecursiveMBAH {
823
1
            args,
824
1
            graph_args: hatk::clap::ClapGraphArgs::default(),
825
1
            decoy_samples: None,
826
1
            variable_data: Some(PathBuf::from("tests/clinical_data.csv")),
827
1
            variables: Some(vec!["aoo".to_string()]),
828
1
            save_branch_haplotypes: true,
829
1
        };
830
1
        hatk::clap::run_cmd(cmd).unwrap();
831
1

            
832
1
        let res = std::fs::read_to_string("tests/results/recursive_mbah_left_only_longest.svg").unwrap();
833
1
        insta::assert_yaml_snapshot!(res);
834
1
    }
835

            
836
1
    #[test]
837
    #[cfg(feature = "clap")]
838
1
    fn recursive_mbah_all() {
839
1
        let args = clap_standard_args(hatk::clap::ClapSelection::All);
840
1

            
841
1
        let cmd = hatk::clap::SubCommand::RecursiveMBAH {
842
1
            args,
843
1
            graph_args: hatk::clap::ClapGraphArgs::default(),
844
1
            decoy_samples: None,
845
1
            variable_data: Some(PathBuf::from("tests/clinical_data.csv")),
846
1
            variables: Some(vec!["aoo".to_string()]),
847
1
            save_branch_haplotypes: true,
848
1
        };
849
1
        hatk::clap::run_cmd(cmd).unwrap();
850
1

            
851
1
        let res = std::fs::read_to_string("tests/results/recursive_mbah_left.svg").unwrap();
852
1
        insta::assert_yaml_snapshot!(res);
853
1
    }
854

            
855
1
    #[test]
856
    #[cfg(feature = "clap")]
857
1
    fn coverage() {
858
1
        let cmd = hatk::clap::SubCommand::Coverage {
859
1
            file: PathBuf::from(TEST_VCF),
860
1
            npipes: 10,
861
1
            bp_per_snp: 2,
862
1
            threads: 1,
863
1
        };
864
1
        let res = hatk::clap::run_cmd(cmd);
865
1
        // Contig has under 100 records
866
1
        assert!(res.is_err());
867
1
    }
868

            
869
1
    #[test]
870
    #[cfg(feature = "clap")]
871
1
    fn samples() {
872
1
        let cmd = hatk::clap::SubCommand::Samples {
873
1
            file: PathBuf::from(TEST_VCF),
874
1
        };
875
1
        hatk::clap::run_cmd(cmd).unwrap();
876
1
    }
877

            
878
1
    #[test]
879
    #[cfg(feature = "clap")]
880
1
    fn local_rwc_alts() {
881
1
        let args = clap_standard_args(hatk::clap::ClapSelection::OnlyAlts);
882
1

            
883
1
        let cmd = hatk::clap::SubCommand::SampleSharedHaplotype {
884
1
            args,
885
1
            threads: 8,
886
1
            niters: 100,
887
1
            sample_size: 4,
888
1
        };
889
1
        hatk::clap::run_cmd(cmd).unwrap();
890
1
    }
891

            
892
1
    #[test]
893
    #[cfg(feature = "clap")]
894
1
    fn local_rwc_unphased() {
895
1
        let args = clap_standard_args(hatk::clap::ClapSelection::Unphased);
896
1

            
897
1
        let cmd = hatk::clap::SubCommand::SampleSharedHaplotype {
898
1
            args,
899
1
            threads: 8,
900
1
            niters: 100,
901
1
            sample_size: 4,
902
1
        };
903
1
        hatk::clap::run_cmd(cmd).unwrap();
904
1
        let res = std::fs::read_to_string("tests/results/random_sampled_shared_haplotype_rwc.csv").unwrap();
905
1
        insta::assert_yaml_snapshot!(res);
906
1
    }
907

            
908

            
909
1
    #[test]
910
    #[cfg(feature = "clap")]
911
1
    fn sampled_rwc() {
912
1
        let cmd = hatk::clap::SubCommand::SampleRWC {
913
1
            file: PathBuf::from(TEST_VCF),
914
1
            merge_rule: hatk::clap::ClapMergeRule::Start,
915
1
            prefix: None,
916
1
            samples: None,
917
1
            outdir: PathBuf::from("tests/results"),
918
1
            info_limit: None,
919
1
            top_markers_n: 20,
920
1
            threads: 8,
921
1
            niters: 100,
922
1
            sort: true,
923
1
            sample_size: 4,
924
1
            min_marker_length: 2,
925
1
        };
926
1
        hatk::clap::run_cmd(cmd).unwrap();
927
1
        let res = std::fs::read_to_string("tests/results/random_sampled_rwc_start.csv").unwrap();
928
1
        insta::assert_yaml_snapshot!(res);
929
1
    }
930

            
931
1
    #[test]
932
1
    fn matrix_to_graph() {
933
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
934
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
935
1

            
936
1
        let g = recursive_mbah::tree_petgraph(&vcf, &LocDirection::Left, &None, true).unwrap();
937
1
        let mut f = std::fs::File::create("tests/results/test.dot").unwrap();
938
1
        f.write_all(format!("{}", petgraph::dot::Dot::new(&g)).as_bytes()).unwrap();
939
1
    }
940

            
941
1
    #[test]
942
1
    fn matrix_graph_png() {
943
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
944
1
        let gargs = GraphArgs { ..Default::default() };
945
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
946
1
        let indexes: Vec<_> = (0..vcf.samples().len()).collect();
947
1
        hatk::graphs::matrix_graph::matrix_graph_png(&vcf, gargs, false, None, &indexes);
948
1
    }
949

            
950
1
    #[test]
951
1
    fn graph_ancestral_haplotype() {
952
1
        let args = StandardArgs { file: PathBuf::from(TEST_VCF), ..Default::default() };
953
1
        let vcf = hatk::read_vcf::read_vcf_to_matrix(&args, "chr9", 32, None).unwrap();
954
1
        let g = recursive_mbah::tree_petgraph(&vcf, &LocDirection::Left, &None, true).unwrap();
955
1
        let dg = DecayGraph::new(&g, &vcf, GraphArgs::default());
956
1
        let ht = dg.find_ancestral_haplotype();
957
1

            
958
1
        let g2 = recursive_mbah::tree_petgraph(&vcf, &LocDirection::Right, &None, true).unwrap();
959
1
        let dg2 = DecayGraph::new(&g2, &vcf, GraphArgs::default());
960
1
        let ht2 = dg2.find_ancestral_haplotype();
961
1

            
962
1
        assert_eq!(ht.len() + ht2.len(), 55);
963

            
964
1
    }
965

            
966
}
967

            
968
#[cfg(test)]
969
#[rustfmt::skip]
970
mod io_tests {
971
    use std::path::PathBuf;
972

            
973
1
    #[test]
974
1
    fn read_haplotype_file() {
975
1
        let file = PathBuf::from("tests/test_haplotype_carriers.csv");
976
1
        let ht = hatk::io::read_haplotype_file(file).unwrap();
977
1
        let pos: Vec<i64> = (17..48).collect();
978
1

            
979
31
        assert_eq!(pos, ht.iter().map(|h| h.pos).collect::<Vec<i64>>());
980

            
981
1
        let file = PathBuf::from("tests/test_haplotype_unsorted.csv");
982
1
        let result = hatk::io::read_haplotype_file(file);
983
1
        assert!(result.is_err());
984
1
    }
985

            
986
1
    #[test]
987
1
    fn read_recombination_rates() {
988
1
        let rates = PathBuf::from("tests/recombination_rates.tsv");
989
1
        let btree = hatk::io::read_recombination_file(rates).unwrap();
990
1
        let pos: Vec<_> = (1..64).collect();
991
63
        for (i, (p, _)) in btree.iter().enumerate() {
992
63
            assert_eq!(&pos[i], p);
993
        }
994
1
        let rates = PathBuf::from("tests/recombination_rates_with_header.tsv");
995
1
        let res = hatk::io::read_recombination_file(rates);
996
1
        assert!(res.is_err());
997
1
    }
998

            
999
1
    #[test]
1
    fn read_samples_file() {
1
        let rates = PathBuf::from("tests/samples.ids");
1
        let wanted = hatk::io::read_sample_ids(&Some(rates)).unwrap().unwrap();
1
        let vec = vec!["SAMPLE1", "SAMPLE2", "SAMPLE3", "SAMPLE10",
1
            "#*@#_)i%*#",
1
            "foo_foosa_23e41_das",
1
            "!!!!!!!",
1
            "#######"
1
        ];
1
        assert_eq!(vec, wanted);
1
        let path = PathBuf::from("tests/does_not_exist.ids");
1
        let res = hatk::io::read_sample_ids(&Some(path));
1
        assert!(res.is_err());
1
    }
1
    #[test]
1
    fn read_variable_data() {
1
        let path = PathBuf::from("tests/clinical_data.csv");
1
        let df = hatk::io::read_variable_data_file(path).unwrap();
1

            
1
        let array = df["id"].utf8().unwrap();
13
        let vec: Vec<_> = array.into_iter().filter_map(|v| v).collect();
1
        assert_eq!(vec[0], "SAMPLE1");
1
        let array = df["aoo"].i64().unwrap();
13
        let vec: Vec<_> = array.into_iter().filter_map(|v| v).collect();
1
        assert_eq!(vec[0], 88);
1
        assert_eq!(vec[2], 58);
1
        let path = PathBuf::from("tests/does_not_exist.csv");
1
        let res = hatk::io::read_variable_data_file(path);
1
        assert!(res.is_err());
1
    }
}