mirror of
https://github.com/google/pebble.git
synced 2025-03-21 19:31:20 +00:00
296 lines
8.6 KiB
C
296 lines
8.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.
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include "applib/graphics/gtypes.h"
|
|
#include "applib/graphics/gcontext.h"
|
|
#include "applib/graphics/graphics_circle.h"
|
|
#include "applib/rockyjs/api/rocky_api_util.h"
|
|
#include "applib/tick_timer_service.h"
|
|
#include "applib/ui/layer.h"
|
|
|
|
#include "kernel/events.h"
|
|
#include "syscall/syscall.h"
|
|
|
|
#include <clar.h>
|
|
#include <util/attributes.h>
|
|
|
|
#include <string.h>
|
|
|
|
#define ASSERT_JS_GLOBAL_EQUALS_B(name, value) \
|
|
cl_assert_equal_i(prv_js_global_get_boolean(name), value);
|
|
|
|
#define ASSERT_JS_GLOBAL_EQUALS_I(name, value) \
|
|
cl_assert_equal_i(prv_js_global_get_double(name), value);
|
|
|
|
#define ASSERT_JS_GLOBAL_EQUALS_D(name, value) \
|
|
cl_assert_equal_d(prv_js_global_get_double(name), value);
|
|
|
|
#define ASSERT_JS_GLOBAL_EQUALS_S(name, value) \
|
|
do { \
|
|
char str_buffer[1024] = {}; \
|
|
prv_js_global_get_string(name, str_buffer, sizeof(str_buffer)); \
|
|
cl_assert_equal_s(str_buffer, value); \
|
|
} while(0)
|
|
|
|
#define JS_GLOBAL_GET_VALUE(name) \
|
|
prv_js_global_get_value(name)
|
|
|
|
#define ASSERT_JS_ERROR(error_value, expected_error_string) \
|
|
do { \
|
|
const bool expects_error = (expected_error_string) != NULL; \
|
|
const bool is_error = jerry_value_has_error_flag(error_value); \
|
|
if (is_error) { \
|
|
if (expects_error) { \
|
|
jerry_char_t buffer[100] = {0}; \
|
|
jerry_object_to_string_to_utf8_char_buffer(error_value, buffer, sizeof(buffer)); \
|
|
cl_assert_equal_s((char *)(expected_error_string), (char *)buffer); \
|
|
} else {\
|
|
rocky_log_exception("ASSERT_JS_ERROR", error_value); \
|
|
cl_fail("Error value while no error was expected!"); \
|
|
} \
|
|
} else { \
|
|
if (expects_error) { \
|
|
cl_fail("expected error during JS execution did not occur"); \
|
|
} \
|
|
} \
|
|
} while(0)
|
|
|
|
#define EXECUTE_SCRIPT_EXPECT_UNDEFINED(script) \
|
|
do { \
|
|
JS_VAR rv = jerry_eval((jerry_char_t *)script, \
|
|
strlen(script), \
|
|
false /* is_strict */); \
|
|
cl_assert_equal_b(true, jerry_value_is_undefined(rv)); \
|
|
} while(0)
|
|
|
|
|
|
#define EXECUTE_SCRIPT_EXPECT_ERROR(script, expected_error) \
|
|
do { \
|
|
JS_VAR rv = jerry_eval((jerry_char_t *)script, \
|
|
strlen(script), \
|
|
false /* is_strict */); \
|
|
ASSERT_JS_ERROR(rv, expected_error); \
|
|
} while(0)
|
|
|
|
#define EXECUTE_SCRIPT(script) EXECUTE_SCRIPT_EXPECT_ERROR((script), NULL)
|
|
|
|
#define EXECUTE_SCRIPT_AND_ASSERT_RV_EQUALS_S(script, expected_c_string) \
|
|
do { \
|
|
JS_VAR rv = jerry_eval((jerry_char_t *)script, \
|
|
strlen(script), false /* is_strict */); \
|
|
ASSERT_JS_ERROR(rv, NULL); \
|
|
JS_VAR rv_string = jerry_value_to_string(rv); \
|
|
jerry_size_t sz = jerry_get_utf8_string_size(rv_string); \
|
|
cl_assert(sz); \
|
|
jerry_char_t *buffer = malloc(sz + 1); \
|
|
memset(buffer, 0, sz + 1); \
|
|
cl_assert(buffer); \
|
|
cl_assert_equal_i(sz, jerry_string_to_utf8_char_buffer(rv_string, buffer, sz)); \
|
|
cl_assert_equal_s((char *)buffer, expected_c_string); \
|
|
free(buffer); \
|
|
} while(0)
|
|
|
|
#ifndef DO_NOT_STUB_LEGACY2
|
|
|
|
UNUSED bool process_manager_compiled_with_legacy2_sdk(void) {
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
UNUSED static jerry_value_t prv_js_global_get_value(char *name) {
|
|
JS_VAR global_obj = jerry_get_global_object();
|
|
cl_assert_equal_b(jerry_value_is_undefined(global_obj), false);
|
|
|
|
JS_VAR val = jerry_get_object_field(global_obj, name);
|
|
cl_assert_equal_b(jerry_value_is_undefined(val), false);
|
|
return jerry_acquire_value(val);
|
|
}
|
|
|
|
UNUSED static bool prv_js_global_get_boolean(char *name) {
|
|
JS_VAR val = prv_js_global_get_value(name);
|
|
cl_assert(jerry_value_is_boolean(val));
|
|
double rv = jerry_get_boolean_value(val);
|
|
return rv;
|
|
}
|
|
|
|
UNUSED static double prv_js_global_get_double(char *name) {
|
|
JS_VAR val = prv_js_global_get_value(name);
|
|
cl_assert(jerry_value_is_number(val));
|
|
double rv = jerry_get_number_value(val);
|
|
return rv;
|
|
}
|
|
|
|
UNUSED static void prv_js_global_get_string(char *name, char *buffer, size_t buffer_size) {
|
|
JS_VAR val = prv_js_global_get_value(name);
|
|
cl_assert(jerry_value_is_string(val));
|
|
ssize_t num_bytes = jerry_string_to_char_buffer(val, (jerry_char_t *)buffer, buffer_size);
|
|
cl_assert(num_bytes <= buffer_size);
|
|
}
|
|
|
|
void (*s_app_event_loop_callback)(void);
|
|
|
|
void app_event_loop_common(void) {
|
|
if (s_app_event_loop_callback) {
|
|
s_app_event_loop_callback();
|
|
}
|
|
}
|
|
|
|
#define cl_assert_equal_point(a, b) \
|
|
do { \
|
|
const GPoint __pt_a = (a); \
|
|
const GPoint __pt_b = (b); \
|
|
cl_assert_equal_i(__pt_a.x, __pt_b.x); \
|
|
cl_assert_equal_i(__pt_a.y, __pt_b.y); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_point_precise(a, b) \
|
|
do { \
|
|
const GPointPrecise __pt_a = (a); \
|
|
const GPointPrecise __pt_b = (b); \
|
|
cl_assert_equal_i(__pt_a.x.raw_value, __pt_b.x.raw_value); \
|
|
cl_assert_equal_i(__pt_a.y.raw_value, __pt_b.y.raw_value); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_vector_precise(a, b) \
|
|
do { \
|
|
const GVectorPrecise __a = (a); \
|
|
const GVectorPrecise __b = (b); \
|
|
cl_assert_equal_i(__a.dx.raw_value, __b.dx.raw_value); \
|
|
cl_assert_equal_i(__a.dy.raw_value, __b.dy.raw_value); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_size(a, b) \
|
|
do { \
|
|
const GSize __sz_a = (a); \
|
|
const GSize __sz_b = (b); \
|
|
cl_assert_equal_i(__sz_a.w, __sz_b.w); \
|
|
cl_assert_equal_i(__sz_a.h, __sz_b.h); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_size_precise(a, b) \
|
|
do { \
|
|
const GSizePrecise __sz_a = (a); \
|
|
const GSizePrecise __sz_b = (b); \
|
|
cl_assert_equal_i(__sz_a.w.raw_value, __sz_b.w.raw_value); \
|
|
cl_assert_equal_i(__sz_a.h.raw_value, __sz_b.h.raw_value); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_rect(a, b) \
|
|
do { \
|
|
const GRect __a = (a); \
|
|
const GRect __b = (b); \
|
|
cl_assert_equal_point(__a.origin, __b.origin); \
|
|
cl_assert_equal_size(__a.size, __b.size); \
|
|
} while(0)
|
|
|
|
#define cl_assert_equal_rect_precise(a, b) \
|
|
do { \
|
|
const GRectPrecise __a = (a); \
|
|
const GRectPrecise __b = (b); \
|
|
cl_assert_equal_point_precise(__a.origin, __b.origin); \
|
|
cl_assert_equal_size_precise(__a.size, __b.size); \
|
|
} while(0)
|
|
|
|
|
|
typedef struct {
|
|
union {
|
|
Layer *layer;
|
|
GContext *ctx;
|
|
};
|
|
union {
|
|
GColor color;
|
|
uint8_t width;
|
|
struct {
|
|
GPoint p0;
|
|
GPoint p1;
|
|
};
|
|
struct {
|
|
GPointPrecise pp0;
|
|
GPointPrecise pp1;
|
|
};
|
|
struct {
|
|
GPointPrecise center;
|
|
Fixed_S16_3 radius;
|
|
int32_t angle_start;
|
|
int32_t angle_end;
|
|
} draw_arc;
|
|
struct {
|
|
GRect rect;
|
|
uint16_t radius;
|
|
GCornerMask corner_mask;
|
|
};
|
|
struct {
|
|
GRectPrecise prect;
|
|
};
|
|
TimeUnits tick_units;
|
|
const char *font_key;
|
|
struct {
|
|
char text[200];
|
|
GRect box;
|
|
GColor color;
|
|
} draw_text;
|
|
struct {
|
|
char text[200];
|
|
GFont font;
|
|
GRect box;
|
|
GTextOverflowMode overflow_mode;
|
|
GTextAlignment alignment;
|
|
} max_used_size;
|
|
struct {
|
|
GPoint points[200];
|
|
size_t num_points;
|
|
} path;
|
|
struct {
|
|
GPointPrecise center;
|
|
Fixed_S16_3 radius_inner;
|
|
Fixed_S16_3 radius_outer;
|
|
int32_t angle_start;
|
|
int32_t angle_end;
|
|
} fill_radial_precise;
|
|
};
|
|
} MockCallRecording;
|
|
|
|
typedef struct {
|
|
int call_count;
|
|
MockCallRecording last_call;
|
|
} MockCallRecordings;
|
|
|
|
#define record_mock_call(var) \
|
|
var.call_count++; \
|
|
var.last_call = (MockCallRecording)
|
|
|
|
// Handy for poking at .js things when debugging a unit test with gdb, for example:
|
|
// (gdb) call js_eval("1 + 1")
|
|
// 2
|
|
// (gdb) call js_eval("Date()")
|
|
// Thu Jan 01 1970 00:00:00 GMT+00:00
|
|
void js_eval(const char *src) {
|
|
JS_VAR rv = jerry_eval((const jerry_char_t *)src, strlen(src), false);
|
|
char buf[256] = {};
|
|
jerry_object_to_string_to_utf8_char_buffer(rv, (jerry_char_t *)buf, sizeof(buf));
|
|
printf("%s\n", buf);
|
|
}
|
|
|
|
static void (*s_process_manager_callback)(void *data);
|
|
static void *s_process_manager_callback_data;
|
|
void sys_current_process_schedule_callback(CallbackEventCallback async_cb,
|
|
void *ctx) {
|
|
s_process_manager_callback = async_cb;
|
|
s_process_manager_callback_data = ctx;
|
|
}
|