blob: 1a27edabeb3be834c152e5489f2a61e08853e0b6 [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
Alexei Frolovc10c8122019-11-01 16:31:19 -070019namespace pw::unit_test {
20
21void RegisterEventHandler(EventHandler* event_handler) {
22 internal::Framework::Get().RegisterEventHandler(event_handler);
23}
24
25namespace internal {
26
27// Singleton instance of the unit test framework class.
28Framework Framework::framework_;
29
30// Linked list of all test cases in the test executable. This is static as it is
31// populated using static initialization.
32TestInfo* Framework::tests_ = nullptr;
33
Wyatt Heplercad29b42020-02-03 17:21:48 -080034void Framework::RegisterTest(TestInfo* new_test) {
35 // If the test list is empty, set new_test as the first test.
36 if (tests_ == nullptr) {
37 tests_ = new_test;
38 return;
Alexei Frolovc10c8122019-11-01 16:31:19 -070039 }
Wyatt Heplercad29b42020-02-03 17:21:48 -080040
41 // Append the test case to the end of the test list.
42 TestInfo* info = tests_;
43 for (; info->next() != nullptr; info = info->next()) {
44 }
45 info->set_next(new_test);
Alexei Frolovc10c8122019-11-01 16:31:19 -070046}
47
48int Framework::RunAllTests() {
Keir Mierle243e32a2019-11-05 10:29:26 -080049 run_tests_summary_.passed_tests = 0;
50 run_tests_summary_.failed_tests = 0;
51
52 if (event_handler_ != nullptr) {
53 event_handler_->RunAllTestsStart();
54 }
Wyatt Heplercad29b42020-02-03 17:21:48 -080055 for (const TestInfo* test = tests_; test != nullptr; test = test->next()) {
56 if (test->enabled()) {
Wyatt Hepler1c0e65e2020-01-27 13:10:18 -080057 test->run();
58 } else {
Wyatt Heplercad29b42020-02-03 17:21:48 -080059 event_handler_->TestCaseDisabled(test->test_case());
Wyatt Hepler1c0e65e2020-01-27 13:10:18 -080060 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070061 }
Keir Mierle243e32a2019-11-05 10:29:26 -080062 if (event_handler_ != nullptr) {
63 event_handler_->RunAllTestsEnd(run_tests_summary_);
64 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070065 return exit_status_;
66}
67
Wyatt Heplercad29b42020-02-03 17:21:48 -080068void Framework::StartTest(const TestInfo& test) {
69 current_test_ = &test;
Alexei Frolovc10c8122019-11-01 16:31:19 -070070 current_result_ = TestResult::kSuccess;
71
Wyatt Heplercad29b42020-02-03 17:21:48 -080072 if (event_handler_ != nullptr) {
73 event_handler_->TestCaseStart(test.test_case());
Alexei Frolovc10c8122019-11-01 16:31:19 -070074 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070075}
76
Wyatt Heplercad29b42020-02-03 17:21:48 -080077void Framework::EndCurrentTest() {
Keir Mierle243e32a2019-11-05 10:29:26 -080078 switch (current_result_) {
79 case TestResult::kSuccess:
80 run_tests_summary_.passed_tests++;
81 break;
82 case TestResult::kFailure:
83 run_tests_summary_.failed_tests++;
84 break;
85 }
Alexei Frolovc10c8122019-11-01 16:31:19 -070086
Wyatt Heplercad29b42020-02-03 17:21:48 -080087 if (event_handler_ != nullptr) {
88 event_handler_->TestCaseEnd(current_test_->test_case(), current_result_);
Alexei Frolovc10c8122019-11-01 16:31:19 -070089 }
90
Wyatt Heplercad29b42020-02-03 17:21:48 -080091 current_test_ = nullptr;
Alexei Frolovc10c8122019-11-01 16:31:19 -070092}
93
94void Framework::ExpectationResult(const char* expression,
Wyatt Heplera55d4c72020-01-16 10:26:04 -080095 const char* evaluated_expression,
Alexei Frolovc10c8122019-11-01 16:31:19 -070096 int line,
97 bool success) {
98 if (!success) {
99 current_result_ = TestResult::kFailure;
100 exit_status_ = 1;
101 }
102
103 if (event_handler_ == nullptr) {
104 return;
105 }
106
Alexei Frolovc10c8122019-11-01 16:31:19 -0700107 TestExpectation expectation = {
108 .expression = expression,
Wyatt Hepler8663e9c2019-11-20 13:58:29 -0800109 .evaluated_expression = evaluated_expression,
Alexei Frolovc10c8122019-11-01 16:31:19 -0700110 .line_number = line,
111 .success = success,
112 };
113
Wyatt Heplercad29b42020-02-03 17:21:48 -0800114 event_handler_->TestCaseExpect(current_test_->test_case(), expectation);
115}
116
117bool TestInfo::enabled() const {
118 constexpr size_t kStringSize = sizeof("DISABLED_") - 1;
119 return std::strncmp("DISABLED_", test_case().test_name, kStringSize) != 0 &&
120 std::strncmp("DISABLED_", test_case().suite_name, kStringSize) != 0;
Alexei Frolovc10c8122019-11-01 16:31:19 -0700121}
122
123} // namespace internal
Alexei Frolovc10c8122019-11-01 16:31:19 -0700124} // namespace pw::unit_test