blob: 249928404d0938ee9f66efad0f341a587389ee6d [file]
// Copyright 2026 The Pigweed Authors
//
// 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
//
// https://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.
#include "pw_clock_tree/clock_tree.h"
#include "pw_compilation_testing/negative_compilation.h"
#include "pw_unit_test/framework.h"
namespace pw::clock_tree {
namespace {
TEST(ClockTreeDependency, CompileTimeTests) {}
#if PW_NC_TEST(NonBlockingCannotFailDependsOnBlocking)
PW_NC_EXPECT("Non-blocking element cannot depend on a blocking element");
// 1. ElementNonBlockingCannotFail depending on ElementBlocking
void NonBlockingCannotFailDependsOnBlocking() {
ClockSourceNoOpBlocking source_blocking;
class DependentNonBlocking
: public DependentElement<ElementNonBlockingCannotFail> {
public:
constexpr DependentNonBlocking(ElementBlocking& source)
: DependentElement<ElementNonBlockingCannotFail>(source) {}
Status DoEnable() override { return OkStatus(); }
};
DependentNonBlocking dep(source_blocking);
}
#elif PW_NC_TEST(NonBlockingMightFailDependsOnBlocking)
PW_NC_EXPECT("Non-blocking element cannot depend on a blocking element");
// 2. ElementNonBlockingMightFail depending on ElementBlocking
void NonBlockingMightFailDependsOnBlocking() {
ClockSourceNoOpBlocking source_blocking;
class DependentNonBlocking
: public DependentElement<ElementNonBlockingMightFail> {
public:
constexpr DependentNonBlocking(ElementBlocking& source)
: DependentElement<ElementNonBlockingMightFail>(source) {}
Status DoEnable() override { return OkStatus(); }
};
DependentNonBlocking dep(source_blocking);
}
#elif PW_NC_TEST(NonBlockingCannotFailDependsOnNonBlockingMightFail)
PW_NC_EXPECT("Non-failing element cannot depend on an element that might fail");
// 3. ElementNonBlockingCannotFail depending on ElementNonBlockingMightFail
void NonBlockingCannotFailDependsOnNonBlockingMightFail() {
class ClockSourceNonBlockingMightFail
: public ClockSource<ElementNonBlockingMightFail> {
public:
Status DoEnable() override { return OkStatus(); }
};
ClockSourceNonBlockingMightFail source_might_fail;
class DependentNonBlocking
: public DependentElement<ElementNonBlockingCannotFail> {
public:
constexpr DependentNonBlocking(ElementNonBlockingMightFail& source)
: DependentElement<ElementNonBlockingCannotFail>(source) {}
Status DoEnable() override { return OkStatus(); }
};
DependentNonBlocking dep(source_might_fail);
}
#elif PW_NC_TEST(NonBlockingCannotFailDependsOnElement)
PW_NC_EXPECT("Non-failing element cannot depend on an element that might fail");
// 4. ElementNonBlockingCannotFail depending on Element
void NonBlockingCannotFailDependsOnElement() {
ClockSourceNoOp source_cannot_fail;
class DependentNonBlocking
: public DependentElement<ElementNonBlockingCannotFail> {
public:
constexpr DependentNonBlocking(Element& source)
: DependentElement<ElementNonBlockingCannotFail>(source) {}
Status DoEnable() override { return OkStatus(); }
};
Element element_source_cannot_fail = source_cannot_fail;
DependentNonBlocking dep(element_source_cannot_fail);
}
#elif PW_NC_TEST(NonBlockingMightFailDependsOnElement)
PW_NC_EXPECT("Non-blocking element cannot depend on a blocking element");
// 5. ElementNonBlockingMightFail depending on Element
void NonBlockingMightFailDependsOnElement() {
ClockSourceNoOp source_cannot_fail;
class DependentNonBlocking
: public DependentElement<ElementNonBlockingMightFail> {
public:
constexpr DependentNonBlocking(Element& source)
: DependentElement<ElementNonBlockingMightFail>(source) {}
Status DoEnable() override { return OkStatus(); }
};
Element element_source_cannot_fail = source_cannot_fail;
DependentNonBlocking dep(element_source_cannot_fail);
}
#elif PW_NC_TEST(ClockDividerNonBlockingCannotFailDependsOnBlocking)
PW_NC_EXPECT("Non-blocking element cannot depend on a blocking element");
// 6. ClockDividerNonBlockingCannotFail depending on ElementBlocking
void ClockDividerNonBlockingCannotFailDependsOnBlocking() {
ClockSourceNoOpBlocking source_blocking;
class MyDivider : public ClockDividerElement<ElementNonBlockingCannotFail> {
public:
constexpr MyDivider(ElementBlocking& source, uint32_t divider)
: ClockDividerElement<ElementNonBlockingCannotFail>(source, divider) {}
Status DoEnable() override { return OkStatus(); }
};
MyDivider divider(source_blocking, 2);
}
#elif PW_NC_TEST(ClockDividerNonBlockingCannotFailDependsOnNonBlockingMightFail)
PW_NC_EXPECT("Non-failing element cannot depend on an element that might fail");
// 7. ClockDividerNonBlockingCannotFail depending on ElementNonBlockingMightFail
void ClockDividerNonBlockingCannotFailDependsOnNonBlockingMightFail() {
class ClockSourceNonBlockingMightFail
: public ClockSource<ElementNonBlockingMightFail> {
public:
Status DoEnable() override { return OkStatus(); }
};
ClockSourceNonBlockingMightFail source_might_fail;
class MyDivider : public ClockDividerElement<ElementNonBlockingCannotFail> {
public:
constexpr MyDivider(ElementNonBlockingMightFail& source, uint32_t divider)
: ClockDividerElement<ElementNonBlockingCannotFail>(source, divider) {}
Status DoEnable() override { return OkStatus(); }
};
MyDivider divider(source_might_fail, 2);
}
#elif PW_NC_TEST(ClockDividerNonBlockingMightFailDependsOnBlocking)
PW_NC_EXPECT("Non-blocking element cannot depend on a blocking element");
// 8. ClockDividerNonBlockingMightFail depending on ElementBlocking
void ClockDividerNonBlockingMightFailDependsOnBlocking() {
ClockSourceNoOpBlocking source_blocking;
class MyDivider : public ClockDividerElement<ElementNonBlockingMightFail> {
public:
constexpr MyDivider(ElementBlocking& source, uint32_t divider)
: ClockDividerElement<ElementNonBlockingMightFail>(source, divider) {}
Status DoEnable() override { return OkStatus(); }
};
MyDivider divider(source_blocking, 2);
}
#endif // PW_NC_TEST
} // namespace
} // namespace pw::clock_tree