Commit 1fbd1b19 authored by Patrick Chen's avatar Patrick Chen

use pgjson to access JSON strings

parent e59eb345
[submodule "submodule/json"]
path = submodule/json
url = https://github.com/nlohmann/json.git
REPO_DIR=$(shell pwd) REPO_DIR=$(shell pwd)
INCLUDE_DIR=$(REPO_DIR)/include INCLUDE_DIR=$(REPO_DIR)/include
SRC_DIR=$(REPO_DIR)/src SRC_DIR=$(REPO_DIR)/src
SUBMOD_DIR=$(REPO_DIR)/submodule
BUILD_DIR=$(REPO_DIR)/build BUILD_DIR=$(REPO_DIR)/build
CXX=clang++ CXX=clang++
CXX_FLAGS=-g -std=c++14 \ CXX_FLAGS=-g -std=c++14 \
-I/usr/local/include \ -I/usr/local/include \
-I$(INCLUDE_DIR) \ -I$(INCLUDE_DIR)
-I$(SUBMOD_DIR)/json/single_include
LD_FLAGS=-L/usr/local/lib \ LD_FLAGS=-L/usr/local/lib \
-lboost_system \ -lboost_system \
-lboost_filesystem \ -lboost_filesystem \
......
...@@ -6,8 +6,8 @@ ...@@ -6,8 +6,8 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range.hpp>
#include <nlohmann/json.hpp>
#include "pgjson/pgjson.hpp"
#include "test/Expectation.h" #include "test/Expectation.h"
#include "test/Service.h" #include "test/Service.h"
...@@ -39,7 +39,7 @@ namespace xs { namespace test ...@@ -39,7 +39,7 @@ namespace xs { namespace test
> getExpectations() const noexcept; > getExpectations() const noexcept;
private: private:
static bool verify(const nlohmann::json& object) noexcept; static bool verify(const pgjson::CValue& object) noexcept;
private: private:
service_range_type services_; service_range_type services_;
......
#ifndef XS_TEST_EXPECTATION_H_INCLUDED #ifndef XS_TEST_EXPECTATION_H_INCLUDED
#define XS_TEST_EXPECTATION_H_INCLUDED #define XS_TEST_EXPECTATION_H_INCLUDED
#include "pgjson/pgjson.hpp"
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <nlohmann/json.hpp>
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
...@@ -15,19 +16,19 @@ namespace xs { namespace test ...@@ -15,19 +16,19 @@ namespace xs { namespace test
public: public:
Expectation() = delete; Expectation() = delete;
Expectation(const Expectation&) = delete; Expectation(const Expectation&) = delete;
Expectation(Expectation&&) noexcept = default; Expectation(Expectation&&) = default;
~Expectation() noexcept = default; ~Expectation() noexcept = default;
Expectation& operator=(const Expectation&) = delete; Expectation& operator=(const Expectation&) = delete;
Expectation& operator=(Expectation&&) = delete; Expectation& operator=(Expectation&&) = delete;
explicit Expectation(const nlohmann::json& object); explicit Expectation(const pgjson::CValue& object);
static bool verify(const nlohmann::json& object) noexcept; static bool verify(const pgjson::CValue& object) noexcept;
public: public:
std::string name_; std::string name_;
nlohmann::json request_; pgjson::CValue request_;
boost::optional<nlohmann::json> response_; boost::optional<pgjson::CValue> response_;
std::unordered_set<std::string> runs_; std::unordered_set<std::string> runs_;
std::unordered_set<std::string> posts_; std::unordered_set<std::string> posts_;
}; };
......
#ifndef XS_TEST_SERVER_H_INCLUDED #ifndef XS_TEST_SERVER_H_INCLUDED
#define XS_TEST_SERVER_H_INCLUDED #define XS_TEST_SERVER_H_INCLUDED
#include <string>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include <nlohmann/json.hpp>
#include <string> #include "pgjson/pgjson.hpp"
namespace xs { namespace test namespace xs { namespace test
...@@ -14,26 +15,26 @@ namespace xs { namespace test ...@@ -14,26 +15,26 @@ namespace xs { namespace test
public: public:
Service() = delete; Service() = delete;
Service(const Service&) = delete; Service(const Service&) = delete;
Service(Service&&) noexcept = default; Service(Service&&) = default;
~Service() noexcept = default; ~Service() noexcept = default;
Service& operator=(const Service&) = delete; Service& operator=(const Service&) = delete;
Service& operator=(Service&&) = delete; Service& operator=(Service&&) = delete;
explicit Service(const nlohmann::json& object); explicit Service(const pgjson::CValue& object);
static bool verify(const nlohmann::json& object) noexcept; static bool verify(const pgjson::CValue& object) noexcept;
bool isCommand() const noexcept; bool isCommand() const noexcept;
bool isEvent() const noexcept; bool isEvent() const noexcept;
private: private:
Service(std::string name, nlohmann::json response) noexcept; Service(std::string name, pgjson::CValue response) noexcept;
Service(std::string name) noexcept; Service(std::string name) noexcept;
public: public:
std::string name_; std::string name_;
boost::optional<nlohmann::json> request_; boost::optional<pgjson::CValue> request_;
boost::optional<nlohmann::json> response_; boost::optional<pgjson::CValue> response_;
}; };
} } } }
......
#include "pgjson/pgjson.hpp"
#include "test/Config.h" #include "test/Config.h"
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <nlohmann/json.hpp>
#include <fstream> #include <fstream>
#include <iterator> #include <iterator>
...@@ -30,7 +30,7 @@ namespace detail ...@@ -30,7 +30,7 @@ namespace detail
Config::Config(const boost::filesystem::path& file) Config::Config(const boost::filesystem::path& file)
{ {
const auto object = nlohmann::json::parse( const auto object = pgjson::toCValue(
detail::readAsString(file) detail::readAsString(file)
); );
...@@ -65,13 +65,13 @@ boost::iterator_range< ...@@ -65,13 +65,13 @@ boost::iterator_range<
); );
} }
bool Config::verify(const nlohmann::json& object) noexcept bool Config::verify(const pgjson::CValue& object) noexcept
{ {
if (!(object.count("mockData") && object["mockData"].is_array())) { if (!(object.hasMember("mockData") && object["mockData"].isArray())) {
return false; return false;
} }
if (!(object.count("script") && object["script"].is_array())) { if (!(object.hasMember("script") && object["script"].isArray())) {
return false; return false;
} }
......
#include "pgjson/pgjson.hpp"
#include "test/Expectation.h" #include "test/Expectation.h"
#include <nlohmann/json.hpp>
#include <stdexcept> #include <stdexcept>
namespace xs { namespace test namespace xs { namespace test
{ {
Expectation::Expectation(const nlohmann::json& object) Expectation::Expectation(const pgjson::CValue& object)
: name_(object["command"].get<std::string>()) : name_(object["command"].as<std::string>())
{ {
request_ = object["param"]; request_ = object["param"];
if (!object.count("expect")) { if (!object.hasMember("expect")) {
return; return;
} }
const auto& expect = object["expect"]; const auto& expect = object["expect"];
response_ = expect["response"]; response_ = expect["response"];
if (expect.count("runs")) { if (expect.hasMember("runs")) {
for (const auto& element : expect["runs"]) { for (const auto& element : expect["runs"]) {
if (!element.is_string()) { if (!element.isString()) {
throw std::runtime_error("element in \"runs\" is not string"); throw std::runtime_error("element in \"runs\" is not string");
} }
runs_.emplace(element.get<std::string>()); runs_.emplace(element.as<std::string>());
} }
} }
if (expect.count("posts")) { if (expect.hasMember("posts")) {
for (const auto& element : expect["posts"]) { for (const auto& element : expect["posts"]) {
if (!element.is_string()) { if (!element.isString()) {
throw std::runtime_error("element in \"posts\" is not string"); throw std::runtime_error("element in \"posts\" is not string");
} }
posts_.emplace(element.get<std::string>()); posts_.emplace(element.as<std::string>());
} }
} }
} }
bool Expectation::verify(const nlohmann::json& object) noexcept bool Expectation::verify(const pgjson::CValue& object) noexcept
{ {
if (!object.is_object()) { if (!object.isObject()) {
return false; return false;
} }
if (!(object.count("command") && object["command"].is_string())) { if (!(object.hasMember("command") && object["command"].isString())) {
return false; return false;
} }
if (!object.count("param")) { if (!object.hasMember("param")) {
return false; return false;
} }
if (!(object["param"].is_string() || object["param"].is_object())) { if (!(object["param"].isString() || object["param"].isObject())) {
return false; return false;
} }
if (!object.count("expect")) { if (!object.hasMember("expect")) {
return true; return true;
} }
if (!object["expect"].is_object()) { if (!object["expect"].isObject()) {
return false; return false;
} }
const auto& expect = object["expect"]; const auto& expect = object["expect"];
if (!expect.count("response")) { if (!expect.hasMember("response")) {
return false; return false;
} }
if (!(expect["response"].is_string() || expect["response"].is_object())) { if (!(expect["response"].isString() || expect["response"].isObject())) {
return false; return false;
} }
if (expect.count("runs") && !expect["runs"].is_array()) { if (expect.hasMember("runs") && !expect["runs"].isArray()) {
return false; return false;
} }
if (expect.count("posts") && !expect["posts"].is_array()) { if (expect.hasMember("posts") && !expect["posts"].isArray()) {
return false; return false;
} }
......
#include "pgjson/pgjson.hpp"
#include "test/Service.h" #include "test/Service.h"
#include <nlohmann/json.hpp>
#include <memory> #include <memory>
namespace xs { namespace test namespace xs { namespace test
{ {
Service::Service(const nlohmann::json& object) Service::Service(const pgjson::CValue& object)
: Service( : Service(
object[object.count("command") ? "command" : "event"].get<std::string>() object[object.hasMember("command") ? "command" : "event"].as<std::string>()
) )
{ {
if (object.count("command")) { if (object.hasMember("command")) {
response_ = object["response"]; response_ = object["response"];
if (object.count("param")) { if (object.hasMember("param")) {
request_ = object["param"]; request_ = object["param"];
} }
} }
} }
bool Service::verify(const nlohmann::json& object) noexcept bool Service::verify(const pgjson::CValue& object) noexcept
{ {
if (!object.is_object()) { if (!object.isObject()) {
return false; return false;
} }
static const auto isStringOrObject = [](const nlohmann::json& object) { static const auto isStringOrObject = [](const pgjson::CValue& object) {
return object.is_string() || object.is_object(); return object.isString() || object.isObject();
}; };
if (object.count("command")) { if (object.hasMember("command")) {
if (object.count("param")) { if (object.hasMember("param")) {
if (!isStringOrObject(object["param"])) { if (!isStringOrObject(object["param"])) {
return false; return false;
} }
} }
return object["command"].is_string() return object["command"].isString()
&& isStringOrObject(object["response"]) && isStringOrObject(object["response"])
; ;
} else if (object.count("event")) { } else if (object.hasMember("event")) {
return object["event"].is_string(); return object["event"].isString();
} }
return false; return false;
......
#include "pgjson/pgjson.hpp"
#include "test/Service.h" #include "test/Service.h"
#include "test/Tester.h" #include "test/Tester.h"
#include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/join.hpp>
#include <boost/format.hpp> #include <boost/format.hpp>
#include <boost/range/adaptors.hpp> #include <boost/range/adaptors.hpp>
#include <nlohmann/json.hpp>
#include <chrono> #include <chrono>
#include <functional> #include <functional>
...@@ -14,10 +14,10 @@ ...@@ -14,10 +14,10 @@
namespace xs { namespace test { namespace xs { namespace test {
namespace detail { namespace detail {
std::string toString(const nlohmann::json& object) std::string toString(const pgjson::CValue& object)
{ {
return object.is_string() ? object.get<std::string>() return object.isString() ? object.as<std::string>()
: object.dump(); : object.toStdString();
} }
} }
...@@ -62,11 +62,11 @@ Tester::Report Tester::createReport(const std::string& response, const Expectati ...@@ -62,11 +62,11 @@ Tester::Report Tester::createReport(const std::string& response, const Expectati
return report; return report;
} }
if (expectation.response_->is_string()) { if (expectation.response_->isString()) {
report.pass = (response == expectation.response_->get<std::string>()); report.pass = (response == expectation.response_->as<std::string>());
} else { } else {
try { try {
report.pass = (nlohmann::json::parse(response) == *expectation.response_); report.pass = (pgjson::toCValue(response) == *expectation.response_);
} catch (...) { } catch (...) {
} }
...@@ -112,14 +112,14 @@ std::string Tester::onCommand(const std::string& name, const std::string& params ...@@ -112,14 +112,14 @@ std::string Tester::onCommand(const std::string& name, const std::string& params
auto& receiveCount = receivedCommandCount_[name]; auto& receiveCount = receivedCommandCount_[name];
const auto& request = *handler.request_; const auto& request = *handler.request_;
const bool isString = request.is_string(); const bool isString = request.isString();
if (isString) { if (isString) {
if (params == request.get<std::string>()) { if (params == request.as<std::string>()) {
receiveCount++; receiveCount++;
return detail::toString(*handler.response_); return detail::toString(*handler.response_);
} }
} else { } else {
if (nlohmann::json::parse(params) == request) { if (pgjson::toCValue(params) == request) {
receiveCount++; receiveCount++;
return detail::toString(*handler.response_); return detail::toString(*handler.response_);
} }
...@@ -139,7 +139,7 @@ void Tester::run() noexcept ...@@ -139,7 +139,7 @@ void Tester::run() noexcept
for (const auto& expectation : config_.getExpectations()) { for (const auto& expectation : config_.getExpectations()) {
resetCounters(); resetCounters();
const auto response = server_.runCmd(expectation.name_, expectation.request_.dump()); const auto response = server_.runCmd(expectation.name_, expectation.request_.toStdString());
// wait 100ms for upcoming events // wait 100ms for upcoming events
using namespace std::chrono_literals; using namespace std::chrono_literals;
......
#include "pgjson/pgjson.hpp"
#include "positivegrid/exchange_server.h"
#include "test/Tester.h"
#include <boost/filesystem.hpp>
#include <chrono> #include <chrono>
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <thread> #include <thread>
#include <boost/filesystem.hpp>
#include "test/Tester.h"
#include "nlohmann/json.hpp"
#include "positivegrid/exchange_server.h"
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc < 2) { if (argc < 2) {
......
Subproject commit d713727f2277f2eb919a2dbbfdd534f8988aa493
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