Echo Writes Code

test_backtrace.cpp

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
#include "crucible/process.hpp"
#include "crucible/testing.hpp"

#include <algorithm>

namespace crucible::process::test_backtrace {
#ifdef CRUCIBLE_UNIX
  auto detailed_snapshot_inner_function() -> void {
    auto const result { process::backtrace::take_detailed_snapshot() };
    EXPECT_FAILURE(result);

    auto const &error { result.get_failure() };
    EXPECT_EQ(error.format(), "crucible::core::fallible::Error { my_variant: crucible::process::result::MissingDebugInformation {} }");
  }
#endif // CRUCIBLE_UNIX

#ifdef CRUCIBLE_WINDOWS
  auto detailed_snapshot_inner_function() -> void {
    std::string const file_std_string { __FILE__ };

    auto const result { process::backtrace::take_detailed_snapshot() }; int const line { __LINE__ };
    EXPECT_SUCCESS(result);

    auto const &snapshot { result.get_success() };
    EXPECT(!snapshot.empty());

    auto const &frame_1 { snapshot.at(1) };
    EXPECT_EQ(frame_1.get_function(), "crucible::process::backtrace::take_detailed_snapshot()");

    auto const &frame_2 { snapshot.at(2) };
    EXPECT_EQ(frame_2.get_function(), "crucible::process::test_backtrace::detailed_snapshot_inner_function()");
    EXPECT_EQ(frame_2.get_file(), file_std_string);
    EXPECT_EQ(frame_2.get_line(), line);

    std::string const root_std_string { CRUCIBLE_ROOT };
    auto const root_index { file_std_string.find(root_std_string) };
    auto const relative_file { root_index == 0 ? file_std_string.substr(root_std_string.size() + 1) : file_std_string };

    EXPECT_EQ(frame_2.describe(), "crucible::process::test_backtrace::detailed_snapshot_inner_function() at " + relative_file + ":" + std::to_string(line));
    EXPECT_EQ(frame_2.format(), "crucible::process::backtrace::DetailedStackFrame { my_function: std::string { \"crucible::process::test_backtrace::detailed_snapshot_inner_function()\" }, my_file: std::string { \"" + file_std_string + "\" }, my_line: " + std::to_string(line) + " }");
  }
#endif // CRUCIBLE_WINDOWS

  auto simple_snapshot_inner_function() -> void {
    auto const result { process::backtrace::take_simple_snapshot() };
    EXPECT_SUCCESS(result);

    auto const &snapshot { result.get_success() };
    EXPECT(!snapshot.empty());

    {
      auto const predicate {
        [](process::backtrace::SimpleStackFrame const &frame) -> bool {
          return frame.get_function().find("crucible::process::backtrace::take_simple_snapshot") != std::string::npos;
        }
      };

      auto const iterator { std::find_if(snapshot.begin(), snapshot.end(), predicate) };
      EXPECT_NE(iterator, snapshot.end());
    }

    {
      auto const predicate {
        [](process::backtrace::SimpleStackFrame const &frame) -> bool {
          return frame.get_function().find("crucible::process::test_backtrace::simple_snapshot_inner_function") != std::string::npos;
        }
      };

      auto const iterator { std::find_if(snapshot.begin(), snapshot.end(), predicate) };
      EXPECT_NE(iterator, snapshot.end());

      auto const &frame_2 { *iterator };

      auto const actual_describe { frame_2.describe() };
      auto const expected_describe { "crucible::process::test_backtrace::simple_snapshot_inner_function" };
      EXPECT_NE(actual_describe.find(expected_describe), std::string::npos);

      auto const actual_format { frame_2.format() };
      auto const expected_format_head { "crucible::process::backtrace::SimpleStackFrame { " };
      auto const expected_format_function { "crucible::process::test_backtrace::simple_snapshot_inner_function" };
      EXPECT_NE(actual_format.find(expected_format_head), std::string::npos);
      EXPECT_NE(actual_format.find(expected_format_function), std::string::npos);
    }
  }

  SCENARIO(backtrace, take_detailed_snapshot) {
    detailed_snapshot_inner_function();
  }

  SCENARIO(backtrace, take_simple_snapshot) {
    simple_snapshot_inner_function();
  }
}