diff --git a/.indent.pro b/.indent.pro index 66eef285..2800b51c 100644 --- a/.indent.pro +++ b/.indent.pro @@ -107,6 +107,8 @@ -T lxw_drawing_rel_id -T lxw_error -T lxw_fill +-T lxw_filter_rule +-T lxw_filter_rule_obj -T lxw_font -T lxw_format -T lxw_hash_element diff --git a/include/xlsxwriter/common.h b/include/xlsxwriter/common.h index 0d99117f..57f20c64 100644 --- a/include/xlsxwriter/common.h +++ b/include/xlsxwriter/common.h @@ -293,6 +293,9 @@ enum lxw_custom_property_types { #define LXW_WARN_FORMAT2(message, var1, var2) \ LXW_PRINTF(LXW_STDERR "[WARNING]: " message "\n", var1, var2) +#define LXW_WARN_FORMAT3(message, var1, var2, var3) \ + LXW_PRINTF(LXW_STDERR "[WARNING]: " message "\n", var1, var2, var3) + /* Chart axis type checks. */ #define LXW_WARN_CAT_AXIS_ONLY(function) \ do { \ diff --git a/include/xlsxwriter/worksheet.h b/include/xlsxwriter/worksheet.h index a2aaa5a1..55e4f993 100644 --- a/include/xlsxwriter/worksheet.h +++ b/include/xlsxwriter/worksheet.h @@ -536,6 +536,56 @@ enum lxw_conditional_icon_types { LXW_CONDITIONAL_ICONS_5_QUARTERS }; +/** @brief The criteria used in autofilter rules. + * + * Criteria used to define an autofilter rule condition. + */ +enum lxw_filter_criteria { + LXW_FILTER_CRITERIA_NONE, + + /** Filter cells equal to a value. */ + LXW_FILTER_CRITERIA_EQUAL_TO, + + /** Filter cells not equal to a value. */ + LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + + /** Filter cells greater than a value. */ + LXW_FILTER_CRITERIA_GREATER_THAN, + + /** Filter cells less than a value. */ + LXW_FILTER_CRITERIA_LESS_THAN, + + /** Filter cells greater than or equal to a value. */ + LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO, + + /** Filter cells less than or equal to a value. */ + LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO, + + /** Filter cells that are blank. */ + LXW_FILTER_CRITERIA_BLANKS, + + /** Filter cells that are not blank. */ + LXW_FILTER_CRITERIA_NON_BLANKS +}; + +enum lxw_filter_operator { + LXW_FILTER_AND, + + LXW_FILTER_OR +}; + +enum lxw_filter_type { + LXW_FILTER_TYPE_NONE, + + LXW_FILTER_TYPE_SINGLE, + + LXW_FILTER_TYPE_AND, + + LXW_FILTER_TYPE_OR, + + LXW_FILTER_TYPE_STRING_LIST +}; + /** Options to control the positioning of worksheet objects such as images * or charts. See @ref working_with_object_positioning. */ enum lxw_object_position { @@ -772,6 +822,7 @@ typedef struct lxw_print_area { typedef struct lxw_autofilter { uint8_t in_use; + uint8_t has_rules; lxw_row_t first_row; lxw_row_t last_row; lxw_col_t first_col; @@ -1262,6 +1313,32 @@ typedef struct lxw_cond_format_hash_element { RB_ENTRY (lxw_cond_format_hash_element) tree_pointers; } lxw_cond_format_hash_element; +typedef struct lxw_filter_rule { + + uint8_t criteria; + double value; + char *value_string; +} lxw_filter_rule; + +typedef struct lxw_filter_rule_obj { + + uint8_t type; + uint8_t is_custom; + uint8_t has_blanks; + lxw_col_t col_num; + + uint8_t criteria1; + uint8_t criteria2; + double value1; + double value2; + char *value1_string; + char *value2_string; + + uint16_t num_list_filters; + char **list; + +} lxw_filter_rule_obj; + /** * @brief Options for inserted images. * @@ -1801,6 +1878,9 @@ typedef struct lxw_worksheet { lxw_object_properties *footer_right_object_props; lxw_object_properties *background_image; + lxw_filter_rule_obj **filter_rules; + lxw_col_t num_filter_rules; + STAILQ_ENTRY (lxw_worksheet) list_pointers; } lxw_worksheet; @@ -3529,6 +3609,16 @@ lxw_error worksheet_autofilter(lxw_worksheet *worksheet, lxw_row_t first_row, lxw_col_t first_col, lxw_row_t last_row, lxw_col_t last_col); +lxw_error worksheet_filter_column(lxw_worksheet *worksheet, lxw_col_t col, + lxw_filter_rule *rule); + +lxw_error worksheet_filter_column2(lxw_worksheet *worksheet, lxw_col_t col, + lxw_filter_rule *rule1, + lxw_filter_rule *rule2, uint8_t operator); + +lxw_error worksheet_filter_list(lxw_worksheet *worksheet, lxw_col_t col, + char **list); + /** * @brief Add a data validation to a cell. * @@ -5124,6 +5214,8 @@ STATIC void _worksheet_write_data_validations(lxw_worksheet *self); STATIC double _pixels_to_height(double pixels); STATIC double _pixels_to_width(double pixels); + +STATIC void _worksheet_write_auto_filter(lxw_worksheet *worksheet); #endif /* TESTING */ /* *INDENT-OFF* */ diff --git a/src/worksheet.c b/src/worksheet.c index 385d6cd4..8bc03463 100644 --- a/src/worksheet.c +++ b/src/worksheet.c @@ -298,6 +298,47 @@ _free_vml_object(lxw_vml_obj *vml_obj) free(vml_obj); } +/* + * Free autofilter rule object. + */ +STATIC void +_free_filter_rule(lxw_filter_rule_obj *rule_obj) +{ + uint16_t i; + + if (!rule_obj) + return; + + free(rule_obj->value1_string); + free(rule_obj->value2_string); + + if (rule_obj->list) { + for (i = 0; i < rule_obj->num_list_filters; i++) + free(rule_obj->list[i]); + + free(rule_obj->list); + } + + free(rule_obj); +} + +/* + * Free autofilter rules. + */ +STATIC void +_free_filter_rules(lxw_worksheet *worksheet) +{ + uint16_t i; + + if (!worksheet->filter_rules) + return; + + for (i = 0; i < worksheet->num_filter_rules; i++) + _free_filter_rule(worksheet->filter_rules[i]); + + free(worksheet->filter_rules); +} + /* * Free a worksheet cell. */ @@ -643,6 +684,8 @@ lxw_worksheet_free(lxw_worksheet *worksheet) _free_relationship(worksheet->external_vml_header_link); _free_relationship(worksheet->external_background_link); + _free_filter_rules(worksheet); + if (worksheet->array) { for (col = 0; col < LXW_COL_MAX; col++) { _free_cell(worksheet->array[col]); @@ -1403,6 +1446,36 @@ _pixels_to_height(double pixels) return pixels * 0.75; } +/* Check and set if an autofilter is a standard or custom filter. */ +void +set_custom_filter(lxw_filter_rule_obj *rule_obj) +{ + rule_obj->is_custom = LXW_TRUE; + + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_EQUAL_TO) + rule_obj->is_custom = LXW_FALSE; + + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_BLANKS) + rule_obj->is_custom = LXW_FALSE; + + if (rule_obj->criteria2 != LXW_FILTER_CRITERIA_NONE) { + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_EQUAL_TO) + rule_obj->is_custom = LXW_FALSE; + + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_BLANKS) + rule_obj->is_custom = LXW_FALSE; + + if (rule_obj->type == LXW_FILTER_TYPE_AND) + rule_obj->is_custom = LXW_TRUE; + } + + if (rule_obj->value1_string && strpbrk(rule_obj->value1_string, "*?")) + rule_obj->is_custom = LXW_TRUE; + + if (rule_obj->value2_string && strpbrk(rule_obj->value2_string, "*?")) + rule_obj->is_custom = LXW_TRUE; +} + /***************************************************************************** * * XML functions. @@ -4460,6 +4533,195 @@ _worksheet_write_col_breaks(lxw_worksheet *self) LXW_FREE_ATTRIBUTES(); } +/* + * Write the element. + */ +STATIC void +_worksheet_write_filter(lxw_worksheet *self, char *str, double num, + uint8_t operator) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + + if (operator == LXW_FILTER_CRITERIA_BLANKS) + return; + + LXW_INIT_ATTRIBUTES(); + + if (str) + LXW_PUSH_ATTRIBUTES_STR("val", str); + else + LXW_PUSH_ATTRIBUTES_DBL("val", num); + + lxw_xml_empty_tag(self->file, "filter", &attributes); + + LXW_FREE_ATTRIBUTES(); +} + +/* + * Write the element as simple equality. + */ +STATIC void +_worksheet_write_filter_standard(lxw_worksheet *self, + lxw_filter_rule_obj *filter) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + + LXW_INIT_ATTRIBUTES(); + + if (filter->has_blanks) { + LXW_PUSH_ATTRIBUTES_STR("blank", "1"); + } + + if (filter->type == LXW_FILTER_TYPE_SINGLE && filter->has_blanks) { + lxw_xml_empty_tag(self->file, "filters", &attributes); + + } + else { + lxw_xml_start_tag(self->file, "filters", &attributes); + + /* Write the filter element. */ + if (filter->type == LXW_FILTER_TYPE_SINGLE) { + _worksheet_write_filter(self, filter->value1_string, + filter->value1, filter->criteria1); + } + else if (filter->type == LXW_FILTER_TYPE_AND + || filter->type == LXW_FILTER_TYPE_OR) { + _worksheet_write_filter(self, filter->value1_string, + filter->value1, filter->criteria1); + _worksheet_write_filter(self, filter->value2_string, + filter->value2, filter->criteria2); + } + + lxw_xml_end_tag(self->file, "filters"); + } +} + +/* + * Write the element. + */ +STATIC void +_worksheet_write_custom_filter(lxw_worksheet *self, char *str, double num, + uint8_t operator) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + + LXW_INIT_ATTRIBUTES(); + + if (operator == LXW_FILTER_CRITERIA_NOT_EQUAL_TO) + LXW_PUSH_ATTRIBUTES_STR("operator", "notEqual"); + if (operator == LXW_FILTER_CRITERIA_GREATER_THAN) + LXW_PUSH_ATTRIBUTES_STR("operator", "greaterThan"); + else if (operator == LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO) + LXW_PUSH_ATTRIBUTES_STR("operator", "greaterThanOrEqual"); + else if (operator == LXW_FILTER_CRITERIA_LESS_THAN) + LXW_PUSH_ATTRIBUTES_STR("operator", "lessThan"); + else if (operator == LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO) + LXW_PUSH_ATTRIBUTES_STR("operator", "lessThanOrEqual"); + + if (str) + LXW_PUSH_ATTRIBUTES_STR("val", str); + else + LXW_PUSH_ATTRIBUTES_DBL("val", num); + + lxw_xml_empty_tag(self->file, "customFilter", &attributes); + + LXW_FREE_ATTRIBUTES(); +} + +/* + * Write the element as a list. + */ +STATIC void +_worksheet_write_filter_list(lxw_worksheet *self, lxw_filter_rule_obj *filter) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + uint16_t i; + + LXW_INIT_ATTRIBUTES(); + + if (filter->has_blanks) { + LXW_PUSH_ATTRIBUTES_STR("blank", "1"); + } + + lxw_xml_start_tag(self->file, "filters", &attributes); + + for (i = 0; i < filter->num_list_filters; i++) { + _worksheet_write_filter(self, filter->list[i], 0, 0); + } + + lxw_xml_end_tag(self->file, "filters"); + +} + +/* + * Write the element. + */ +STATIC void +_worksheet_write_filter_custom(lxw_worksheet *self, + lxw_filter_rule_obj *filter) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + + LXW_INIT_ATTRIBUTES(); + + if (filter->type == LXW_FILTER_TYPE_AND) + LXW_PUSH_ATTRIBUTES_STR("and", "1"); + + lxw_xml_start_tag(self->file, "customFilters", &attributes); + + /* Write the filter element. */ + if (filter->type == LXW_FILTER_TYPE_SINGLE) { + _worksheet_write_custom_filter(self, filter->value1_string, + filter->value1, filter->criteria1); + } + else if (filter->type == LXW_FILTER_TYPE_AND + || filter->type == LXW_FILTER_TYPE_OR) { + _worksheet_write_custom_filter(self, filter->value1_string, + filter->value1, filter->criteria1); + _worksheet_write_custom_filter(self, filter->value2_string, + filter->value2, filter->criteria2); + } + + lxw_xml_end_tag(self->file, "customFilters"); + + LXW_FREE_ATTRIBUTES(); +} + +/* + * Write the element. + */ +STATIC void +_worksheet_write_filter_column(lxw_worksheet *self, + lxw_filter_rule_obj *filter) +{ + struct xml_attribute_list attributes; + struct xml_attribute *attribute; + + if (!filter) + return; + + LXW_INIT_ATTRIBUTES(); + LXW_PUSH_ATTRIBUTES_INT("colId", filter->col_num); + + lxw_xml_start_tag(self->file, "filterColumn", &attributes); + + if (filter->list) + _worksheet_write_filter_list(self, filter); + else if (filter->is_custom) + _worksheet_write_filter_custom(self, filter); + else + _worksheet_write_filter_standard(self, filter); + + lxw_xml_end_tag(self->file, "filterColumn"); + + LXW_FREE_ATTRIBUTES(); +} + /* * Write the element. */ @@ -4469,6 +4731,7 @@ _worksheet_write_auto_filter(lxw_worksheet *self) struct xml_attribute_list attributes; struct xml_attribute *attribute; char range[LXW_MAX_CELL_RANGE_LENGTH]; + uint16_t i; if (!self->autofilter.in_use) return; @@ -4481,7 +4744,18 @@ _worksheet_write_auto_filter(lxw_worksheet *self) LXW_INIT_ATTRIBUTES(); LXW_PUSH_ATTRIBUTES_STR("ref", range); - lxw_xml_empty_tag(self->file, "autoFilter", &attributes); + if (self->autofilter.has_rules) { + lxw_xml_start_tag(self->file, "autoFilter", &attributes); + + for (i = 0; i < self->num_filter_rules; i++) + _worksheet_write_filter_column(self, self->filter_rules[i]); + + lxw_xml_end_tag(self->file, "autoFilter"); + + } + else { + lxw_xml_empty_tag(self->file, "autoFilter", &attributes); + } LXW_FREE_ATTRIBUTES(); } @@ -7987,10 +8261,8 @@ worksheet_autofilter(lxw_worksheet *self, lxw_row_t first_row, lxw_row_t tmp_row; lxw_col_t tmp_col; lxw_error err; - - /* Excel doesn't allow a single cell to be merged */ - if (first_row == last_row && first_col == last_col) - return LXW_ERROR_PARAMETER_VALIDATION; + lxw_filter_rule_obj **filter_rules; + lxw_col_t num_filter_rules; /* Swap last row/col with first row/col as necessary */ if (first_row > last_row) { @@ -8009,12 +8281,262 @@ worksheet_autofilter(lxw_worksheet *self, lxw_row_t first_row, if (err) return err; + /* Create a array to hold filter rules. */ + self->autofilter.in_use = LXW_FALSE; + self->autofilter.has_rules = LXW_FALSE; + _free_filter_rules(self); + num_filter_rules = last_col - first_col + 1; + filter_rules = calloc(num_filter_rules, sizeof(lxw_filter_rule_obj *)); + RETURN_ON_MEM_ERROR(filter_rules, LXW_ERROR_MEMORY_MALLOC_FAILED); + self->autofilter.in_use = LXW_TRUE; self->autofilter.first_row = first_row; self->autofilter.first_col = first_col; self->autofilter.last_row = last_row; self->autofilter.last_col = last_col; + self->filter_rules = filter_rules; + self->num_filter_rules = num_filter_rules; + + return LXW_NO_ERROR; +} + +/* + * Set a autofilter rule for a filter column. + */ +lxw_error +worksheet_filter_column(lxw_worksheet *self, lxw_col_t col, + lxw_filter_rule *rule) +{ + lxw_filter_rule_obj *rule_obj; + uint16_t rule_index; + + if (!rule) { + LXW_WARN("worksheet_filter_column(): rule parameter cannot be NULL"); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (self->autofilter.in_use == LXW_FALSE) { + LXW_WARN("worksheet_filter_column(): " + "Worksheet autofilter range hasn't been defined. " + "Use worksheet_autofilter() first."); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (col < self->autofilter.first_col || col > self->autofilter.last_col) { + LXW_WARN_FORMAT3("worksheet_filter_column(): " + "Column '%d' is outside autofilter range " + "'%d <= col <= %d'.", col, + self->autofilter.first_col, + self->autofilter.last_col); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + /* Free any previous rule in the column slot. */ + rule_index = col - self->autofilter.first_col; + _free_filter_rule(self->filter_rules[rule_index]); + + /* Create a new rule and copy user input. */ + rule_obj = calloc(1, sizeof(lxw_filter_rule_obj)); + RETURN_ON_MEM_ERROR(rule_obj, LXW_ERROR_MEMORY_MALLOC_FAILED); + + rule_obj->col_num = rule_index; + rule_obj->type = LXW_FILTER_TYPE_SINGLE; + rule_obj->criteria1 = rule->criteria; + rule_obj->value1 = rule->value; + + if (rule_obj->criteria1 != LXW_FILTER_CRITERIA_NON_BLANKS) { + rule_obj->value1_string = lxw_strdup(rule->value_string); + } + else { + rule_obj->criteria1 = LXW_FILTER_CRITERIA_NOT_EQUAL_TO; + rule_obj->value1_string = lxw_strdup(" "); + } + + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_BLANKS) + rule_obj->has_blanks = LXW_TRUE; + + set_custom_filter(rule_obj); + + self->filter_rules[rule_index] = rule_obj; + self->filter_on = LXW_TRUE; + self->autofilter.has_rules = LXW_TRUE; + + return LXW_NO_ERROR; +} + +/* + * Set two autofilter rules for a filter column. + */ +lxw_error +worksheet_filter_column2(lxw_worksheet *self, lxw_col_t col, + lxw_filter_rule *rule1, lxw_filter_rule *rule2, + uint8_t operator) +{ + lxw_filter_rule_obj *rule_obj; + uint16_t rule_index; + + if (!rule1 || !rule2) { + LXW_WARN("worksheet_filter_column2(): rule parameter cannot be NULL"); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (self->autofilter.in_use == LXW_FALSE) { + LXW_WARN("worksheet_filter_column2(): " + "Worksheet autofilter range hasn't been defined. " + "Use worksheet_autofilter() first."); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (col < self->autofilter.first_col || col > self->autofilter.last_col) { + LXW_WARN_FORMAT3("worksheet_filter_column2(): " + "Column '%d' is outside autofilter range " + "'%d <= col <= %d'.", col, + self->autofilter.first_col, + self->autofilter.last_col); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + /* Free any previous rule in the column slot. */ + rule_index = col - self->autofilter.first_col; + _free_filter_rule(self->filter_rules[rule_index]); + + /* Create a new rule and copy user input. */ + rule_obj = calloc(1, sizeof(lxw_filter_rule_obj)); + RETURN_ON_MEM_ERROR(rule_obj, LXW_ERROR_MEMORY_MALLOC_FAILED); + + if (operator == LXW_FILTER_AND) + rule_obj->type = LXW_FILTER_TYPE_AND; + else + rule_obj->type = LXW_FILTER_TYPE_OR; + + rule_obj->col_num = rule_index; + + rule_obj->criteria1 = rule1->criteria; + rule_obj->value1 = rule1->value; + + rule_obj->criteria2 = rule2->criteria; + rule_obj->value2 = rule2->value; + + if (rule_obj->criteria1 != LXW_FILTER_CRITERIA_NON_BLANKS) { + rule_obj->value1_string = lxw_strdup(rule1->value_string); + } + else { + rule_obj->criteria1 = LXW_FILTER_CRITERIA_NOT_EQUAL_TO; + rule_obj->value1_string = lxw_strdup(" "); + } + + if (rule_obj->criteria2 != LXW_FILTER_CRITERIA_NON_BLANKS) { + rule_obj->value2_string = lxw_strdup(rule2->value_string); + } + else { + rule_obj->criteria2 = LXW_FILTER_CRITERIA_NOT_EQUAL_TO; + rule_obj->value2_string = lxw_strdup(" "); + } + + if (rule_obj->criteria1 == LXW_FILTER_CRITERIA_BLANKS) + rule_obj->has_blanks = LXW_TRUE; + + if (rule_obj->criteria2 == LXW_FILTER_CRITERIA_BLANKS) + rule_obj->has_blanks = LXW_TRUE; + + set_custom_filter(rule_obj); + + self->filter_rules[rule_index] = rule_obj; + self->filter_on = LXW_TRUE; + self->autofilter.has_rules = LXW_TRUE; + + return LXW_NO_ERROR; +} + +/* + * Set two autofilter rules for a filter column. + */ +lxw_error +worksheet_filter_list(lxw_worksheet *self, lxw_col_t col, char **list) +{ + lxw_filter_rule_obj *rule_obj; + uint16_t rule_index; + uint8_t has_blanks = LXW_FALSE; + uint16_t num_filters = 0; + uint16_t input_list_index; + uint16_t rule_obj_list_index; + char *str; + char **tmp_list; + + if (!list) { + LXW_WARN("worksheet_filter_list(): list parameter cannot be NULL"); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (self->autofilter.in_use == LXW_FALSE) { + LXW_WARN("worksheet_filter_list(): " + "Worksheet autofilter range hasn't been defined. " + "Use worksheet_autofilter() first."); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + if (col < self->autofilter.first_col || col > self->autofilter.last_col) { + LXW_WARN_FORMAT3("worksheet_filter_list(): " + "Column '%d' is outside autofilter range " + "'%d <= col <= %d'.", col, + self->autofilter.first_col, + self->autofilter.last_col); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + /* Count the number of non "Blanks" strings in the input list. */ + input_list_index = 0; + while ((str = list[input_list_index]) != NULL) { + if (strncmp(str, "Blanks", 6) == 0) + has_blanks = LXW_TRUE; + else + num_filters++; + + input_list_index++; + } + + /* There should be at least one filter string. */ + if (num_filters == 0) { + LXW_WARN("worksheet_filter_list(): " + "list must have at least 1 non-blanks item."); + return LXW_ERROR_PARAMETER_VALIDATION; + } + + /* Free any previous rule in the column slot. */ + rule_index = col - self->autofilter.first_col; + _free_filter_rule(self->filter_rules[rule_index]); + + /* Create a new rule and copy user input. */ + rule_obj = calloc(1, sizeof(lxw_filter_rule_obj)); + RETURN_ON_MEM_ERROR(rule_obj, LXW_ERROR_MEMORY_MALLOC_FAILED); + + tmp_list = calloc(num_filters + 1, sizeof(char *)); + RETURN_ON_MEM_ERROR(tmp_list, LXW_ERROR_MEMORY_MALLOC_FAILED); + + /* Copy input list (without any "Blanks" command) to an internal list. */ + input_list_index = 0; + rule_obj_list_index = 0; + while ((str = list[input_list_index]) != NULL) { + if (strncmp(str, "Blanks", 6) != 0) { + tmp_list[rule_obj_list_index] = lxw_strdup(str); + rule_obj_list_index++; + } + + input_list_index++; + } + + rule_obj->list = tmp_list; + rule_obj->num_list_filters = num_filters; + rule_obj->is_custom = LXW_FALSE; + rule_obj->col_num = rule_index; + rule_obj->type = LXW_FILTER_TYPE_STRING_LIST; + rule_obj->has_blanks = has_blanks; + + self->filter_rules[rule_index] = rule_obj; + self->filter_on = LXW_TRUE; + self->autofilter.has_rules = LXW_TRUE; + return LXW_NO_ERROR; } diff --git a/test/functional/src/test_autofilter00.c b/test/functional/src/test_autofilter00.c index 816f07c3..9d84e5cf 100644 --- a/test/functional/src/test_autofilter00.c +++ b/test/functional/src/test_autofilter00.c @@ -87,7 +87,7 @@ int main() { for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); - worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); } diff --git a/test/functional/src/test_autofilter01.c b/test/functional/src/test_autofilter01.c index 1a98a38b..835d684f 100644 --- a/test/functional/src/test_autofilter01.c +++ b/test/functional/src/test_autofilter01.c @@ -87,7 +87,7 @@ int main() { for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); - worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); } diff --git a/test/functional/src/test_autofilter02.c b/test/functional/src/test_autofilter02.c new file mode 100644 index 00000000..310140a5 --- /dev/null +++ b/test/functional/src/test_autofilter02.c @@ -0,0 +1,114 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter02.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"South", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume" , NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter03.c b/test/functional/src/test_autofilter03.c new file mode 100644 index 00000000..7ec25fc3 --- /dev/null +++ b/test/functional/src/test_autofilter03.c @@ -0,0 +1,117 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter03.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"South", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume", NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0 || strcmp(data[i].region, "South") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "South"}; + + worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter04.c b/test/functional/src/test_autofilter04.c new file mode 100644 index 00000000..35eeb1b3 --- /dev/null +++ b/test/functional/src/test_autofilter04.c @@ -0,0 +1,122 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter04.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"South", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume" , NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0 && + data[i].volume > 3000 && data[i].volume < 8000) + { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN, + .value = 3000}; + + lxw_filter_rule filter_rule3 = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN, + .value = 8000}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + worksheet_filter_column2(worksheet, 2, &filter_rule2, &filter_rule3, LXW_FILTER_AND); + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter05.c b/test/functional/src/test_autofilter05.c new file mode 100644 index 00000000..25392680 --- /dev/null +++ b/test/functional/src/test_autofilter05.c @@ -0,0 +1,113 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter05.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume", NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_BLANKS}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter06.c b/test/functional/src/test_autofilter06.c new file mode 100644 index 00000000..efef2ff0 --- /dev/null +++ b/test/functional/src/test_autofilter06.c @@ -0,0 +1,113 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter06.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume", NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "") != 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NON_BLANKS}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter07.c b/test/functional/src/test_autofilter07.c new file mode 100644 index 00000000..c5191d4c --- /dev/null +++ b/test/functional/src/test_autofilter07.c @@ -0,0 +1,114 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter07.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"South", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 2, 3, "Region", NULL); + worksheet_write_string(worksheet, 2, 4, "Item", NULL); + worksheet_write_string(worksheet, 2, 5, "Volume" , NULL); + worksheet_write_string(worksheet, 2, 6, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 3, 3, data[i].region, NULL); + worksheet_write_string(worksheet, i + 3, 4, data[i].item, NULL); + worksheet_write_number(worksheet, i + 3, 5, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 3, 6, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 3, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 2, 3, 52, 6); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + worksheet_filter_column(worksheet, 3, &filter_rule1); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter08.c b/test/functional/src/test_autofilter08.c new file mode 100644 index 00000000..62e00bbf --- /dev/null +++ b/test/functional/src/test_autofilter08.c @@ -0,0 +1,117 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter08.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume" , NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "North") == 0 || strcmp(data[i].region, "") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "North"}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_BLANKS}; + + + worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter09.c b/test/functional/src/test_autofilter09.c new file mode 100644 index 00000000..95bbd03e --- /dev/null +++ b/test/functional/src/test_autofilter09.c @@ -0,0 +1,115 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter09.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume", NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0 || + strcmp(data[i].region, "North") == 0 || + strcmp(data[i].region, "South") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + char* list[] = {"East", "North", "South", NULL}; + + worksheet_filter_list(worksheet, 0, list); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter10.c b/test/functional/src/test_autofilter10.c new file mode 100644 index 00000000..9cef3e79 --- /dev/null +++ b/test/functional/src/test_autofilter10.c @@ -0,0 +1,116 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter10.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume", NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume , NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (strcmp(data[i].region, "East") == 0 || + strcmp(data[i].region, "North") == 0 || + strcmp(data[i].region, "South") == 0 || + strcmp(data[i].region, "") == 0) { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + char* list[] = {"East", "North", "South", "Blanks", NULL}; + + worksheet_filter_list(worksheet, 0, list); + + + return workbook_close(workbook); +} diff --git a/test/functional/src/test_autofilter11.c b/test/functional/src/test_autofilter11.c new file mode 100644 index 00000000..729dddf3 --- /dev/null +++ b/test/functional/src/test_autofilter11.c @@ -0,0 +1,116 @@ +/***************************************************************************** + * Test cases for libxlsxwriter. + * + * Test to compare output against Excel files. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "xlsxwriter.h" + +int main() { + + lxw_workbook *workbook = workbook_new("test_autofilter11.xlsx"); + lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); + uint16_t i; + + struct row { + char region[16]; + char item[16]; + int volume; + char month[16]; + }; + + struct row data[] = { + {"East", "Apple", 9000, "July" }, + {"East", "Apple", 5000, "July" }, + {"South", "Orange", 9000, "September" }, + {"North", "Apple", 2000, "November" }, + {"West", "Apple", 9000, "November" }, + {"South", "Pear", 7000, "October" }, + {"North", "Pear", 9000, "August" }, + {"West", "Orange", 1000, "December" }, + {"West", "Grape", 1000, "November" }, + {"South", "Pear", 10000, "April" }, + {"West", "Grape", 6000, "January" }, + {"South", "Orange", 3000, "May" }, + {"North", "Apple", 3000, "December" }, + {"South", "Apple", 7000, "February" }, + {"West", "Grape", 1000, "December" }, + {"East", "Grape", 8000, "February" }, + {"South", "Grape", 10000, "June" }, + {"West", "Pear", 7000, "December" }, + {"South", "Apple", 2000, "October" }, + {"East", "Grape", 7000, "December" }, + {"North", "Grape", 6000, "April" }, + {"East", "Pear", 8000, "February" }, + {"North", "Apple", 7000, "August" }, + {"North", "Orange", 7000, "July" }, + {"North", "Apple", 6000, "June" }, + {"South", "Grape", 8000, "September" }, + {"West", "Apple", 3000, "October" }, + {"South", "Orange", 10000, "November" }, + {"West", "Grape", 4000, "July" }, + {"North", "Orange", 5000, "August" }, + {"East", "Orange", 1000, "November" }, + {"East", "Orange", 4000, "October" }, + {"North", "Grape", 5000, "August" }, + {"East", "Apple", 1000, "December" }, + {"South", "Apple", 10000, "March" }, + {"East", "Grape", 7000, "October" }, + {"West", "Grape", 1000, "September" }, + {"East", "Grape", 10000, "October" }, + {"South", "Orange", 8000, "March" }, + {"North", "Apple", 4000, "July" }, + {"South", "Orange", 5000, "July" }, + {"West", "Apple", 4000, "June" }, + {"East", "Apple", 5000, "April" }, + {"North", "Pear", 3000, "August" }, + {"East", "Grape", 9000, "November" }, + {"North", "Orange", 8000, "October" }, + {"East", "Apple", 10000, "June" }, + {"South", "Pear", 1000, "December" }, + {"North", "Grape", 10000, "July" }, + {"East", "Grape", 6000, "February" } + }; + + + /* Write the column headers. */ + worksheet_write_string(worksheet, 0, 0, "Region", NULL); + worksheet_write_string(worksheet, 0, 1, "Item", NULL); + worksheet_write_string(worksheet, 0, 2, "Volume" , NULL); + worksheet_write_string(worksheet, 0, 3, "Month", NULL); + + + lxw_row_col_options hidden = {.hidden = LXW_TRUE}; + + + /* Write the row data. */ + for (i = 0; i < sizeof(data)/sizeof(struct row); i++) { + worksheet_write_string(worksheet, i + 1, 0, data[i].region, NULL); + worksheet_write_string(worksheet, i + 1, 1, data[i].item, NULL); + worksheet_write_number(worksheet, i + 1, 2, data[i].volume, NULL); + worksheet_write_string(worksheet, i + 1, 3, data[i].month, NULL); + + if (data[i].volume == 3000 || + data[i].volume == 5000 || + data[i].volume == 8000) + { + /* Row matches the filter, no further action required. */ + } + else { + /* We need to hide rows that don't match the filter. */ + worksheet_set_row_opt(worksheet, i + 1, LXW_DEF_ROW_HEIGHT, NULL, &hidden); + } + } + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + + char* list[] = {"3000", "5000", "8000", NULL}; + + worksheet_filter_list(worksheet, 2, list); + + return workbook_close(workbook); +} diff --git a/test/functional/test_autofilter.py b/test/functional/test_autofilter.py index ab604b6d..642000fb 100644 --- a/test/functional/test_autofilter.py +++ b/test/functional/test_autofilter.py @@ -19,4 +19,32 @@ class TestCompareXLSXFiles(base_test_class.XLSXBaseTest): def test_autofilter01(self): self.run_exe_test('test_autofilter01') - + def test_autofilter02(self): + self.run_exe_test('test_autofilter02') + + def test_autofilter03(self): + self.run_exe_test('test_autofilter03') + + def test_autofilter04(self): + self.run_exe_test('test_autofilter04') + + def test_autofilter05(self): + self.run_exe_test('test_autofilter05') + + def test_autofilter06(self): + self.run_exe_test('test_autofilter06') + + def test_autofilter07(self): + self.run_exe_test('test_autofilter07') + + def test_autofilter08(self): + self.run_exe_test('test_autofilter08') + + def test_autofilter09(self): + self.run_exe_test('test_autofilter09') + + def test_autofilter10(self): + self.run_exe_test('test_autofilter10') + + def test_autofilter11(self): + self.run_exe_test('test_autofilter11') diff --git a/test/functional/xlsx_files/autofilter02.xlsx b/test/functional/xlsx_files/autofilter02.xlsx new file mode 100644 index 00000000..30763080 Binary files /dev/null and b/test/functional/xlsx_files/autofilter02.xlsx differ diff --git a/test/functional/xlsx_files/autofilter03.xlsx b/test/functional/xlsx_files/autofilter03.xlsx new file mode 100644 index 00000000..01352905 Binary files /dev/null and b/test/functional/xlsx_files/autofilter03.xlsx differ diff --git a/test/functional/xlsx_files/autofilter04.xlsx b/test/functional/xlsx_files/autofilter04.xlsx new file mode 100644 index 00000000..e64282a3 Binary files /dev/null and b/test/functional/xlsx_files/autofilter04.xlsx differ diff --git a/test/functional/xlsx_files/autofilter05.xlsx b/test/functional/xlsx_files/autofilter05.xlsx new file mode 100644 index 00000000..ea0f6679 Binary files /dev/null and b/test/functional/xlsx_files/autofilter05.xlsx differ diff --git a/test/functional/xlsx_files/autofilter06.xlsx b/test/functional/xlsx_files/autofilter06.xlsx new file mode 100644 index 00000000..c498ae6a Binary files /dev/null and b/test/functional/xlsx_files/autofilter06.xlsx differ diff --git a/test/functional/xlsx_files/autofilter07.xlsx b/test/functional/xlsx_files/autofilter07.xlsx new file mode 100644 index 00000000..9392716d Binary files /dev/null and b/test/functional/xlsx_files/autofilter07.xlsx differ diff --git a/test/functional/xlsx_files/autofilter08.xlsx b/test/functional/xlsx_files/autofilter08.xlsx new file mode 100644 index 00000000..8e986e2d Binary files /dev/null and b/test/functional/xlsx_files/autofilter08.xlsx differ diff --git a/test/functional/xlsx_files/autofilter09.xlsx b/test/functional/xlsx_files/autofilter09.xlsx new file mode 100644 index 00000000..7bbfd1c2 Binary files /dev/null and b/test/functional/xlsx_files/autofilter09.xlsx differ diff --git a/test/functional/xlsx_files/autofilter10.xlsx b/test/functional/xlsx_files/autofilter10.xlsx new file mode 100644 index 00000000..ebc5379f Binary files /dev/null and b/test/functional/xlsx_files/autofilter10.xlsx differ diff --git a/test/functional/xlsx_files/autofilter11.xlsx b/test/functional/xlsx_files/autofilter11.xlsx new file mode 100644 index 00000000..72c49c54 Binary files /dev/null and b/test/functional/xlsx_files/autofilter11.xlsx differ diff --git a/test/unit/worksheet/test_worksheet_write_auto_filter.c b/test/unit/worksheet/test_worksheet_write_auto_filter.c new file mode 100644 index 00000000..381023bf --- /dev/null +++ b/test/unit/worksheet/test_worksheet_write_auto_filter.c @@ -0,0 +1,516 @@ +/* + * Tests for the libxlsxwriter library. + * + * Copyright 2014-2021, John McNamara, jmcnamara@cpan.org + * + */ + +#include "../ctest.h" +#include "../helper.h" + +#include "xlsxwriter/worksheet.h" + + +/* Test the _write_auto_filter() method with no filter. */ +CTEST(worksheet, write_write_auto_filter01) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter02) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter03) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "North"}; + + worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_OR); + + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter04) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "East"}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "North"}; + + worksheet_filter_column2(worksheet, 0, &filter_rule1, &filter_rule2, LXW_FILTER_AND); + + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter05) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + .value_string = "East"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter06) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "S*"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter07) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + .value_string = "S*"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter08) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "*h"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter09) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + .value_string = "*h"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter10) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value_string = "*o*"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter11) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + .value_string = "*r*"}; + + worksheet_filter_column(worksheet, 0, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter12) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_EQUAL_TO, + .value = 1000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter13) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_NOT_EQUAL_TO, + .value = 2000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter14) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN, + .value = 3000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter15) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO, + .value = 4000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter16) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN, + .value = 5000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter17) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO, + .value = 6000}; + + worksheet_filter_column(worksheet, 2, &filter_rule1); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter() method with a filter. */ +CTEST(worksheet, write_write_auto_filter18) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + lxw_filter_rule filter_rule1 = {.criteria = LXW_FILTER_CRITERIA_GREATER_THAN_OR_EQUAL_TO, + .value = 1000}; + + lxw_filter_rule filter_rule2 = {.criteria = LXW_FILTER_CRITERIA_LESS_THAN_OR_EQUAL_TO, + .value = 2000}; + + worksheet_filter_column2(worksheet, 2, &filter_rule1, &filter_rule2, LXW_FILTER_AND); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter_list() method with a filter. */ +CTEST(worksheet, write_write_auto_filter19) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + char* list[] = {"East", NULL}; + + worksheet_filter_list(worksheet, 0, list); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter_list() method with a filter. */ +CTEST(worksheet, write_write_auto_filter20) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + char* list[] = {"East", "North", NULL}; + + worksheet_filter_list(worksheet, 0, list); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} + + +/* Test the _write_auto_filter_list() method with a filter. */ +CTEST(worksheet, write_write_auto_filter21) { + char* got; + char exp[] = ""; + FILE* testfile = lxw_tmpfile(NULL); + + lxw_worksheet *worksheet = lxw_worksheet_new(NULL); + worksheet->file = testfile; + + worksheet_autofilter(worksheet, 0, 0, 50, 3); + + char* list[] = {"February", "January", "July", "June", NULL}; + + worksheet_filter_list(worksheet, 3, list); + + _worksheet_write_auto_filter(worksheet); + + RUN_XLSX_STREQ(exp, got); + + lxw_worksheet_free(worksheet); +} diff --git a/test_autofilter11.py b/test_autofilter11.py new file mode 100644 index 00000000..c0fc3668 --- /dev/null +++ b/test_autofilter11.py @@ -0,0 +1,83 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2021, John McNamara, jmcnamara@cpan.org +# + +from ..excel_comparison_test import ExcelComparisonTest +from ...workbook import Workbook + + +class TestCompareXLSXFiles(ExcelComparisonTest): + """ + Test file created by XlsxWriter against a file created by Excel. + + """ + + def setUp(self): + + self.set_filename('autofilter11.xlsx') + self.set_text_file('autofilter_data.txt') + + def test_create_file(self): + """ + Test the creation of a simple XlsxWriter file with an autofilter. + """ + + workbook = Workbook(self.got_filename) + worksheet = workbook.add_worksheet() + + # Set the autofilter. + worksheet.autofilter('A1:D51') + + # Add filter criteria. + worksheet.filter_column_list('C', [3000, 5000, 8000]) + + # Open a text file with autofilter example data. + textfile = open(self.txt_filename) + + # Read the headers from the first line of the input file. + headers = textfile.readline().strip("\n").split() + + # Write out the headers. + worksheet.write_row('A1', headers) + + # Start writing data after the headers. + row = 1 + + # Read the rest of the text file and write it to the worksheet. + for line in textfile: + + # Split the input data based on whitespace. + data = line.strip("\n").split() + + # Convert the number data from the text file. + for i, item in enumerate(data): + try: + data[i] = float(item) + except ValueError: + pass + + # Get some of the field data. + region = data[0] + volume = int(data[2]) + + # Check for rows that match the filter. + if volume == 3000 or volume == 5000 or volume == 8000: + # Row matches the filter, no further action required. + pass + else: + # We need to hide rows that don't match the filter. + worksheet.set_row(row, options={'hidden': True}) + + # Write out the row data. + worksheet.write_row(row, 0, data) + + # Move on to the next worksheet row. + row += 1 + + textfile.close() + workbook.close() + + self.assertExcelEqual() diff --git a/test_write_auto_filter.py b/test_write_auto_filter.py new file mode 100644 index 00000000..ebd4458b --- /dev/null +++ b/test_write_auto_filter.py @@ -0,0 +1,294 @@ +############################################################################### +# +# Tests for XlsxWriter. +# +# Copyright (c), 2013-2021, John McNamara, jmcnamara@cpan.org +# + +import unittest +from io import StringIO +from ...worksheet import Worksheet + + +class TestWriteAutoFilter(unittest.TestCase): + """ + Test the Worksheet _write_auto_filter() method. + + """ + + def setUp(self): + self.fh = StringIO() + self.worksheet = Worksheet() + self.worksheet._set_filehandle(self.fh) + self.worksheet.name = 'Sheet1' + self.worksheet.autofilter('A1:D51') + + def test_write_auto_filter_1(self): + """Test the _write_auto_filter() method""" + + self.worksheet._write_auto_filter() + + exp = """""" + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_2(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == East' + exp = """""" + + self.worksheet.filter_column(0, filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_3(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == East or x == North' + exp = """""" + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_4(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == East and x == North' + exp = """""" + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_5(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x != East' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_6(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == S*' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_7(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x != S*' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_8(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == *h' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_9(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x != *h' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_10(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x =~ *o*' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_11(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x !~ *r*' + exp = '' + + self.worksheet.filter_column('A', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_12(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x == 1000' + exp = '' + + self.worksheet.filter_column(2, filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_13(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x != 2000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_14(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x > 3000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_15(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x >= 4000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_16(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x < 5000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_17(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x <= 6000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_18(self): + """Test the _write_auto_filter() method""" + + filter_condition = 'x >= 1000 and x <= 2000' + exp = '' + + self.worksheet.filter_column('C', filter_condition) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_19(self): + """Test the _write_auto_filter() method""" + + matches = ['East'] + exp = '' + + self.worksheet.filter_column_list('A', matches) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_20(self): + """Test the _write_auto_filter() method""" + + matches = ['East', 'North'] + exp = '' + + self.worksheet.filter_column_list('A', matches) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp) + + def test_write_auto_filter_21(self): + """Test the _write_auto_filter() method""" + + matches = ['February', 'January', 'July', 'June'] + exp = '' + + self.worksheet.filter_column_list(3, matches) + self.worksheet._write_auto_filter() + + got = self.fh.getvalue() + + self.assertEqual(got, exp)