mirror of
https://github.com/google/pebble.git
synced 2025-03-19 10:31:21 +00:00
206 lines
6 KiB
C
206 lines
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 "util/iterator.h"
|
|
#include "utf8_test_data.h"
|
|
#include "applib/graphics/utf8.h"
|
|
|
|
#include "clar.h"
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
// Stubs
|
|
///////////////////////////////////////////////////////////
|
|
#include "stubs_logging.h"
|
|
#include "stubs_passert.h"
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Tests
|
|
|
|
void test_utf8_iterator__decode_test_string_empty(void) {
|
|
bool success = false;
|
|
utf8_get_bounds(&success, "");
|
|
cl_assert(success);
|
|
}
|
|
|
|
//! Decode ASCII char
|
|
void test_utf8_iterator__decode_test_single_codepoint_string_single_byte(void) {
|
|
// Mutable types
|
|
Iterator utf8_iter;
|
|
Utf8IterState utf8_iter_state;
|
|
|
|
// Immutable types
|
|
bool success = false;
|
|
const Utf8Bounds utf8_bounds = utf8_get_bounds(&success, "A");
|
|
cl_assert(utf8_bounds.end - utf8_bounds.start == 1);
|
|
cl_assert(success);
|
|
|
|
// Init mutable types
|
|
utf8_iter_init(&utf8_iter, &utf8_iter_state, &utf8_bounds, utf8_bounds.start);
|
|
|
|
// Tests
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
}
|
|
|
|
//! Decode multi-byte char
|
|
void test_utf8_iterator__decode_test_single_codepoint_string_multi_byte(void) {
|
|
// Mutable types
|
|
Iterator utf8_iter;
|
|
Utf8IterState utf8_iter_state;
|
|
|
|
// Immutable types
|
|
bool success = false;
|
|
const Utf8Bounds utf8_bounds = utf8_get_bounds(&success, "\xc3\xb0");
|
|
cl_assert(utf8_bounds.end - utf8_bounds.start == 2);
|
|
cl_assert(success);
|
|
|
|
// Init mutable types
|
|
utf8_iter_init(&utf8_iter, &utf8_iter_state, &utf8_bounds, utf8_bounds.start);
|
|
|
|
// Tests
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
}
|
|
|
|
void test_utf8_iterator__decode_valid_string(void) {
|
|
// Mutable types
|
|
Iterator utf8_iter;
|
|
Utf8IterState utf8_iter_state;
|
|
|
|
// Immutable types
|
|
bool success = false;
|
|
const Utf8Bounds utf8_bounds = utf8_get_bounds(&success, s_valid_test_string);
|
|
cl_assert(success);
|
|
|
|
const int NUM_VALID_CODEPOINTS = sizeof(s_valid_test_codepoints) / sizeof(uint32_t);
|
|
|
|
// Init mutable types
|
|
utf8_iter_init(&utf8_iter, &utf8_iter_state, &utf8_bounds, utf8_bounds.start);
|
|
|
|
// Tests
|
|
int i = 0;
|
|
do {
|
|
cl_assert(utf8_iter_state.current < utf8_bounds.end);
|
|
cl_assert(i < NUM_VALID_CODEPOINTS);
|
|
|
|
uint32_t decoded_codepoint = utf8_iter_state.codepoint;
|
|
uint32_t actual_codepoint = s_valid_test_codepoints[i];
|
|
|
|
cl_assert_equal_i(decoded_codepoint, actual_codepoint);
|
|
|
|
++i;
|
|
} while (iter_next(&utf8_iter));
|
|
cl_assert(!iter_next(&utf8_iter));
|
|
|
|
cl_assert(i == NUM_VALID_CODEPOINTS);
|
|
cl_assert(utf8_iter_state.current == utf8_bounds.end);
|
|
cl_assert(*utf8_iter_state.current == '\0');
|
|
cl_assert(utf8_iter_state.codepoint == 0);
|
|
}
|
|
|
|
void test_utf8_iterator__decode_valid_string_backwards(void) {
|
|
// Mutable types
|
|
Iterator utf8_iter;
|
|
Utf8IterState utf8_iter_state;
|
|
|
|
// Immutable types
|
|
bool success = false;
|
|
const Utf8Bounds utf8_bounds = utf8_get_bounds(&success, s_valid_test_string);
|
|
cl_assert(success);
|
|
|
|
const int NUM_VALID_CODEPOINTS = sizeof(s_valid_test_codepoints) / sizeof(uint32_t);
|
|
|
|
// Init mutable types
|
|
utf8_iter_init(&utf8_iter, &utf8_iter_state, &utf8_bounds, utf8_bounds.end);
|
|
|
|
// Tests
|
|
int i = sizeof(s_valid_test_codepoints) / sizeof(s_valid_test_codepoints[0]);
|
|
while (iter_prev(&utf8_iter)) {
|
|
cl_assert(utf8_iter_state.current >= utf8_bounds.start);
|
|
cl_assert(i > 0);
|
|
|
|
uint32_t decoded_codepoint = utf8_iter_state.codepoint;
|
|
uint32_t actual_codepoint = s_valid_test_codepoints[i - 1];
|
|
|
|
cl_assert_equal_i(decoded_codepoint, actual_codepoint);
|
|
--i;
|
|
};
|
|
|
|
cl_assert(i == 0);
|
|
cl_assert(utf8_iter_state.current == utf8_bounds.start);
|
|
cl_assert(utf8_iter_state.codepoint == 0);
|
|
}
|
|
|
|
static void *s_context;
|
|
|
|
static int s_each_count = 0;
|
|
|
|
static bool prv_each_codepoint(int index, Codepoint codepoint, void *context) {
|
|
static int s_index = 0;
|
|
static Codepoint s_codes[] = { 0xf0, 'a' };
|
|
cl_assert_equal_i(s_codes[index], codepoint);
|
|
cl_assert_equal_i(s_index++, index);
|
|
cl_assert_equal_p(context, &s_context);
|
|
s_each_count++;
|
|
return true;
|
|
}
|
|
|
|
void test_utf8_iterator__each_codepoint(void) {
|
|
void *context = &s_context;
|
|
const char *str = "\xc3\xb0" "a";
|
|
s_each_count = 0;
|
|
cl_assert_equal_b(utf8_each_codepoint(str, prv_each_codepoint, context), true);
|
|
cl_assert_equal_i(s_each_count, 2);
|
|
}
|
|
|
|
static bool prv_each_codepoint_break(int index, Codepoint codepoint, void *context) {
|
|
static int s_index = 0;
|
|
static Codepoint s_codes[] = { 'a', 'b', 'c', 'd', 'e' };
|
|
cl_assert_equal_i(s_index++, index);
|
|
cl_assert_equal_i(s_codes[index], codepoint);
|
|
cl_assert_equal_p(context, &s_context);
|
|
s_each_count++;
|
|
return (index != 2);
|
|
}
|
|
|
|
void test_utf8_iterator__each_codepoint_break(void) {
|
|
void *context = &s_context;
|
|
const char *str = "abcde";
|
|
s_each_count = 0;
|
|
cl_assert_equal_b(utf8_each_codepoint(str, prv_each_codepoint_break, context), true);
|
|
cl_assert_equal_i(s_each_count, 3);
|
|
}
|
|
|
|
void test_utf8_iterator__each_codepoint_invalid(void) {
|
|
void *context = &s_context;
|
|
const char *str = "\xc3\x28";
|
|
s_each_count = 0;
|
|
cl_assert_equal_b(utf8_each_codepoint(str, prv_each_codepoint, context), false);
|
|
cl_assert_equal_i(s_each_count, 0);
|
|
}
|
|
|
|
void test_utf8_iterator__each_codepoint_emptry_string(void) {
|
|
void *context = (void *)(uintptr_t)0x42;
|
|
const char *str = "";
|
|
s_each_count = 0;
|
|
cl_assert_equal_b(utf8_each_codepoint(str, prv_each_codepoint, context), true);
|
|
cl_assert_equal_i(s_each_count, 0);
|
|
}
|