blob: 69529bc77ec5118cae7dcafc2a058f9944c3d900 [file] [log] [blame]
Alexei Frolovc10c8122019-11-01 16:31:19 -07001// Copyright 2019 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
Wyatt Hepler1a960942019-11-26 14:13:38 -08004// use this file except in compliance with the License. You may obtain a copy of
5// the License at
Alexei Frolovc10c8122019-11-01 16:31:19 -07006//
7// https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
Wyatt Hepler1a960942019-11-26 14:13:38 -080012// License for the specific language governing permissions and limitations under
13// the License.
Alexei Frolovc10c8122019-11-01 16:31:19 -070014
15#include "pw_unit_test/framework.h"
16
Wyatt Hepler1c0e65e2020-01-27 13:10:18 -080017#include <cstring>
18
karthik bharadwaj4116dbd2020-08-10 11:03:06 -070019namespace pw {
20namespace unit_test {
Alexei Frolovc10c8122019-11-01 16:31:19 -070021
22void RegisterEventHandler(EventHandler* event_handler) {
23 internal::Framework::Get().RegisterEventHandler(event_handler);
24}
25
26namespace internal {
27
28// Singleton instance of the unit test framework class.
29Framework Framework::framework_;
30
31// Linked list of all test cases in the test executable. This is static as it is
32// populated using static initialization.
33TestInfo* Framework::tests_ = nullptr;
34
Wyatt Heplercad29b42020-02-03 17:21:48 -080035void Framework::RegisterTest(TestInfo* new_test) {
36 // If the test list is empty, set new_test as the first test.
37 if (tests_ == nullptr) {
38 tests_ = new_test;
39 return;
Alexei Frolovc10c8122019-11-01 16:31:19 -070040 }
Wyatt Heplercad29b42020-02-03 17:21:48 -080041
42 // Append the test case to the end of the test list.
43 TestInfo* info = tests_;
44 for (; info->next() != nullptr; info = info->next()) {
45 }
46 info->set_next(new_test);
Alexei Frolovc10c8122019-11-01 16:31:19 -070047}
48
49int Framework::RunAllTests() {
Keir Mierle243e32a2019-11-05 10:29:26 -080050 run_tests_summary_.passed_tests = 0;
51 run_tests_summary_.failed_tests = 0;
52
53 if (event_handler_ != nullptr) {
54 event_handler_->RunAllTestsStart();
55 }
Wyatt Heplercad29b42020-02-03 17:21:48 -080056 for (const TestInfo* test = tests_; test != nullptr; test = test->next()) {
57 if (test->enabled()) {
Wyatt Hepler1c0e65e2020-01-27 13:10:18 -080058 test->run();
Prashanth Swaminathanee8b0f62021-02-02 19:49:10 -080059 } else if (event_handler_ != nullptr) {
Wyatt Heplercad29b42020-02-03 17:21:48 -080060 event_handler_->TestCaseDisabled(test->test_case());
Wyatt Hepler1c0e65e2020-01-27 13:10:18 -080061 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070062 }
Keir Mierle243e32a2019-11-05 10:29:26 -080063 if (event_handler_ != nullptr) {
64 event_handler_->RunAllTestsEnd(run_tests_summary_);
65 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070066 return exit_status_;
67}
68
Wyatt Heplercad29b42020-02-03 17:21:48 -080069void Framework::StartTest(const TestInfo& test) {
70 current_test_ = &test;
Alexei Frolovc10c8122019-11-01 16:31:19 -070071 current_result_ = TestResult::kSuccess;
72
Wyatt Heplercad29b42020-02-03 17:21:48 -080073 if (event_handler_ != nullptr) {
74 event_handler_->TestCaseStart(test.test_case());
Alexei Frolovc10c8122019-11-01 16:31:19 -070075 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070076}
77
Wyatt Heplercad29b42020-02-03 17:21:48 -080078void Framework::EndCurrentTest() {
Keir Mierle243e32a2019-11-05 10:29:26 -080079 switch (current_result_) {
80 case TestResult::kSuccess:
81 run_tests_summary_.passed_tests++;
82 break;
83 case TestResult::kFailure:
84 run_tests_summary_.failed_tests++;
85 break;
86 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070087
Wyatt Heplercad29b42020-02-03 17:21:48 -080088 if (event_handler_ != nullptr) {
89 event_handler_->TestCaseEnd(current_test_->test_case(), current_result_);
Alexei Frolovc10c8122019-11-01 16:31:19 -070090 }
91
Wyatt Heplercad29b42020-02-03 17:21:48 -080092 current_test_ = nullptr;
Alexei Frolovc10c8122019-11-01 16:31:19 -070093}
94
95void Framework::ExpectationResult(const char* expression,
Wyatt Heplera55d4c72020-01-16 10:26:04 -080096 const char* evaluated_expression,
Alexei Frolovc10c8122019-11-01 16:31:19 -070097 int line,
98 bool success) {
99 if (!success) {
100 current_result_ = TestResult::kFailure;
101 exit_status_ = 1;
102 }
103
104 if (event_handler_ == nullptr) {
105 return;
106 }
107
Alexei Frolovc10c8122019-11-01 16:31:19 -0700108 TestExpectation expectation = {
109 .expression = expression,
Wyatt Hepler8663e9c2019-11-20 13:58:29 -0800110 .evaluated_expression = evaluated_expression,
Alexei Frolovc10c8122019-11-01 16:31:19 -0700111 .line_number = line,
112 .success = success,
113 };
114
Wyatt Heplercad29b42020-02-03 17:21:48 -0800115 event_handler_->TestCaseExpect(current_test_->test_case(), expectation);
116}
117
118bool TestInfo::enabled() const {
119 constexpr size_t kStringSize = sizeof("DISABLED_") - 1;
120 return std::strncmp("DISABLED_", test_case().test_name, kStringSize) != 0 &&
121 std::strncmp("DISABLED_", test_case().suite_name, kStringSize) != 0;
Alexei Frolovc10c8122019-11-01 16:31:19 -0700122}
123
124} // namespace internal
karthik bharadwaj4116dbd2020-08-10 11:03:06 -0700125} // namespace unit_test
126} // namespace pw