Skip to content

Commit

Permalink
Improve codecov results (#9)
Browse files Browse the repository at this point in the history
* refactor: ♻️ Increase codevoc

Exclude certain directories from codecov and remove unused AssertionSpan

* test: ✅ Add assertion parsing tests
  • Loading branch information
DRovara authored Aug 12, 2024
1 parent 7469237 commit 439f7da
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 66 deletions.
3 changes: 3 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ ignore:
- "**/python"
- "test/**/*"
- "src/mqt/debug/dap/**/*"
- "src/mqt/debug/dap/*"
- "app/*"
- "src/frontend/**/*"

coverage:
range: 60..90
Expand Down
12 changes: 0 additions & 12 deletions include/common/parsing/AssertionParsing.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
enum class AssertionType : uint8_t {
Entanglement,
Superposition,
Span,
StatevectorEquality,
CircuitEquality
};
Expand All @@ -36,17 +35,6 @@ class SuperpositionAssertion : public Assertion {
explicit SuperpositionAssertion(std::vector<std::string> targetQubits);
};

class SpanAssertion : public Assertion {
std::vector<Statevector> spanVectors;

public:
SpanAssertion(std::vector<Statevector> spanVectors,
std::vector<std::string> targetQubits);
[[nodiscard]] const std::vector<Statevector>& getSpanVectors() const;

~SpanAssertion() override;
};

class EqualityAssertion : public Assertion {
double similarityThreshold;

Expand Down
11 changes: 0 additions & 11 deletions src/backend/dd/DDSimDebug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -955,12 +955,6 @@ bool checkAssertionSuperposition(
return found > 1;
}

[[noreturn]] bool
checkAssertionSpan([[maybe_unused]] DDSimulationState* ddsim,
[[maybe_unused]] std::unique_ptr<SpanAssertion>& assertion) {
throw std::runtime_error("Span assertions are not implemented");
}

bool checkAssertionEqualityStatevector(
DDSimulationState* ddsim,
std::unique_ptr<StatevectorEqualityAssertion>& assertion) {
Expand Down Expand Up @@ -1044,11 +1038,6 @@ bool checkAssertion(DDSimulationState* ddsim,
assertion = std::move(superpositionAssertion);
return result;
}
if (assertion->getType() == AssertionType::Span) {
std::unique_ptr<SpanAssertion> spanAssertion(
dynamic_cast<SpanAssertion*>(assertion.release()));
checkAssertionSpan(ddsim, spanAssertion);
}
if (assertion->getType() == AssertionType::StatevectorEquality) {
std::unique_ptr<StatevectorEqualityAssertion> svEqualityAssertion(
dynamic_cast<StatevectorEqualityAssertion*>(assertion.release()));
Expand Down
47 changes: 5 additions & 42 deletions src/common/parsing/AssertionParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "common/parsing/ParsingError.hpp"
#include "common/parsing/Utils.hpp"

#include <algorithm>
#include <cmath>
#include <cstddef>
#include <memory>
Expand All @@ -30,27 +31,6 @@ SuperpositionAssertion::SuperpositionAssertion(
std::vector<std::string> inputTargetQubits)
: Assertion(std::move(inputTargetQubits), AssertionType::Superposition) {}

SpanAssertion::SpanAssertion(std::vector<Statevector> inputSpanVectors,
std::vector<std::string> inputTargetQubits)
: Assertion(std::move(inputTargetQubits), AssertionType::Span),
spanVectors(std::move(inputSpanVectors)) {
for (auto& statevector : spanVectors) {
if (statevector.numQubits != getTargetQubits().size()) {
throw ParsingError(
"Number of target qubits must match number of qubits in statevector");
}
}
}
const std::vector<Statevector>& SpanAssertion::getSpanVectors() const {
return spanVectors;
}
SpanAssertion::~SpanAssertion() {
for (auto& statevector : spanVectors) {
// NOLINTNEXTLINE(cppcoreguidelines-owning-memory)
delete[] statevector.amplitudes;
}
}

EqualityAssertion::EqualityAssertion(double inputSimilarityThreshold,
std::vector<std::string> inputTargetQubits,
AssertionType assertionType)
Expand Down Expand Up @@ -93,7 +73,10 @@ const std::string& CircuitEqualityAssertion::getCircuitCode() const {
}

std::vector<std::string> extractTargetQubits(const std::string& targetPart) {
return splitString(targetPart, ',');
const auto parts = splitString(targetPart, ',');
std::vector<std::string> trimmedParts(parts.size());
std::transform(parts.begin(), parts.end(), trimmedParts.begin(), trim);
return trimmedParts;
}

Complex parseComplex(std::string complexString) {
Expand Down Expand Up @@ -143,7 +126,6 @@ bool isAssertion(std::string expression) {
expression = trim(expression);
return startsWith(expression, "assert-ent") ||
startsWith(expression, "assert-sup") ||
startsWith(expression, "assert-span") ||
startsWith(expression, "assert-eq");
}

Expand All @@ -159,25 +141,6 @@ std::unique_ptr<Assertion> parseAssertion(std::string assertionString,
auto targets = extractTargetQubits(assertionString.substr(11));
return std::make_unique<SuperpositionAssertion>(targets);
}
if (startsWith(assertionString, "assert-span")) {
auto sub = assertionString.substr(12);
auto targets = extractTargetQubits(sub);
auto statevectors = splitString(blockContent, ';');
std::vector<Statevector> statevectorList(statevectors.size());
for (auto& statevector : statevectors) {
statevectorList.emplace_back(parseStatevector(statevector));
}

auto assertion = std::make_unique<SpanAssertion>(statevectorList, targets);
auto svSize = statevectorList[0].numStates;
for (auto& sv : statevectorList) {
if (sv.numStates != svSize) {
throw ParsingError(
"Statevectors in span assertion must have the same size");
}
}
return assertion;
}
if (startsWith(assertionString, "assert-eq")) {
auto sub = assertionString.substr(10);
auto targets = extractTargetQubits(sub);
Expand Down
3 changes: 2 additions & 1 deletion test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ package_add_test(
test_simulation.cpp
test_data_retrieval.cpp
test_diagnostics.cpp
test_custom_code.cpp)
test_custom_code.cpp
test_parsing.cpp)

# set include directories
target_include_directories(mqt_debug_test PUBLIC ${PROJECT_SOURCE_DIR}/test/utils)
11 changes: 11 additions & 0 deletions test/test_custom_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,14 @@ TEST_F(CustomCodeTest, GateInGateName) {
"assert-eq q[0] { 0, 1 }");
state->runSimulation(state);
}

TEST_F(CustomCodeTest, EqualityAssertion) {
loadCode(2, 0,
"h q[0];"
"cx q[0], q[1];"
"assert-eq 0.9, q[0], q[1] { 0.707, 0, 0, 0.707 }"
"assert-eq q[0], q[1] { qreg q[2]; h q[1]; cx q[1], q[0]; }");
size_t numErrors = 0;
ASSERT_EQ(state->runAll(state, &numErrors), OK);
ASSERT_EQ(numErrors, 0);
}
64 changes: 64 additions & 0 deletions test/test_parsing.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "common/parsing/AssertionParsing.hpp"
#include "common/parsing/ParsingError.hpp"

#include <gtest/gtest.h>
#include <memory>
#include <string>

class ParsingTest : public testing::Test {
void SetUp() override {}
};

TEST_F(ParsingTest, EqualityAssertion) {
// With statevector
const auto a1 = parseAssertion("assert-eq 0.5, q[0]", "1, 0");
ASSERT_EQ(a1->getType(), AssertionType::StatevectorEquality);
ASSERT_EQ(a1->getTargetQubits().size(), 1);
ASSERT_EQ(a1->getTargetQubits()[0], "q[0]");
const auto* sv = dynamic_cast<StatevectorEqualityAssertion*>(a1.get());
ASSERT_EQ(sv->getSimilarityThreshold(), 0.5);
ASSERT_EQ(sv->getTargetStatevector().numQubits, 1);
ASSERT_EQ(sv->getTargetStatevector().numStates, 2);
ASSERT_EQ(sv->getTargetStatevector().amplitudes->real, 1);

// With circuit
const auto a2 = parseAssertion("assert-eq 0.5, q[0]", "qreg q[1]; h q[0];");
ASSERT_EQ(a2->getType(), AssertionType::CircuitEquality);
ASSERT_EQ(a2->getTargetQubits().size(), 1);
ASSERT_EQ(a2->getTargetQubits()[0], "q[0]");
const auto* c = dynamic_cast<CircuitEqualityAssertion*>(a2.get());
ASSERT_EQ(c->getSimilarityThreshold(), 0.5);
ASSERT_EQ(c->getCircuitCode(), "qreg q[1]; h q[0];");
}

TEST_F(ParsingTest, EntanglementAssertion) {
const auto a = parseAssertion("assert-ent q[0], q[1]", "");
ASSERT_EQ(a->getType(), AssertionType::Entanglement);
ASSERT_EQ(a->getTargetQubits().size(), 2);
ASSERT_EQ(a->getTargetQubits()[0], "q[0]");
ASSERT_EQ(a->getTargetQubits()[1], "q[1]");
}

TEST_F(ParsingTest, SuperpositionAssertion) {
const auto a = parseAssertion("assert-sup q[0], q[1]", "");
ASSERT_EQ(a->getType(), AssertionType::Superposition);
ASSERT_EQ(a->getTargetQubits().size(), 2);
ASSERT_EQ(a->getTargetQubits()[0], "q[0]");
ASSERT_EQ(a->getTargetQubits()[1], "q[1]");
}

TEST_F(ParsingTest, ErrorStatevectorEqualityAssertion) {
ASSERT_THROW(parseAssertion("assert-eq 1.5, q[0]", "1, 0"), ParsingError);
ASSERT_THROW(parseAssertion("assert-eq 0.5, q[0]", "1, 0, 0"), ParsingError);
ASSERT_THROW(parseAssertion("assert-eq 0.5, q[0]", "1, 0, 0, 0"),
ParsingError);
}

TEST_F(ParsingTest, ErrorCircuitEqualityAssertion) {
ASSERT_THROW(parseAssertion("assert-eq 1.5, q[0]", "qreg q[1]; h q[0];"),
ParsingError);
}

TEST_F(ParsingTest, ErrorInvalidAssertion) {
ASSERT_THROW(parseAssertion("assert-fake q[0]", ""), ParsingError);
}

0 comments on commit 439f7da

Please sign in to comment.