pebble/tests/fw/ui/test_option_menu_window.c
2025-01-27 11:38:16 -08:00

228 lines
7.6 KiB
C

/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "applib/ui/option_menu_window.h"
#include "resource/resource.h"
#include "resource/resource_ids.auto.h"
#include "services/normal/timeline/timeline_resources.h"
#include "clar.h"
// Fakes
/////////////////////
#include "fake_app_state.h"
#include "fake_content_indicator.h"
#include "fake_graphics_context.h"
#include "fixtures/load_test_resources.h"
// Stubs
/////////////////////
#include "stubs_analytics.h"
#include "stubs_animation_timing.h"
#include "stubs_app_install_manager.h"
#include "stubs_app_state.h"
#include "stubs_app_timer.h"
#include "stubs_bootbits.h"
#include "stubs_buffer.h"
#include "stubs_click.h"
#include "stubs_compiled_with_legacy2_sdk.h"
#include "stubs_event_service_client.h"
#include "stubs_heap.h"
#include "stubs_logging.h"
#include "stubs_memory_layout.h"
#include "stubs_mutex.h"
#include "stubs_passert.h"
#include "stubs_pbl_malloc.h"
#include "stubs_pebble_tasks.h"
#include "stubs_print.h"
#include "stubs_process_manager.h"
#include "stubs_prompt.h"
#include "stubs_serial.h"
#include "stubs_shell_prefs.h"
#include "stubs_sleep.h"
#include "stubs_syscalls.h"
#include "stubs_task_watchdog.h"
#include "stubs_unobstructed_area.h"
#include "stubs_window_manager.h"
#include "stubs_window_stack.h"
// Setup and Teardown
////////////////////////////////////
typedef struct OptionMenuTestData {
OptionMenu option_menu;
} OptionMenuTestData;
OptionMenuTestData s_data;
void test_option_menu_window__initialize(void) {
fake_app_state_init();
load_system_resources_fixture();
s_data = (OptionMenuTestData) {};
rtc_set_time(3 * SECONDS_PER_DAY);
}
void test_option_menu_window__cleanup(void) {
}
// Helpers
//////////////////////
typedef struct MenuItemConfig {
const char *title;
const char *subtitle;
} MenuItemConfig;
typedef struct MenuConfig {
OptionMenuCallbacks callbacks;
const char *title;
size_t num_items;
MenuItemConfig *items;
OptionMenuContentType content_type;
bool icons_enabled;
} MenuConfig;
static uint16_t prv_menu_get_num_rows(OptionMenu *option_menu, void *context) {
return ((MenuConfig *)context)->num_items;
}
static void prv_menu_draw_row(OptionMenu *option_menu, GContext *ctx, const Layer *cell_layer,
const GRect *cell_frame, uint32_t row, bool selected, void *context) {
MenuConfig *data = context;
option_menu_system_draw_row(option_menu, ctx, cell_layer, cell_frame, data->items[row].title,
selected, context);
}
static void prv_create_menu_and_render(MenuConfig *config) {
option_menu_init(&s_data.option_menu);
const OptionMenuConfig option_menu_config = {
.title = config->title ?: "Option Menu",
.content_type = config->content_type,
.status_colors = { GColorWhite, GColorBlack },
.highlight_colors = { PBL_IF_COLOR_ELSE(GColorCobaltBlue, GColorBlack), GColorWhite },
.icons_enabled = config->icons_enabled,
};
option_menu_configure(&s_data.option_menu, &option_menu_config);
const OptionMenuCallbacks callbacks = {
.draw_row = config->callbacks.draw_row ?: prv_menu_draw_row,
.get_num_rows = config->callbacks.get_num_rows ?: prv_menu_get_num_rows,
.get_cell_height = config->callbacks.get_cell_height ?: NULL,
};
option_menu_set_callbacks(&s_data.option_menu, &callbacks, config);
window_set_on_screen(&s_data.option_menu.window, true, true);
window_render(&s_data.option_menu.window, fake_graphics_context_get_context());
}
// Tests
//////////////////////
// These tests test all permutations on all platforms even if the combination on the particular
// platform was not designed and thus does not appear pleasant. Make sure you are looking at the
// combination relevant to your use case when examining the unit test output of Option Menu.
void prv_create_menu_and_render_long_title(bool icons_enabled, const char *title,
bool special_height) {
prv_create_menu_and_render(&(MenuConfig) {
.title = title,
.content_type = special_height ? OptionMenuContentType_DoubleLine :
OptionMenuContentType_Default,
.num_items = 3,
.items = (MenuItemConfig[]) {
{
.title = "Allow All Notifications",
}, {
.title = "Allow Phone Calls Only",
}, {
.title = "Mute All Notifications",
}
},
.icons_enabled = icons_enabled,
});
}
void test_option_menu_window__long_title_default_height(void) {
prv_create_menu_and_render_long_title(false /* icons_enabled */, "Default Height",
false /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__long_title_default_height_icons(void) {
prv_create_menu_and_render_long_title(true /* icons_enabled */, "Default Height",
false /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__long_title_special_height(void) {
prv_create_menu_and_render_long_title(false /* icons_enabled */, "Special Height",
true /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__long_title_special_height_icons(void) {
prv_create_menu_and_render_long_title(true /* icons_enabled */, "Special Height",
true /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void prv_create_menu_and_render_short_title(bool icons_enabled, const char *title,
bool special_height) {
prv_create_menu_and_render(&(MenuConfig) {
.title = title,
.content_type = special_height ? OptionMenuContentType_SingleLine :
OptionMenuContentType_Default,
.num_items = 3,
.items = (MenuItemConfig[]) {
{
.title = "Smaller",
}, {
.title = "Default",
}, {
.title = "Larger",
}
},
.icons_enabled = icons_enabled,
});
}
void test_option_menu_window__short_title_default_height(void) {
prv_create_menu_and_render_short_title(false /* icons_enabled */, "Default Height",
false /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__short_title_default_height_icons(void) {
prv_create_menu_and_render_short_title(true /* icons_enabled */, "Default Height",
false /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__short_title_special_height(void) {
prv_create_menu_and_render_short_title(false /* icons_enabled */, "Special Height",
true /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}
void test_option_menu_window__short_title_special_height_icons(void) {
prv_create_menu_and_render_short_title(true /* icons_enabled */, "Special Height",
true /* special_height */);
FAKE_GRAPHICS_CONTEXT_CHECK_DEST_BITMAP_FILE();
}