mirror of
https://github.com/meekrosoft/fff
synced 2026-01-28 02:34:28 +01:00
Migrate build to CMake and standard github workflows
Replace makefiles with CMakeLists.txt. This will allow for IDE and platform agnostic builds of FFF. Update the CI for FFF to use github workflows which don't depend on MS VC. The workflow added will verify the pull requests sent to master buy running 'buildandtest' which mirrors the developer workflow. Signed-off-by: Yuval Peress <peress@google.com>
This commit is contained in:
48
examples/embedded_ui/src/UI.c
Normal file
48
examples/embedded_ui/src/UI.c
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "UI.h"
|
||||
#include "DISPLAY.h"
|
||||
#include "SYSTEM.h"
|
||||
#include <string.h>
|
||||
|
||||
static unsigned int missed_irq_counter;
|
||||
button_cbk_t button_cbk;
|
||||
|
||||
|
||||
void UI_init()
|
||||
{
|
||||
DISPLAY_init();
|
||||
SYSTEM_register_irq(UI_button_irq_handler, IRQ_GPIO_2);
|
||||
button_cbk = 0;
|
||||
missed_irq_counter = 0;
|
||||
}
|
||||
|
||||
unsigned int UI_get_missed_irqs()
|
||||
{
|
||||
return missed_irq_counter;
|
||||
}
|
||||
|
||||
void UI_button_irq_handler()
|
||||
{
|
||||
if(button_cbk)
|
||||
{
|
||||
button_cbk();
|
||||
}
|
||||
else
|
||||
{
|
||||
missed_irq_counter++;
|
||||
}
|
||||
}
|
||||
|
||||
void UI_register_button_cbk(button_cbk_t cbk)
|
||||
{
|
||||
button_cbk = cbk;
|
||||
}
|
||||
|
||||
void UI_write_line(char *line)
|
||||
{
|
||||
static char out[27];
|
||||
strncpy(out, line, 26);
|
||||
out[26] = '\0';
|
||||
if(DISPLAY_get_line_capacity() == DISPLAY_get_line_insert_index())
|
||||
DISPLAY_clear();
|
||||
DISPLAY_output(out);
|
||||
}
|
||||
183
examples/embedded_ui/src/UI_test_ansic.c
Normal file
183
examples/embedded_ui/src/UI_test_ansic.c
Normal file
@@ -0,0 +1,183 @@
|
||||
#include "UI.h"
|
||||
#include "fff.h"
|
||||
#include "SYSTEM.h"
|
||||
#include "DISPLAY.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Test Framework :-) */
|
||||
void setup();
|
||||
#define TEST_F(SUITE, NAME) void NAME()
|
||||
#define RUN_TEST(SUITE, TESTNAME) printf(" Running %s.%s: \n", #SUITE, #TESTNAME); setup(); TESTNAME(); printf(" SUCCESS\n");
|
||||
|
||||
DEFINE_FFF_GLOBALS;
|
||||
|
||||
/* SYSTEM.h */
|
||||
FAKE_VOID_FUNC2(SYSTEM_register_irq, irq_func_t, unsigned int);
|
||||
/* DISPLAY.h */
|
||||
FAKE_VOID_FUNC(DISPLAY_init);
|
||||
FAKE_VOID_FUNC(DISPLAY_clear);
|
||||
FAKE_VOID_FUNC(DISPLAY_output, char *);
|
||||
FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_capacity);
|
||||
FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_insert_index);
|
||||
|
||||
FAKE_VOID_FUNC0(button_press_cbk);
|
||||
|
||||
|
||||
|
||||
/* Initialializers called for every test */
|
||||
void setup()
|
||||
{
|
||||
RESET_FAKE(SYSTEM_register_irq);
|
||||
|
||||
RESET_FAKE(DISPLAY_init)
|
||||
RESET_FAKE(DISPLAY_clear)
|
||||
RESET_FAKE(DISPLAY_output)
|
||||
RESET_FAKE(DISPLAY_get_line_capacity)
|
||||
RESET_FAKE(DISPLAY_get_line_insert_index);
|
||||
|
||||
RESET_FAKE(button_press_cbk);
|
||||
|
||||
FFF_RESET_HISTORY();
|
||||
|
||||
DISPLAY_get_line_capacity_fake.return_val = 2;
|
||||
}
|
||||
|
||||
/* Tests go here */
|
||||
TEST_F(UITests, init_will_initialise_display)
|
||||
{
|
||||
UI_init();
|
||||
assert(DISPLAY_init_fake.call_count == 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, init_will_register_interrupt_gpio2)
|
||||
{
|
||||
UI_init();
|
||||
assert(SYSTEM_register_irq_fake.call_count == 1);
|
||||
assert(SYSTEM_register_irq_fake.arg0_val == UI_button_irq_handler);
|
||||
assert(SYSTEM_register_irq_fake.arg1_val == IRQ_GPIO_2);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_no_irq_then_missed_irq_counter_zero)
|
||||
{
|
||||
assert(UI_get_missed_irqs() == 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_no_handler_then_missed_irq_counter_one)
|
||||
{
|
||||
UI_button_irq_handler();
|
||||
assert(UI_get_missed_irqs() == 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero)
|
||||
{
|
||||
UI_init();
|
||||
UI_register_button_cbk(button_press_cbk);
|
||||
UI_button_irq_handler();
|
||||
assert(UI_get_missed_irqs() == 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_valid_callback_then_callback_called)
|
||||
{
|
||||
UI_register_button_cbk(button_press_cbk);
|
||||
UI_button_irq_handler();
|
||||
assert(button_press_cbk_fake.call_count == 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, write_line_outputs_lines_to_display)
|
||||
{
|
||||
char msg[] = "helloworld";
|
||||
UI_write_line(msg);
|
||||
assert(DISPLAY_output_fake.call_count == 1);
|
||||
assert(strncmp(DISPLAY_output_fake.arg0_val, msg, 26) == 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display)
|
||||
{
|
||||
DISPLAY_get_line_insert_index_fake.return_val = 2;
|
||||
char msg[] = "helloworld";
|
||||
|
||||
UI_write_line(msg);
|
||||
|
||||
assert(DISPLAY_clear_fake.call_count == 1);
|
||||
assert(DISPLAY_output_fake.call_count == 1);
|
||||
// Check the order of the calls: Don't care about the first two:
|
||||
// DISPLAY_get_line_capacity and DISPLAY_get_line_insert_index
|
||||
assert(fff.call_history_idx == 4);
|
||||
assert(fff.call_history[2] == (void *) DISPLAY_clear);
|
||||
assert(fff.call_history[3] == (void *) DISPLAY_output);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_empty_lines_write_line_doesnt_clear_screen)
|
||||
{
|
||||
// given
|
||||
DISPLAY_get_line_insert_index_fake.return_val = 1;
|
||||
char msg[] = "helloworld";
|
||||
// when
|
||||
UI_write_line(msg);
|
||||
// then
|
||||
assert(DISPLAY_clear_fake.call_count == 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_string_longer_than_26_then_truncated_string_output)
|
||||
{
|
||||
// given
|
||||
char input[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
char expected[] = "abcdefghijklmnopqrstuvwxyz";
|
||||
// when
|
||||
UI_write_line(input);
|
||||
// then
|
||||
assert(strncmp(expected, DISPLAY_output_fake.arg0_val, 37) == 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_outputting_to_full_display_then_previous_inserted)
|
||||
{
|
||||
// given
|
||||
DISPLAY_get_line_insert_index_fake.return_val = 1;
|
||||
char oldest[] = "oldest";
|
||||
char newest[] = "newest";
|
||||
// when
|
||||
UI_write_line(oldest);
|
||||
UI_write_line(newest);
|
||||
// then
|
||||
|
||||
assert(DISPLAY_output_fake.call_count == 2);
|
||||
|
||||
// fills last line
|
||||
assert(strncmp(oldest, DISPLAY_output_fake.arg0_history[0], 37) == 0);
|
||||
//clears
|
||||
assert(DISPLAY_clear_fake.call_count == 1);
|
||||
// inserts old line at first
|
||||
assert(strncmp(oldest, DISPLAY_output_fake.arg0_history[1], 37) == 0);
|
||||
// then inserts new line
|
||||
assert(strncmp(newest, DISPLAY_output_fake.arg0_history[2], 37) == 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
setbuf(stdout, NULL);
|
||||
fprintf(stdout, "-------------\n");
|
||||
fprintf(stdout, "Running Tests\n");
|
||||
fprintf(stdout, "-------------\n\n");
|
||||
fflush(0);
|
||||
|
||||
/* Run tests */
|
||||
RUN_TEST(UITests, init_will_initialise_display);
|
||||
RUN_TEST(UITests, init_will_register_interrupt_gpio2);
|
||||
RUN_TEST(UITests, when_no_irq_then_missed_irq_counter_zero);
|
||||
RUN_TEST(UITests, when_one_irq_and_no_handler_then_missed_irq_counter_one);
|
||||
RUN_TEST(UITests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero);
|
||||
RUN_TEST(UITests, when_one_irq_and_valid_callback_then_callback_called);
|
||||
RUN_TEST(UITests, write_line_outputs_lines_to_display);
|
||||
RUN_TEST(UITests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display);
|
||||
RUN_TEST(UITests, when_empty_lines_write_line_doesnt_clear_screen);
|
||||
RUN_TEST(UITests, when_string_longer_than_26_then_truncated_string_output);
|
||||
|
||||
printf("\n-------------\n");
|
||||
printf("Complete\n");
|
||||
printf("-------------\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
136
examples/embedded_ui/src/UI_test_cpp.cpp
Normal file
136
examples/embedded_ui/src/UI_test_cpp.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
extern "C"{
|
||||
#include "UI.h"
|
||||
#include "SYSTEM.h"
|
||||
#include "DISPLAY.h"
|
||||
}
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
|
||||
#include "fff.h"
|
||||
DEFINE_FFF_GLOBALS;
|
||||
|
||||
/* SYSTEM.h */
|
||||
FAKE_VOID_FUNC(SYSTEM_register_irq, irq_func_t, unsigned int);
|
||||
/* DISPLAY.h */
|
||||
FAKE_VOID_FUNC(DISPLAY_init);
|
||||
FAKE_VOID_FUNC(DISPLAY_clear);
|
||||
FAKE_VOID_FUNC(DISPLAY_output, char *);
|
||||
FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_capacity);
|
||||
FAKE_VALUE_FUNC(unsigned int, DISPLAY_get_line_insert_index);
|
||||
|
||||
FAKE_VOID_FUNC(button_press_cbk);
|
||||
|
||||
|
||||
class UITests : public testing::Test
|
||||
{
|
||||
public:
|
||||
|
||||
void SetUp()
|
||||
{
|
||||
// Register resets
|
||||
RESET_FAKE(SYSTEM_register_irq);
|
||||
|
||||
RESET_FAKE(DISPLAY_init)
|
||||
RESET_FAKE(DISPLAY_clear)
|
||||
RESET_FAKE(DISPLAY_output)
|
||||
RESET_FAKE(DISPLAY_get_line_capacity)
|
||||
RESET_FAKE(DISPLAY_get_line_insert_index);
|
||||
|
||||
RESET_FAKE(button_press_cbk);
|
||||
|
||||
FFF_RESET_HISTORY();
|
||||
// non default init
|
||||
DISPLAY_get_line_capacity_fake.return_val = 2;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* Tests go here */
|
||||
TEST_F(UITests, init_will_initialise_display)
|
||||
{
|
||||
UI_init();
|
||||
ASSERT_EQ(DISPLAY_init_fake.call_count, 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, init_will_register_interrupt_gpio2)
|
||||
{
|
||||
UI_init();
|
||||
ASSERT_EQ(SYSTEM_register_irq_fake.call_count, 1);
|
||||
ASSERT_EQ((void *)SYSTEM_register_irq_fake.arg0_val, (void *)UI_button_irq_handler);
|
||||
ASSERT_EQ(SYSTEM_register_irq_fake.arg1_val, IRQ_GPIO_2);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_no_irq_then_missed_irq_counter_zero)
|
||||
{
|
||||
ASSERT_EQ(UI_get_missed_irqs(), 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_no_handler_then_missed_irq_counter_one)
|
||||
{
|
||||
UI_button_irq_handler();
|
||||
ASSERT_EQ(UI_get_missed_irqs(), 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_valid_callback_then_missed_irq_counter_zero)
|
||||
{
|
||||
UI_init();
|
||||
UI_register_button_cbk(button_press_cbk);
|
||||
UI_button_irq_handler();
|
||||
ASSERT_EQ(UI_get_missed_irqs(), 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_one_irq_and_valid_callback_then_callback_called)
|
||||
{
|
||||
UI_register_button_cbk(button_press_cbk);
|
||||
UI_button_irq_handler();
|
||||
ASSERT_EQ(button_press_cbk_fake.call_count, 1);
|
||||
}
|
||||
|
||||
TEST_F(UITests, write_line_outputs_lines_to_display)
|
||||
{
|
||||
char msg[] = "helloworld";
|
||||
UI_write_line(msg);
|
||||
ASSERT_EQ(DISPLAY_output_fake.call_count, 1);
|
||||
ASSERT_EQ(strncmp(DISPLAY_output_fake.arg0_val, msg, 26), 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_no_empty_lines_write_line_clears_screen_and_outputs_lines_to_display)
|
||||
{
|
||||
DISPLAY_get_line_insert_index_fake.return_val = 2;
|
||||
char msg[] = "helloworld";
|
||||
|
||||
UI_write_line(msg);
|
||||
|
||||
ASSERT_EQ(DISPLAY_clear_fake.call_count, 1);
|
||||
ASSERT_EQ(DISPLAY_output_fake.call_count, 1);
|
||||
// Check the order of the calls: Don't care about the first two:
|
||||
// DISPLAY_get_line_capacity and DISPLAY_get_line_insert_index
|
||||
ASSERT_EQ(fff.call_history_idx, 4);
|
||||
ASSERT_EQ(fff.call_history[2], (void *) DISPLAY_clear);
|
||||
ASSERT_EQ(fff.call_history[3], (void *) DISPLAY_output);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_empty_lines_write_line_doesnt_clear_screen)
|
||||
{
|
||||
// given
|
||||
DISPLAY_get_line_insert_index_fake.return_val = 1;
|
||||
char msg[] = "helloworld";
|
||||
// when
|
||||
UI_write_line(msg);
|
||||
// then
|
||||
ASSERT_EQ(DISPLAY_clear_fake.call_count, 0);
|
||||
}
|
||||
|
||||
TEST_F(UITests, when_string_longer_than_26_then_truncated_string_output)
|
||||
{
|
||||
// given
|
||||
char input[] = "abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
char expected[] = "abcdefghijklmnopqrstuvwxyz";
|
||||
// when
|
||||
UI_write_line(input);
|
||||
// then
|
||||
ASSERT_EQ(strncmp(expected, DISPLAY_output_fake.arg0_val, 37), 0);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user