Commit 4f2d576e authored by Patrick Chen's avatar Patrick Chen

refactor code: use report

parent bba0f3ca
......@@ -8,7 +8,9 @@
"script": [
{
"command": "GetGreetingMessage",
"expect": "Hello, Master!"
"expect": "Hello, Master!",
"runs": ["GetName"],
"posts": []
}
]
}
......@@ -4,6 +4,7 @@
#include <nlohmann/json.hpp>
#include <string>
#include <unordered_set>
namespace xs { namespace test
......@@ -28,6 +29,8 @@ namespace xs { namespace test
public:
std::string name_;
nlohmann::json value_;
std::unordered_set<std::string> runs_;
std::unordered_set<std::string> posts_;
};
} }
......
......@@ -14,6 +14,14 @@ namespace xs { namespace test
{
class Tester final
{
public:
struct Report
{
bool pass;
std::unordered_set<std::string> missedCommands;
std::unordered_set<std::string> missedEvents;
};
public:
Tester() = delete;
~Tester() noexcept = default;
......@@ -33,12 +41,16 @@ namespace xs { namespace test
void onEvent(const std::string& name, const std::string& params) noexcept;
void registerServices() noexcept;
void resetCounters() noexcept;
Report createReport(const std::string& response, const Expectation& expectation) noexcept;
public:
private:
Config config_;
ExchangeServer server_;
std::unordered_map<std::string, const Service*> acceptCommands_;
std::unordered_map<std::string, const Service*> acceptEvents_;
std::unordered_map<std::string, unsigned> receivedCommandCount_;
std::unordered_map<std::string, unsigned> receivedEventCount_;
};
} }
......
#include "test/Expectation.h"
#include <nlohmann/json.hpp>
#include <stdexcept>
namespace xs { namespace test
{
Expectation::Expectation(const nlohmann::json& object)
: Expectation(object["command"].get<std::string>(), object["expect"])
{ }
{
if (object.count("runs")) {
for (const auto& element : object["runs"]) {
if (!element.is_string()) {
throw std::runtime_error("element in \"runs\" is not string");
}
runs_.emplace(element.get<std::string>());
}
}
if (object.count("posts")) {
for (const auto& element : object["posts"]) {
if (!element.is_string()) {
throw std::runtime_error("element in \"posts\" is not string");
}
posts_.emplace(element.get<std::string>());
}
}
}
bool Expectation::verify(const nlohmann::json& object) noexcept
{
......@@ -17,6 +36,14 @@ namespace xs { namespace test
return false;
}
if (object.count("runs") && !object["runs"].is_array()) {
return false;
}
if (object.count("posts") && !object["posts"].is_array()) {
return false;
}
return (
object["command"].is_string()
&& (
......
#include "test/Service.h"
#include "test/Tester.h"
#include <boost/algorithm/string/join.hpp>
#include <boost/format.hpp>
#include <boost/range/adaptors.hpp>
#include <nlohmann/json.hpp>
......@@ -52,13 +53,54 @@ void Tester::registerServices() noexcept
}
}
void Tester::resetCounters() noexcept
{
receivedCommandCount_.clear();
receivedEventCount_.clear();
}
Tester::Report Tester::createReport(const std::string& response, const Expectation& expectation) noexcept
{
Report report;
if (expectation.value_.is_string()) {
report.pass = (response == expectation.value_.get<std::string>());
} else {
try {
report.pass = (nlohmann::json::parse(response) == expectation.value_);
} catch (...) {
}
}
if (!expectation.runs_.empty()) {
for (const auto& command : expectation.runs_) {
if (!receivedCommandCount_[command]) {
report.missedCommands.emplace(command);
report.pass = false;
}
}
}
if (!expectation.posts_.empty()) {
for (const auto& event : expectation.posts_) {
if (!receivedEventCount_[event]) {
report.missedEvents.emplace(event);
report.pass = false;
}
}
}
return report;
}
std::string Tester::onCommand(const std::string& name, const std::string& params) noexcept
{
const auto found = acceptCommands_.find(name);
const auto* service = std::get<1>(*found);
const auto& response = service->response_;
/// TODO: keep track the status
receivedCommandCount_[name]++;
return detail::toString(response);
}
......@@ -68,32 +110,35 @@ void Tester::onEvent(const std::string& name, const std::string& params) noexcep
const auto* service = std::get<1>(*found);
const auto& response = service->response_;
/// TODO: keep track the status
receivedEventCount_[name]++;
}
void Tester::run() noexcept
{
for (const auto& e : config_.getExpectations()) {
const auto& command = e.name_;
const auto& expect = e.value_;
const auto response = server_.runCmd(command, "");
bool asExpect = false;
if (expect.is_string()) {
asExpect = (response == expect.get<std::string>());
} else {
try {
asExpect = (nlohmann::json::parse(response) == expect);
} catch (...) {
for (const auto& expectation : config_.getExpectations()) {
resetCounters();
}
const auto response = server_.runCmd(expectation.name_, "");
const auto report = createReport(response, expectation);
if (report.pass) {
std::cout << "[PASS] run command: " << expectation.name_ << std::endl;
continue;
}
if (asExpect) {
std::cout << "[PASS] run command: " << command << std::endl;
std::cout << "[FAILED] run command: " << expectation.name_ << std::endl;
if (report.missedCommands.empty() && report.missedEvents.empty()) {
std::cout << boost::format(R"([REASON] unexpected response: "%1%"(real) vs %2%(expect))")
% response % detail::toString(expectation.value_)
<< std::endl;
} else if (!report.missedCommands.empty()) {
std::cout << boost::format("[REASON] missed commands: [%1%]")
% boost::algorithm::join(report.missedCommands, ", ")
<< std::endl;
} else {
std::cout << "[FAILED] run command: " << command << " with unexpected response: "
<< "\"" << response << "\"(real) vs " << detail::toString(expect) << "(expect)" << std::endl;
std::cout << boost::format("[REASON] missed events: [%1%]")
% boost::algorithm::join(report.missedEvents, ", ")
<< std::endl;
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment