#include "unit_test.h"
#include <slow5/slow5.h>
#include "slow5_extra.h"
#include "slow5_misc.h"
int slow5_open_valid(void) {
struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r");
ASSERT(s5p);
ASSERT(slow5_idx_load(s5p) == 0);
struct slow5_rec *read = NULL;
ASSERT(slow5_get("a649a4ae-c43d-492a-b6a1-a5b8b8076be4", &read, s5p) == 0);
int err;
uint8_t end_reason = slow5_aux_get_enum(read, "end_reason", &err);
ASSERT(end_reason == 4); ASSERT(err == 0);
uint8_t n;
char **end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n);
ASSERT(end_reason_labels);
ASSERT(n == 6);
ASSERT(strcmp(end_reason_labels[end_reason], "signal_positive") == 0);
for (int i = 0; i < n; ++ i) {
ASSERT(printf("%s,", end_reason_labels[i]) == strlen(end_reason_labels[i]) + 1);
}
ASSERT(printf("\n") == 1);
khint_t pos = kh_get(slow5_s2a, read->aux_map, "end_reason");
struct slow5_rec_aux_data end_reason_data = kh_val(read->aux_map, pos);
free(end_reason_data.data);
end_reason = 0;
ASSERT(slow5_rec_set(read, s5p->header->aux_meta, "end_reason", &end_reason) == 0);
end_reason = slow5_aux_get_enum(read, "end_reason", &err);
ASSERT(end_reason == 0); ASSERT(err == 0);
ASSERT(strcmp(end_reason_labels[end_reason], "unknown") == 0);
end_reason = 100;
ASSERT(slow5_rec_set(read, s5p->header->aux_meta, "end_reason", &end_reason) == -4);
slow5_rec_free(read);
ASSERT(slow5_close(s5p) == 0);
return EXIT_SUCCESS;
}
int slow5_get_enum_labels_invalid(void) {
struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r");
ASSERT(s5p);
uint8_t n;
char **end_reason_labels;
end_reason_labels = slow5_get_aux_enum_labels(NULL, "end_reason", &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_ARG);
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, NULL, &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_ARG);
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", NULL);
ASSERT(end_reason_labels);
ASSERT(strcmp(end_reason_labels[4], "signal_positive") == 0);
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "test_array", &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_TYPE);
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "whatisthis", &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_NOFLD);
ASSERT(slow5_close(s5p) == 0);
return EXIT_SUCCESS;
}
int slow5_get_enum_labels_invalid_noaux(void) {
struct slow5_file *s5p = slow5_open("test/data/exp/two_rg/exp_default.slow5", "r");
ASSERT(s5p);
uint8_t n;
char **end_reason_labels;
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_NOAUX);
ASSERT(slow5_close(s5p) == 0);
return EXIT_SUCCESS;
}
int slow5_get_enum_labels_invalid_noenum(void) {
struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless.slow5", "r");
ASSERT(s5p);
uint8_t n;
char **end_reason_labels;
end_reason_labels = slow5_get_aux_enum_labels(s5p->header, "end_reason", &n);
ASSERT(!end_reason_labels);
ASSERT(slow5_errno = SLOW5_ERR_ARG);
ASSERT(slow5_close(s5p) == 0);
return EXIT_SUCCESS;
}
int enum_parse_valid(void) {
char valid_enum1[] = "enum{label}";
char *valid_enum1_labels[] = { "label" };
char valid_enum2[] = "enum{label1,label2}";
char *valid_enum2_labels[] = { "label1", "label2" };
char valid_enum3[] = "enum{x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w}";
char *valid_enum3_labels[] = {"x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w"};
char valid_enum4[] = "enum*{label}";
char *valid_enum4_labels[] = { "label" };
char valid_enum5[] = "enum*{label1,label2}";
char *valid_enum5_labels[] = { "label1", "label2" };
char valid_enum6[] = "enum*{x,y,z,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w}";
char *valid_enum6_labels[] = {"x","y","z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w"};
uint8_t n;
char **labels = slow5_aux_meta_enum_parse(valid_enum1, SLOW5_ENUM, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum1_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum1_labels[i]) == 0);
free(labels[i]);
}
free(labels);
labels = slow5_aux_meta_enum_parse(valid_enum2, SLOW5_ENUM, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum2_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum2_labels[i]) == 0);
free(labels[i]);
}
free(labels);
labels = slow5_aux_meta_enum_parse(valid_enum3, SLOW5_ENUM, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum3_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum3_labels[i]) == 0);
free(labels[i]);
}
free(labels);
labels = slow5_aux_meta_enum_parse(valid_enum4, SLOW5_ENUM_ARRAY, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum4_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum4_labels[i]) == 0);
free(labels[i]);
}
free(labels);
labels = slow5_aux_meta_enum_parse(valid_enum5, SLOW5_ENUM_ARRAY, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum5_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum5_labels[i]) == 0);
free(labels[i]);
}
free(labels);
labels = slow5_aux_meta_enum_parse(valid_enum6, SLOW5_ENUM_ARRAY, &n);
ASSERT(labels);
ASSERT(n == SLOW5_LENGTH(valid_enum6_labels));
for (uint16_t i = 0; i < n; ++ i) {
ASSERT(strcmp(labels[i], valid_enum6_labels[i]) == 0);
free(labels[i]);
}
free(labels);
return EXIT_SUCCESS;
}
int enum_parse_invalid(void) {
char invalid_enum1[] = "enum";
char invalid_enum2[] = "enum{";
char invalid_enum3[] = "enum}";
char invalid_enum4[] = "enum*";
char invalid_enum5[] = "enum{}";
char invalid_enum6[] = "enum{a,}";
char invalid_enum7[] = "enum{,}";
char invalid_enum8[] = "enum{,,,}";
char invalid_enum9[] = "enum{*}";
char invalid_enum10[] = "enum{abcd, efg}";
char invalid_enum11[] = "enum{123,}";
char invalid_enum12[] = "enum{abc,efg ,hi}";
char invalid_enum13[] = "enum{ x}";
char invalid_enum14[] = "enum{x }";
char invalid_enum15[] = "enum{x }";
char invalid_enum16[] = "enum{ x }";
char invalid_enum17[] = "enum{ x}";
char invalid_enum18[] = "enum{abc;efg;hij}";
char invalid_enum19[] = "enum(abc,efg,hij)";
char invalid_enum20[] = "enum{123}";
uint8_t n;
char **labels = slow5_aux_meta_enum_parse(invalid_enum1, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum2, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum3, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum4, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum4, SLOW5_ENUM_ARRAY, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum5, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum6, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum7, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum8, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum9, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum10, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum11, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum12, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum13, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum14, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum15, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum16, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum17, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum18, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum19, SLOW5_ENUM, &n);
ASSERT(!labels);
labels = slow5_aux_meta_enum_parse(invalid_enum20, SLOW5_ENUM, &n);
ASSERT(!labels);
return EXIT_SUCCESS;
}
int slow5_enum_parse_duplicate(void) {
char invalid_enum1[] = "enum{a,a}";
uint8_t n;
char **labels = slow5_aux_meta_enum_parse(invalid_enum1, SLOW5_ENUM, &n);
ASSERT(!labels);
struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason_dup.slow5", "r");
ASSERT(!s5p);
ASSERT(slow5_errno == SLOW5_ERR_HDRPARSE);
return EXIT_SUCCESS;
}
int slow5_get_set_enum_array(void) {
struct slow5_file *s5p = slow5_open("test/data/exp/aux_array/exp_lossless_end_reason.slow5", "r");
ASSERT(s5p);
ASSERT(slow5_idx_load(s5p) == 0);
uint8_t enum_array_valid[] = { 0, 1, 2, 3, 4, 5 };
uint8_t enum_array_invalid[] = { 0, 1, 2, 3, 4, 5, 6 };
const char *enum_labels[] = {"unk","par","mux","unblock","plus","neg"};
const char *enum_labels_bad[] = {"unk","par","mux","unblock","+","-"};
struct slow5_rec *read = NULL;
ASSERT(slow5_get("a649a4ae-c43d-492a-b6a1-a5b8b8076be4", &read, s5p) == 0);
ASSERT(slow5_aux_meta_add_enum(s5p->header->aux_meta, "end_reasons", SLOW5_ENUM_ARRAY, enum_labels_bad, SLOW5_LENGTH(enum_labels_bad)) == -4);
ASSERT(slow5_aux_meta_add_enum(s5p->header->aux_meta, "end_reasons", SLOW5_ENUM_ARRAY, enum_labels, SLOW5_LENGTH(enum_labels)) == 0);
ASSERT(slow5_rec_set_array(read, s5p->header->aux_meta, "end_reasons", enum_array_valid, SLOW5_LENGTH(enum_array_valid)) == 0);
slow5_press_method_t method = {SLOW5_COMPRESS_NONE, SLOW5_COMPRESS_NONE};
slow5_hdr_print(s5p->header, SLOW5_FORMAT_ASCII, method);
slow5_rec_print(read, s5p->header->aux_meta, SLOW5_FORMAT_ASCII, NULL);
ASSERT(slow5_rec_set_array(read, s5p->header->aux_meta, "end_reasons", enum_array_invalid, SLOW5_LENGTH(enum_array_invalid)) == -4);
slow5_rec_free(read);
ASSERT(slow5_close(s5p) == 0);
return EXIT_SUCCESS;
}
int main(void) {
slow5_set_log_level(SLOW5_LOG_OFF);
slow5_set_exit_condition(SLOW5_EXIT_OFF);
struct command tests[] = {
CMD(slow5_open_valid)
CMD(slow5_get_enum_labels_invalid)
CMD(slow5_get_enum_labels_invalid_noaux)
CMD(slow5_get_enum_labels_invalid_noenum)
CMD(enum_parse_valid)
CMD(enum_parse_invalid)
CMD(slow5_enum_parse_duplicate)
CMD(slow5_get_set_enum_array)
};
return RUN_TESTS(tests);
}