aboutsummaryrefslogtreecommitdiffstats
path: root/quantum/visualizer/visualizer.c
blob: 3f182e74d8529b8e6fe8abe995234599e185c9db (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
/*
The MIT License (MIT)

Copyright (c) 2016 Fred Sundvik

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include "config.h"
#include "visualizer.h"
#include <string.h>
#ifdef PROTOCOL_CHIBIOS
#    include "ch.h"
#endif

#include "gfx.h"

#ifdef LCD_BACKLIGHT_ENABLE
#    include "lcd_backlight.h"
#endif

//#define DEBUG_VISUALIZER

#ifdef DEBUG_VISUALIZER
#    include "debug.h"
#else
#    include "nodebug.h"
#endif

#ifdef SERIAL_LINK_ENABLE
#    include "serial_link/protocol/transport.h"
#    include "serial_link/system/serial_link.h"
#endif

#include "action_util.h"

// Define this in config.h
#ifndef VISUALIZER_THREAD_PRIORITY
// The visualizer needs gfx thread priorities
#    define VISUALIZER_THREAD_PRIORITY (NORMAL_PRIORITY - 2)
#endif

static visualizer_keyboard_status_t current_status = {.layer         = 0xFFFFFFFF,
                                                      .default_layer = 0xFFFFFFFF,
                                                      .leds          = 0xFFFFFFFF,
#ifdef BACKLIGHT_ENABLE
                                                      .backlight_level = 0,
#endif
                                                      .mods      = 0xFF,
                                                      .suspended = false,
#ifdef VISUALIZER_USER_DATA_SIZE
                                                      .user_data = {0}
#endif
};

static bool same_status(visualizer_keyboard_status_t* status1, visualizer_keyboard_status_t* status2) {
    return status1->layer == status2->layer && status1->default_layer == status2->default_layer && status1->mods == status2->mods && status1->leds == status2->leds && status1->suspended == status2->suspended
#ifdef BACKLIGHT_ENABLE
           && status1->backlight_level == status2->backlight_level
#endif
#ifdef VISUALIZER_USER_DATA_SIZE
           && memcmp(status1->user_data, status2->user_data, VISUALIZER_USER_DATA_SIZE) == 0
#endif
        ;
}

static bool visualizer_enabled = false;

#ifdef VISUALIZER_USER_DATA_SIZE
static uint8_t user_data[VISUALIZER_USER_DATA_SIZE];
#endif

#define MAX_SIMULTANEOUS_ANIMATIONS 4
static keyframe_animation_t* animations[MAX_SIMULTANEOUS_ANIMATIONS] = {};

#ifdef SERIAL_LINK_ENABLE
MASTER_TO_ALL_SLAVES_OBJECT(current_status, visualizer_keyboard_status_t);

static remote_object_t* remote_objects[] = {
    REMOTE_OBJECT(current_status),
};

#endif

GDisplay* LCD_DISPLAY = 0;
GDisplay* LED_DISPLAY = 0;

#ifdef LCD_DISPLAY_NUMBER
__attribute__((weak)) GDisplay* get_lcd_display(void) { return gdispGetDisplay(LCD_DISPLAY_NUMBER); }
#endif

#ifdef LED_DISPLAY_NUMBER
__attribute__((weak)) GDisplay* get_led_display(void) { return gdispGetDisplay(LED_DISPLAY_NUMBER); }
#endif

void start_keyframe_animation(keyframe_animation_t* animation) {
    animation->current_frame      = -1;
    animation->time_left_in_frame = 0;
    animation->need_update        = true;
    int free_index                = -1;
    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) {
        if (animations[i] == animation) {
            return;
        }
        if (free_index == -1 && animations[i] == NULL) {
            free_index = i;
        }
    }
    if (free_index != -1) {
        animations[free_index] = animation;
    }
}

void stop_keyframe_animation(keyframe_animation_t* animation) {
    animation->current_frame         = animation->num_frames;
    animation->time_left_in_frame    = 0;
    animation->need_update           = true;
    animation->first_update_of_frame = false;
    animation->last_update_of_frame  = false;
    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) {
        if (animations[i] == animation) {
            animations[i] = NULL;
            return;
        }
    }
}

void stop_all_keyframe_animations(void) {
    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) {
        if (animations[i]) {
            animations[i]->current_frame         = animations[i]->num_frames;
            animations[i]->time_left_in_frame    = 0;
            animations[i]->need_update           = true;
            animations[i]->first_update_of_frame = false;
            animations[i]->last_update_of_frame  = false;
            animations[i]                        = NULL;
        }
    }
}

static uint8_t get_num_running_animations(void) {
    uint8_t count = 0;
    for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) {
        count += animations[i] ? 1 : 0;
    }
    return count;
}

static bool update_keyframe_animation(keyframe_animation_t* animation, visualizer_state_t* state, systemticks_t delta, systemticks_t* sleep_time) {
    // TODO: Clean up this messy code
    dprintf("Animation frame%d, left %d, delta %d\n", animation->current_frame, animation->time_left_in_frame, delta);
    if (animation->current_frame == animation->num_frames) {
        animation->need_update = false;
        return false;
    }
    if (animation->current_frame == -1) {
        animation->current_frame         = 0;
        animation->time_left_in_frame    = animation->frame_lengths[0];
        animation->need_update           = true;
        animation->first_update_of_frame = true;
    } else {
        animation->time_left_in_frame -= delta;
        while (animation->time_left_in_frame <= 0) {
            int left = animation->time_left_in_frame;
            if (animation->need_update) {
                animation->time_left_in_frame   = 0;
                animation->last_update_of_frame = true;
                (*animation->frame_functions[animation->current_frame])(animation, state);
                animation->last_update_of_frame = false;
            }
            animation->current_frame++;
            animation->need_update           = true;
            animation->first_update_of_frame = true;
            if (animation->current_frame == animation->num_frames) {
                if (animation->loop) {
                    animation->current_frame = 0;
                } else {
                    stop_keyframe_animation(animation);
                    return false;
                }
            }
            delta                         = -left;
            animation->time_left_in_frame = animation->frame_lengths[animation->current_frame];
            animation->time_left_in_frame -= delta;
        }
    }
    if (animation->need_update) {
        animation->need_update           = (*animation->frame_functions[animation->current_frame])(animation, state);
        animation->first_update_of_frame = false;
    }

    systemticks_t wanted_sleep = animation->need_update ? gfxMillisecondsToTicks(10) : (unsigned)animation->time_left_in_frame;
    if (wanted_sleep < *sleep_time) {
        *sleep_time = wanted_sleep;
    }

    return true;
}

void run_next_keyframe(keyframe_animation_t* animation, visualizer_state_t* state) {
    int next_frame = animation->current_frame + 1;
    if (next_frame == animation->num_frames) {
        next_frame = 0;
    }
    keyframe_animation_t temp_animation  = *animation;
    temp_animation.current_frame         = next_frame;
    temp_animation.time_left_in_frame    = animation->frame_lengths[next_frame];
    temp_animation.first_update_of_frame = true;
    temp_animation.last_update_of_frame  = false;
    temp_animation.need_update           = false;
    visualizer_state_t temp_state        = *state;
    (*temp_animation.frame_functions[next_frame])(&temp_animation, &temp_state);
}

// TODO: Optimize the stack size, this is probably way too big
static DECLARE_THREAD_STACK(visualizerThreadStack, 1024);
static DECLARE_THREAD_FUNCTION(visualizerThread, arg) {
    (void)arg;

    GListener event_listener;
    geventListenerInit(&event_listener);
    geventAttachSource(&event_listener, (GSourceHandle)&current_status, 0);

    visualizer_keyboard_status_t initial_status = {
        .default_layer = 0xFFFFFFFF,
        .layer         = 0xFFFFFFFF,
        .mods          = 0xFF,
        .leds          = 0xFFFFFFFF,
        .suspended     = false,
#ifdef BACKLIGHT_ENABLE
        .backlight_level = 0,
#endif
#ifdef VISUALIZER_USER_DATA_SIZE
        .user_data = {0},
#endif
    };

    visualizer_state_t state = {.status            = initial_status,
                                .current_lcd_color = 0,
#ifdef LCD_ENABLE
                                .font_fixed5x8         = gdispOpenFont("fixed_5x8"),
                                .font_dejavusansbold12 = gdispOpenFont("DejaVuSansBold12")
#endif
    };
    initialize_user_visualizer(&state);
    state.prev_lcd_color = state.current_lcd_color;

#ifdef LCD_BACKLIGHT_ENABLE
    lcd_backlight_color(LCD_HUE(state.current_lcd_color), LCD_SAT(state.current_lcd_color), LCD_INT(state.current_lcd_color));
#endif

    systemticks_t sleep_time   = TIME_INFINITE;
    systemticks_t current_time = gfxSystemTicks();
    bool          force_update = true;

    while (true) {
        systemticks_t new_time = gfxSystemTicks();
        systemticks_t delta    = new_time - current_time;
        current_time           = new_time;
        bool enabled           = visualizer_enabled;
        if (force_update || !same_status(&state.status, &current_status)) {
            force_update = false;
#if BACKLIGHT_ENABLE
            if (current_status.backlight_level != state.status.backlight_level) {
                if (current_status.backlight_level != 0) {
                    gdispGSetPowerMode(LED_DISPLAY, powerOn);
                    uint16_t percent = (uint16_t)current_status.backlight_level * 100 / BACKLIGHT_LEVELS;
                    gdispGSetBacklight(LED_DISPLAY, percent);
                } else {
                    gdispGSetPowerMode(LED_DISPLAY, powerOff);
                }
                state.status.backlight_level = current_status.backlight_level;
            }
#endif
            if (visualizer_enabled) {
                if (current_status.suspended) {
                    stop_all_keyframe_animations();
                    visualizer_enabled = false;
                    state.status       = current_status;
                    user_visualizer_suspend(&state);
                } else {
                    visualizer_keyboard_status_t prev_status = state.status;
                    state.status                             = current_status;
                    update_user_visualizer_state(&state, &prev_status);
                }
                state.prev_lcd_color = state.current_lcd_color;
            }
        }
        if (!enabled && state.status.suspended && current_status.suspended == false) {
            // Setting the status to the initial status will force an update
            // when the visualizer is enabled again
            state.status           = initial_status;
            state.status.suspended = false;
            stop_all_keyframe_animations();
            user_visualizer_resume(&state);
            state.prev_lcd_color = state.current_lcd_color;
        }
        sleep_time = TIME_INFINITE;
        for (int i = 0; i < MAX_SIMULTANEOUS_ANIMATIONS; i++) {
            if (animations[i]) {
                update_keyframe_animation(animations[i], &state, delta, &sleep_time);
            }
        }
#ifdef BACKLIGHT_ENABLE
        gdispGFlush(LED_DISPLAY);
#endif

#ifdef LCD_ENABLE
        gdispGFlush(LCD_DISPLAY);
#endif

#ifdef EMULATOR
        draw_emulator();
#endif
        // Enable the visualizer when the startup or the suspend animation has finished
        if (!visualizer_enabled && state.status.suspended == false && get_num_running_animations() == 0) {
            visualizer_enabled = true;
            force_update       = true;
            sleep_time         = 0;
        }

        systemticks_t after_update = gfxSystemTicks();
        unsigned      update_delta = after_update - current_time;
        if (sleep_time != TIME_INFINITE) {
            if (sleep_time > update_delta) {
                sleep_time -= update_delta;
            } else {
                sleep_time = 0;
            }
        }
        dprintf("Update took %d, last delta %d, sleep_time %d\n", update_delta, delta, sleep_time);
#ifdef PROTOCOL_CHIBIOS
        // The gEventWait function really takes milliseconds, even if the documentation says ticks.
        // Unfortunately there's no generic ugfx conversion from system time to milliseconds,
        // so let's do it in a platform dependent way.

        // On windows the system ticks is the same as milliseconds anyway
        if (sleep_time != TIME_INFINITE) {
            sleep_time = ST2MS(sleep_time);
        }
#endif
        geventEventWait(&event_listener, sleep_time);
    }
#ifdef LCD_ENABLE
    gdispCloseFont(state.font_fixed5x8);
    gdispCloseFont(state.font_dejavusansbold12);
#endif

    return 0;
}

void visualizer_init(void) {
    gfxInit();

#ifdef LCD_BACKLIGHT_ENABLE
    lcd_backlight_init();
#endif

#ifdef SERIAL_LINK_ENABLE
    add_remote_objects(remote_objects, sizeof(remote_objects) / sizeof(remote_object_t*));
#endif

#ifdef LCD_ENABLE
    LCD_DISPLAY = get_lcd_display();
#endif

#ifdef BACKLIGHT_ENABLE
    LED_DISPLAY = get_led_display();
#endif

    // We are using a low priority thread, the idea is to have it run only
    // when the main thread is sleeping during the matrix scanning
    gfxThreadCreate(visualizerThreadStack, sizeof(visualizerThreadStack), VISUALIZER_THREAD_PRIORITY, visualizerThread, NULL);
}

void update_status(bool changed) {
    if (changed) {
        GSourceListener* listener = geventGetSourceListener((GSourceHandle)&current_status, NULL);
        if (listener) {
            geventSendEvent(listener);
        }
    }
#ifdef SERIAL_LINK_ENABLE
    static systime_t last_update    = 0;
    systime_t        current_update = chVTGetSystemTimeX();
    systime_t        delta          = current_update - last_update;
    if (changed || delta > MS2ST(10)) {
        last_update                     = current_update;
        visualizer_keyboard_status_t* r = begin_write_current_status();
        *r                              = current_status;
        end_write_current_status();
    }
#endif
}

uint8_t visualizer_get_mods() {
    uint8_t mods = get_mods();

#ifndef NO_ACTION_ONESHOT
    if (!has_oneshot_mods_timed_out()) {
        mods |= get_oneshot_mods();
    }
#endif
    return mods;
}

#ifdef VISUALIZER_USER_DATA_SIZE
void visualizer_set_user_data(void* u) { memcpy(user_data, u, VISUALIZER_USER_DATA_SIZE); }
#endif

void visualizer_update(layer_state_t default_state, layer_state_t state, uint8_t mods, uint32_t leds) {
    // Note that there's a small race condition here, the thread could read
    // a state where one of these are set but not the other. But this should
    // not really matter as it will be fixed during the next loop step.
    // Alternatively a mutex could be used instead of the volatile variables

    bool changed = false;
#ifdef SERIAL_LINK_ENABLE
    if (is_serial_link_connected()) {
        visualizer_keyboard_status_t* new_status = read_current_status();
        if (new_status) {
            if (!same_status(&current_status, new_status)) {
                changed        = true;
                current_status = *new_status;
            }
        }
    } else {
#else
    {
#endif
        visualizer_keyboard_status_t new_status = {
            .layer         = state,
            .default_layer = default_state,
            .mods          = mods,
            .leds          = leds,
#ifdef BACKLIGHT_ENABLE
            .backlight_level = current_status.backlight_level,
#endif
            .suspended = current_status.suspended,
        };
#ifdef VISUALIZER_USER_DATA_SIZE
        memcpy(new_status.user_data, user_data, VISUALIZER_USER_DATA_SIZE);
#endif
        if (!same_status(&current_status, &new_status)) {
            changed        = true;
            current_status = new_status;
        }
    }
    update_status(changed);
}

void visualizer_suspend(void) {
    current_status.suspended = true;
    update_status(true);
}

void visualizer_resume(void) {
    current_status.suspended = false;
    update_status(true);
}

#ifdef BACKLIGHT_ENABLE
void backlight_set(uint8_t level) {
    current_status.backlight_level = level;
    update_status(true);
}
#endif
'>2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578
# Advanced googletest Topics

<!-- GOOGLETEST_CM0016 DO NOT DELETE -->

## Introduction

Now that you have read the [googletest Primer](primer.md) and learned how to
write tests using googletest, it's time to learn some new tricks. This document
will show you more assertions as well as how to construct complex failure
messages, propagate fatal failures, reuse and speed up your test fixtures, and
use various flags with your tests.

## More Assertions

This section covers some less frequently used, but still significant,
assertions.

### Explicit Success and Failure

These three assertions do not actually test a value or expression. Instead, they
generate a success or failure directly. Like the macros that actually perform a
test, you may stream a custom failure message into them.

```c++
SUCCEED();
```

Generates a success. This does **NOT** make the overall test succeed. A test is
considered successful only if none of its assertions fail during its execution.

NOTE: `SUCCEED()` is purely documentary and currently doesn't generate any
user-visible output. However, we may add `SUCCEED()` messages to googletest's
output in the future.

```c++
FAIL();
ADD_FAILURE();
ADD_FAILURE_AT("file_path", line_number);
```

`FAIL()` generates a fatal failure, while `ADD_FAILURE()` and `ADD_FAILURE_AT()`
generate a nonfatal failure. These are useful when control flow, rather than a
Boolean expression, determines the test's success or failure. For example, you
might want to write something like:

```c++
switch(expression) {
  case 1:
     ... some checks ...
  case 2:
     ... some other checks ...
  default:
     FAIL() << "We shouldn't get here.";
}
```

NOTE: you can only use `FAIL()` in functions that return `void`. See the
[Assertion Placement section](#assertion-placement) for more information.

### Exception Assertions

These are for verifying that a piece of code throws (or does not throw) an
exception of the given type:

Fatal assertion                            | Nonfatal assertion                         | Verifies
------------------------------------------ | ------------------------------------------ | --------
`ASSERT_THROW(statement, exception_type);` | `EXPECT_THROW(statement, exception_type);` | `statement` throws an exception of the given type
`ASSERT_ANY_THROW(statement);`             | `EXPECT_ANY_THROW(statement);`             | `statement` throws an exception of any type
`ASSERT_NO_THROW(statement);`              | `EXPECT_NO_THROW(statement);`              | `statement` doesn't throw any exception

Examples:

```c++
ASSERT_THROW(Foo(5), bar_exception);

EXPECT_NO_THROW({
  int n = 5;
  Bar(&n);
});
```

**Availability**: requires exceptions to be enabled in the build environment

### Predicate Assertions for Better Error Messages

Even though googletest has a rich set of assertions, they can never be complete,
as it's impossible (nor a good idea) to anticipate all scenarios a user might
run into. Therefore, sometimes a user has to use `EXPECT_TRUE()` to check a
complex expression, for lack of a better macro. This has the problem of not
showing you the values of the parts of the expression, making it hard to
understand what went wrong. As a workaround, some users choose to construct the
failure message by themselves, streaming it into `EXPECT_TRUE()`. However, this
is awkward especially when the expression has side-effects or is expensive to
evaluate.

googletest gives you three different options to solve this problem:

#### Using an Existing Boolean Function

If you already have a function or functor that returns `bool` (or a type that
can be implicitly converted to `bool`), you can use it in a *predicate
assertion* to get the function arguments printed for free:

<!-- mdformat off(github rendering does not support multiline tables) -->

| Fatal assertion                   | Nonfatal assertion                | Verifies                    |
| --------------------------------- | --------------------------------- | --------------------------- |
| `ASSERT_PRED1(pred1, val1)`       | `EXPECT_PRED1(pred1, val1)`       | `pred1(val1)` is true       |
| `ASSERT_PRED2(pred2, val1, val2)` | `EXPECT_PRED2(pred2, val1, val2)` | `pred2(val1, val2)` is true |
| `...`                             | `...`                             | `...`                       |

<!-- mdformat on-->
In the above, `predn` is an `n`-ary predicate function or functor, where `val1`,
`val2`, ..., and `valn` are its arguments. The assertion succeeds if the
predicate returns `true` when applied to the given arguments, and fails
otherwise. When the assertion fails, it prints the value of each argument. In
either case, the arguments are evaluated exactly once.

Here's an example. Given

```c++
// Returns true if m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }

const int a = 3;
const int b = 4;
const int c = 10;
```

the assertion

```c++
  EXPECT_PRED2(MutuallyPrime, a, b);
```

will succeed, while the assertion

```c++
  EXPECT_PRED2(MutuallyPrime, b, c);
```

will fail with the message

```none
MutuallyPrime(b, c) is false, where
b is 4
c is 10
```

> NOTE:
>
> 1.  If you see a compiler error "no matching function to call" when using
>     `ASSERT_PRED*` or `EXPECT_PRED*`, please see
>     [this](faq.md#the-compiler-complains-no-matching-function-to-call-when-i-use-assert-pred-how-do-i-fix-it)
>     for how to resolve it.

#### Using a Function That Returns an AssertionResult

While `EXPECT_PRED*()` and friends are handy for a quick job, the syntax is not
satisfactory: you have to use different macros for different arities, and it
feels more like Lisp than C++. The `::testing::AssertionResult` class solves
this problem.

An `AssertionResult` object represents the result of an assertion (whether it's
a success or a failure, and an associated message). You can create an
`AssertionResult` using one of these factory functions:

```c++
namespace testing {

// Returns an AssertionResult object to indicate that an assertion has
// succeeded.
AssertionResult AssertionSuccess();

// Returns an AssertionResult object to indicate that an assertion has
// failed.
AssertionResult AssertionFailure();

}
```

You can then use the `<<` operator to stream messages to the `AssertionResult`
object.

To provide more readable messages in Boolean assertions (e.g. `EXPECT_TRUE()`),
write a predicate function that returns `AssertionResult` instead of `bool`. For
example, if you define `IsEven()` as:

```c++
::testing::AssertionResult IsEven(int n) {
  if ((n % 2) == 0)
     return ::testing::AssertionSuccess();
  else
     return ::testing::AssertionFailure() << n << " is odd";
}
```

instead of:

```c++
bool IsEven(int n) {
  return (n % 2) == 0;
}
```

the failed assertion `EXPECT_TRUE(IsEven(Fib(4)))` will print:

```none
Value of: IsEven(Fib(4))
  Actual: false (3 is odd)
Expected: true
```

instead of a more opaque

```none
Value of: IsEven(Fib(4))
  Actual: false
Expected: true
```

If you want informative messages in `EXPECT_FALSE` and `ASSERT_FALSE` as well
(one third of Boolean assertions in the Google code base are negative ones), and
are fine with making the predicate slower in the success case, you can supply a
success message:

```c++
::testing::AssertionResult IsEven(int n) {
  if ((n % 2) == 0)
     return ::testing::AssertionSuccess() << n << " is even";
  else
     return ::testing::AssertionFailure() << n << " is odd";
}
```

Then the statement `EXPECT_FALSE(IsEven(Fib(6)))` will print

```none
  Value of: IsEven(Fib(6))
     Actual: true (8 is even)
  Expected: false
```

#### Using a Predicate-Formatter

If you find the default message generated by `(ASSERT|EXPECT)_PRED*` and
`(ASSERT|EXPECT)_(TRUE|FALSE)` unsatisfactory, or some arguments to your
predicate do not support streaming to `ostream`, you can instead use the
following *predicate-formatter assertions* to *fully* customize how the message
is formatted:

Fatal assertion                                  | Nonfatal assertion                               | Verifies
------------------------------------------------ | ------------------------------------------------ | --------
`ASSERT_PRED_FORMAT1(pred_format1, val1);`       | `EXPECT_PRED_FORMAT1(pred_format1, val1);`       | `pred_format1(val1)` is successful
`ASSERT_PRED_FORMAT2(pred_format2, val1, val2);` | `EXPECT_PRED_FORMAT2(pred_format2, val1, val2);` | `pred_format2(val1, val2)` is successful
`...`                                            | `...`                                            | ...

The difference between this and the previous group of macros is that instead of
a predicate, `(ASSERT|EXPECT)_PRED_FORMAT*` take a *predicate-formatter*
(`pred_formatn`), which is a function or functor with the signature:

```c++
::testing::AssertionResult PredicateFormattern(const char* expr1,
                                               const char* expr2,
                                               ...
                                               const char* exprn,
                                               T1 val1,
                                               T2 val2,
                                               ...
                                               Tn valn);
```

where `val1`, `val2`, ..., and `valn` are the values of the predicate arguments,
and `expr1`, `expr2`, ..., and `exprn` are the corresponding expressions as they
appear in the source code. The types `T1`, `T2`, ..., and `Tn` can be either
value types or reference types. For example, if an argument has type `Foo`, you
can declare it as either `Foo` or `const Foo&`, whichever is appropriate.

As an example, let's improve the failure message in `MutuallyPrime()`, which was
used with `EXPECT_PRED2()`:

```c++
// Returns the smallest prime common divisor of m and n,
// or 1 when m and n are mutually prime.
int SmallestPrimeCommonDivisor(int m, int n) { ... }

// A predicate-formatter for asserting that two integers are mutually prime.
::testing::AssertionResult AssertMutuallyPrime(const char* m_expr,
                                               const char* n_expr,
                                               int m,
                                               int n) {
  if (MutuallyPrime(m, n)) return ::testing::AssertionSuccess();

  return ::testing::AssertionFailure() << m_expr << " and " << n_expr
      << " (" << m << " and " << n << ") are not mutually prime, "
      << "as they have a common divisor " << SmallestPrimeCommonDivisor(m, n);
}
```

With this predicate-formatter, we can use

```c++
  EXPECT_PRED_FORMAT2(AssertMutuallyPrime, b, c);
```

to generate the message

```none
b and c (4 and 10) are not mutually prime, as they have a common divisor 2.
```

As you may have realized, many of the built-in assertions we introduced earlier
are special cases of `(EXPECT|ASSERT)_PRED_FORMAT*`. In fact, most of them are
indeed defined using `(EXPECT|ASSERT)_PRED_FORMAT*`.

### Floating-Point Comparison

Comparing floating-point numbers is tricky. Due to round-off errors, it is very
unlikely that two floating-points will match exactly. Therefore, `ASSERT_EQ` 's
naive comparison usually doesn't work. And since floating-points can have a wide
value range, no single fixed error bound works. It's better to compare by a
fixed relative error bound, except for values close to 0 due to the loss of
precision there.

In general, for floating-point comparison to make sense, the user needs to
carefully choose the error bound. If they don't want or care to, comparing in
terms of Units in the Last Place (ULPs) is a good default, and googletest
provides assertions to do this. Full details about ULPs are quite long; if you
want to learn more, see
[here](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).

#### Floating-Point Macros

<!-- mdformat off(github rendering does not support multiline tables) -->

| Fatal assertion                 | Nonfatal assertion              | Verifies                                 |
| ------------------------------- | ------------------------------- | ---------------------------------------- |
| `ASSERT_FLOAT_EQ(val1, val2);`  | `EXPECT_FLOAT_EQ(val1, val2);`  | the two `float` values are almost equal  |
| `ASSERT_DOUBLE_EQ(val1, val2);` | `EXPECT_DOUBLE_EQ(val1, val2);` | the two `double` values are almost equal |

<!-- mdformat on-->

By "almost equal" we mean the values are within 4 ULP's from each other.

The following assertions allow you to choose the acceptable error bound:

<!-- mdformat off(github rendering does not support multiline tables) -->

| Fatal assertion                       | Nonfatal assertion                    | Verifies                                                                         |
| ------------------------------------- | ------------------------------------- | -------------------------------------------------------------------------------- |
| `ASSERT_NEAR(val1, val2, abs_error);` | `EXPECT_NEAR(val1, val2, abs_error);` | the difference between `val1` and `val2` doesn't exceed the given absolute error |

<!-- mdformat on-->

#### Floating-Point Predicate-Format Functions

Some floating-point operations are useful, but not that often used. In order to
avoid an explosion of new macros, we provide them as predicate-format functions
that can be used in predicate assertion macros (e.g. `EXPECT_PRED_FORMAT2`,
etc).

```c++
EXPECT_PRED_FORMAT2(::testing::FloatLE, val1, val2);
EXPECT_PRED_FORMAT2(::testing::DoubleLE, val1, val2);
```

Verifies that `val1` is less than, or almost equal to, `val2`. You can replace
`EXPECT_PRED_FORMAT2` in the above table with `ASSERT_PRED_FORMAT2`.

### Asserting Using gMock Matchers

[gMock](../../googlemock) comes with a library of matchers for validating
arguments passed to mock objects. A gMock *matcher* is basically a predicate
that knows how to describe itself. It can be used in these assertion macros:

<!-- mdformat off(github rendering does not support multiline tables) -->

| Fatal assertion                | Nonfatal assertion             | Verifies              |
| ------------------------------ | ------------------------------ | --------------------- |
| `ASSERT_THAT(value, matcher);` | `EXPECT_THAT(value, matcher);` | value matches matcher |

<!-- mdformat on-->

For example, `StartsWith(prefix)` is a matcher that matches a string starting
with `prefix`, and you can write:

```c++
using ::testing::StartsWith;
...
    // Verifies that Foo() returns a string starting with "Hello".
    EXPECT_THAT(Foo(), StartsWith("Hello"));
```

Read this
[recipe](../../googlemock/docs/cook_book.md#using-matchers-in-googletest-assertions)
in the gMock Cookbook for more details.

gMock has a rich set of matchers. You can do many things googletest cannot do
alone with them. For a list of matchers gMock provides, read
[this](../../googlemock/docs/cook_book.md##using-matchers). It's easy to write
your [own matchers](../../googlemock/docs/cook_book.md#NewMatchers) too.

gMock is bundled with googletest, so you don't need to add any build dependency
in order to take advantage of this. Just include `"testing/base/public/gmock.h"`
and you're ready to go.

### More String Assertions

(Please read the [previous](#asserting-using-gmock-matchers) section first if
you haven't.)

You can use the gMock
[string matchers](../../googlemock/docs/cheat_sheet.md#string-matchers) with
`EXPECT_THAT()` or `ASSERT_THAT()` to do more string comparison tricks
(sub-string, prefix, suffix, regular expression, and etc). For example,

```c++
using ::testing::HasSubstr;
using ::testing::MatchesRegex;
...
  ASSERT_THAT(foo_string, HasSubstr("needle"));
  EXPECT_THAT(bar_string, MatchesRegex("\\w*\\d+"));
```

If the string contains a well-formed HTML or XML document, you can check whether
its DOM tree matches an
[XPath expression](http://www.w3.org/TR/xpath/#contents):

```c++
// Currently still in //template/prototemplate/testing:xpath_matcher
#include "template/prototemplate/testing/xpath_matcher.h"
using prototemplate::testing::MatchesXPath;
EXPECT_THAT(html_string, MatchesXPath("//a[text()='click here']"));
```

### Windows HRESULT assertions

These assertions test for `HRESULT` success or failure.

Fatal assertion                        | Nonfatal assertion                     | Verifies
-------------------------------------- | -------------------------------------- | --------
`ASSERT_HRESULT_SUCCEEDED(expression)` | `EXPECT_HRESULT_SUCCEEDED(expression)` | `expression` is a success `HRESULT`
`ASSERT_HRESULT_FAILED(expression)`    | `EXPECT_HRESULT_FAILED(expression)`    | `expression` is a failure `HRESULT`

The generated output contains the human-readable error message associated with
the `HRESULT` code returned by `expression`.

You might use them like this:

```c++
CComPtr<IShellDispatch2> shell;
ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application"));
CComVariant empty;
ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));
```

### Type Assertions

You can call the function

```c++
::testing::StaticAssertTypeEq<T1, T2>();
```

to assert that types `T1` and `T2` are the same. The function does nothing if
the assertion is satisfied. If the types are different, the function call will
fail to compile, the compiler error message will say that
`T1 and T2 are not the same type` and most likely (depending on the compiler)
show you the actual values of `T1` and `T2`. This is mainly useful inside
template code.

**Caveat**: When used inside a member function of a class template or a function
template, `StaticAssertTypeEq<T1, T2>()` is effective only if the function is
instantiated. For example, given:

```c++
template <typename T> class Foo {
 public:
  void Bar() { ::testing::StaticAssertTypeEq<int, T>(); }
};
```

the code:

```c++
void Test1() { Foo<bool> foo; }
```

will not generate a compiler error, as `Foo<bool>::Bar()` is never actually
instantiated. Instead, you need:

```c++
void Test2() { Foo<bool> foo; foo.Bar(); }
```

to cause a compiler error.

### Assertion Placement

You can use assertions in any C++ function. In particular, it doesn't have to be
a method of the test fixture class. The one constraint is that assertions that
generate a fatal failure (`FAIL*` and `ASSERT_*`) can only be used in
void-returning functions. This is a consequence of Google's not using
exceptions. By placing it in a non-void function you'll get a confusing compile
error like `"error: void value not ignored as it ought to be"` or `"cannot
initialize return object of type 'bool' with an rvalue of type 'void'"` or
`"error: no viable conversion from 'void' to 'string'"`.

If you need to use fatal assertions in a function that returns non-void, one
option is to make the function return the value in an out parameter instead. For
example, you can rewrite `T2 Foo(T1 x)` to `void Foo(T1 x, T2* result)`. You
need to make sure that `*result` contains some sensible value even when the
function returns prematurely. As the function now returns `void`, you can use
any assertion inside of it.

If changing the function's type is not an option, you should just use assertions
that generate non-fatal failures, such as `ADD_FAILURE*` and `EXPECT_*`.

NOTE: Constructors and destructors are not considered void-returning functions,
according to the C++ language specification, and so you may not use fatal
assertions in them; you'll get a compilation error if you try. Instead, either
call `abort` and crash the entire test executable, or put the fatal assertion in
a `SetUp`/`TearDown` function; see
[constructor/destructor vs. `SetUp`/`TearDown`](faq.md#CtorVsSetUp)

WARNING: A fatal assertion in a helper function (private void-returning method)
called from a constructor or destructor does not does not terminate the current
test, as your intuition might suggest: it merely returns from the constructor or
destructor early, possibly leaving your object in a partially-constructed or
partially-destructed state! You almost certainly want to `abort` or use
`SetUp`/`TearDown` instead.

## Teaching googletest How to Print Your Values

When a test assertion such as `EXPECT_EQ` fails, googletest prints the argument
values to help you debug. It does this using a user-extensible value printer.

This printer knows how to print built-in C++ types, native arrays, STL
containers, and any type that supports the `<<` operator. For other types, it
prints the raw bytes in the value and hopes that you the user can figure it out.

As mentioned earlier, the printer is *extensible*. That means you can teach it
to do a better job at printing your particular type than to dump the bytes. To
do that, define `<<` for your type:

```c++
#include <ostream>

namespace foo {

class Bar {  // We want googletest to be able to print instances of this.
...
  // Create a free inline friend function.
  friend std::ostream& operator<<(std::ostream& os, const Bar& bar) {
    return os << bar.DebugString();  // whatever needed to print bar to os
  }
};

// If you can't declare the function in the class it's important that the
// << operator is defined in the SAME namespace that defines Bar.  C++'s look-up
// rules rely on that.
std::ostream& operator<<(std::ostream& os, const Bar& bar) {
  return os << bar.DebugString();  // whatever needed to print bar to os
}

}  // namespace foo
```

Sometimes, this might not be an option: your team may consider it bad style to
have a `<<` operator for `Bar`, or `Bar` may already have a `<<` operator that
doesn't do what you want (and you cannot change it). If so, you can instead