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

263 lines
8.1 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 "comm/ble/kernel_le_client/ams/ams_util.h"
#include "clar.h"
// Stubs
///////////////////////////////////////////////////////////
#include "stubs_logging.h"
// Helpers
///////////////////////////////////////////////////////////
static char s_results[10][32];
static uint32_t s_results_lengths[10];
static uint8_t s_results_count;
static uint32_t s_max_results_count;
static bool prv_result_callback(const char *value, uint32_t value_length,
uint32_t index, void *context) {
strcpy(s_results[s_results_count], value);
s_results_lengths[s_results_count] = value_length;
cl_assert_equal_i(index, s_results_count);
++s_results_count;
return (s_max_results_count > s_results_count);
}
// Tests
///////////////////////////////////////////////////////////
void test_ams_util__initialize(void) {
memset(s_results, 0, sizeof(s_results));
s_results_count = 0;
s_max_results_count = ~0;
}
void test_ams_util__cleanup(void) {
}
// ams_util_float_string_parse() tests
///////////////////////////////////////////////////////////
#define assert_float_parse(in, mul, succeeds, expected_result) \
{ \
const char *input = (const char *)in; \
const uint32_t input_length = input ? sizeof(in) : 0; \
const uint32_t multiplier = mul; \
int32_t result = 0; \
cl_assert_equal_b(succeeds, \
ams_util_float_string_parse((const char *)in, input_length, multiplier, &result)); \
if (succeeds) { \
cl_assert_equal_i(result, expected_result); \
} \
}
void test_ams_util__float_string_parse_negative_number(void) {
// "-1" * 3
assert_float_parse("-1", 3, true, -1 * 3);
}
void test_ams_util__float_string_parse_only_minus_sign(void) {
// "-" * 3
assert_float_parse("-", 3, false, 0);
}
void test_ams_util__float_string_parse_negative_number_nothing_before_separator(void) {
// "-.1" * 30
assert_float_parse("-.1", 30, true, -3);
}
void test_ams_util__float_string_parse_multiple_minusses(void) {
// "--.1" * 30
assert_float_parse("--.1", 30, false, 0);
}
void test_ams_util__float_string_parse_null(void) {
// NULL * 3
assert_float_parse(NULL, 3, false, 0);
}
void test_ams_util__float_string_parse_not_zero_terminated(void) {
uint8_t buffer[] = {'1'};
assert_float_parse(buffer, 3, true, 3);
}
void test_ams_util__float_string_parse_null_in_the_middle(void) {
uint8_t buffer[] = {'1', 0, '2'};
assert_float_parse(buffer, 3, true, 3);
}
void test_ams_util__float_string_parse_empty_string(void) {
// "" * 3
assert_float_parse("", 3, false, 0);
}
void test_ams_util__float_string_parse_not_a_number(void) {
// "hello" * 3
assert_float_parse("hello", 3, false, 0);
// " " * 3
assert_float_parse(" ", 3, false, 0);
}
void test_ams_util__float_string_parse_no_fraction(void) {
// "42" * 3
assert_float_parse("42", 3, true, 42 * 3);
}
void test_ams_util__float_string_parse_separator_but_no_fraction(void) {
// "21." * 3
assert_float_parse("21.", 3, true, 21 * 3);
}
void test_ams_util__float_string_parse_comma_decimal_separator(void) {
// "1.23456" * 3 is approx 3.7036800000000003, round up to 4
assert_float_parse("1,23456", 3, true, 4);
}
void test_ams_util__float_string_parse_period_decimal_separator(void) {
// "1.23456" * 3 is approx 3.7036800000000003, round up to 4
assert_float_parse("1.23456", 3, true, 4);
}
void test_ams_util__float_string_parse_round_down(void) {
// "0.74995" * 2 is approx 1.4999, round down to 1
assert_float_parse("0.74995", 2, true, 1);
}
void test_ams_util__float_string_parse_multiple_separators(void) {
// "1.2.2" * 3
assert_float_parse("1.2.2", 2, false, 0);
}
void test_ams_util__float_string_positive_multiplier(void) {
// "1.654321" * 33 is approx 54.592593, round up to 55
assert_float_parse("1.654321", 33, true, 55);
}
void test_ams_util__float_string_negative_multiplier(void) {
// "1.987622" * -33 is approx -65.591526, round to -66
assert_float_parse("1.987622", -33, true, -66);
}
void test_ams_util__float_string_parse_overflow_positive(void) {
// fails:
// "2147483648" * 1
assert_float_parse("2147483648", 1, false, 0);
// succeeds:
// "2147483647" * 1
assert_float_parse("2147483647", 1, true, 2147483647);
}
void test_ams_util__float_string_parse_overflow_negative(void) {
// fails:
// "-2147483649" * 1
assert_float_parse("-2147483649", 1, false, 0);
// succeeds:
// "-2147483648" * 1
assert_float_parse("-2147483648", 1, true, -2147483648);
assert_float_parse("2147483648", -1, true, -2147483648);
}
// ams_util_csv_parse() tests
///////////////////////////////////////////////////////////
#define assert_result(idx, val, len); \
cl_assert_equal_i(len, s_results_lengths[idx]); \
cl_assert_equal_i(memcmp(val, s_results[idx], len), 0);
void test_ams_util__csv_empty_string(void) {
const char empty_string[] = "";
const uint8_t count = ams_util_csv_parse(empty_string, sizeof(empty_string), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 1);
cl_assert_equal_i(count, 1);
cl_assert_equal_s(empty_string, s_results[0]);
}
void test_ams_util__csv_empty_values(void) {
const char one_value[] = ",";
const uint8_t count = ams_util_csv_parse(one_value, sizeof(one_value), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 2);
cl_assert_equal_i(count, 2);
assert_result(0, "", 0);
assert_result(1, "", 0);
}
void test_ams_util__csv_null(void) {
const uint8_t count = ams_util_csv_parse(NULL, 0, NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 0);
cl_assert_equal_i(count, 0);
}
void test_ams_util__csv_one_value(void) {
const char one_value[] = "A";
const uint8_t count = ams_util_csv_parse(one_value, sizeof(one_value), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 1);
cl_assert_equal_i(count, 1);
cl_assert_equal_s(one_value, s_results[0]);
}
void test_ams_util__csv_multiple_values(void) {
const char multi_values[] = "A,B,C";
const uint8_t count = ams_util_csv_parse(multi_values, sizeof(multi_values), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 3);
cl_assert_equal_i(count, 3);
assert_result(0, "A", 1);
assert_result(1, "B", 1);
assert_result(2, "C", 1);
}
void test_ams_util__csv_stop_after_one_value(void) {
const char multi_values[] = "A,B,C";
s_max_results_count = 1;
const uint8_t count = ams_util_csv_parse(multi_values, sizeof(multi_values), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 1);
cl_assert_equal_i(count, 1);
assert_result(0, "A", 1);
}
void test_ams_util__csv_null_in_the_middle(void) {
const char null_middle_value[] = "A\x00 BCD,1234";
cl_assert(sizeof(null_middle_value) > 2);
const uint8_t count = ams_util_csv_parse(null_middle_value, sizeof(null_middle_value), NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 1);
cl_assert_equal_i(count, 1);
assert_result(0, "A", 1);
}
void test_ams_util__csv_buffer_not_zero_terminated(void) {
const char one_value[] = "ABCDEF";
cl_assert(sizeof(one_value) > 2);
const uint8_t count = ams_util_csv_parse(one_value,
sizeof(one_value) - 1 /* omit zero teminator */, NULL,
prv_result_callback);
cl_assert_equal_i(s_results_count, 1);
cl_assert_equal_i(count, 1);
assert_result(0, "ABCDEF", 6);
}