modules.cpp
No OneTemporary

File Metadata

Created
Wed, Jul 8, 5:02 PM

modules.cpp

/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* modules.cpp
*
* Author: pgess <v.melnychenko@xreate.org>
* Created on June 18, 2017, 8:25 PM
*/
class Modules_AST2_Test;
class Modules_Discovery1_Test;
class Modules_Solve1_Test;
#define FRIENDS_MODULES_TESTS \
friend class ::Modules_AST2_Test; \
friend class ::Modules_Discovery1_Test; \
friend class ::Modules_Solve1_Test;
#include "modules.h"
#include "aux/xreatemanager-decorators.h"
#include "aux/xreatemanager-modules.h"
#include "xreatemanager.h"
#include "modules/Parser.h"
#include "supplemental/docutils.h"
#include "gtest/gtest.h"
#include <boost/filesystem.hpp>
#include <regex>
#include <clingo/clingocontrol.hh>
namespace fs = boost::filesystem;
using namespace std;
using namespace xreate;
using namespace xreate::modules;
TEST(Modules, AST1) {
FILE* input = fopen("scripts/dsl/regexp.xreate","r");
assert(input != nullptr);
Scanner scanner(input);
Parser parser(&scanner);
parser.Parse();
ASSERT_EQ(parser.errors->count, 0);
}
TEST(Modules, AST2){
string code = R"Code(
module:: name(test1); status(untested)
{
require(provides(logging)).
controller("/tmp/test-controller.ls").
discover("/tmp/root/").
}
)Code";
Scanner scanner(reinterpret_cast<const unsigned char*>(code.c_str()), code.size());
Parser parser(&scanner);
parser.Parse();
ModuleRecord module = parser.module;
ASSERT_EQ(2, module.__properties.size());
ASSERT_EQ("name", module.__properties.front().getValueString());
ASSERT_EQ("status", module.__properties.back().getValueString());
ASSERT_EQ(1, module.__requests.size());
ASSERT_EQ("provides", module.__requests.front().getValueString());
ASSERT_EQ(1, module.__controllers.size());
ASSERT_EQ("/tmp/test-controller.ls", module.__controllers.front());
ASSERT_EQ(1, module.__discoveryPaths.size());
ASSERT_EQ("/tmp/root/", module.__discoveryPaths.front());
}
TEST(Modules, Discovery1){
const std::string dirModulesRoot = "/tmp/testModulesDiscovery1_t54723/";
string codeA =
R"Code(
module::name(testA); status(needToTestMore).
)Code";
string codeB =
R"Code(
module:: name(testB); status(needToTestEvenMore).
)Code";
string codeMain = string("module{discover (\"") + dirModulesRoot + "\").}";
fs::create_directories(dirModulesRoot);
fs::ofstream fileA(dirModulesRoot + "a.xreate");
fileA << codeA;
fileA.close();
fs::ofstream fileB(dirModulesRoot + "b.xreate");
fileB << codeB;
fileB.close();
Scanner scanner(reinterpret_cast<const unsigned char*>(codeMain.c_str()), codeMain.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.discoverModules(parser.module);
fs::remove_all(dirModulesRoot);
std::string output = solver.__program.str();
cout << output << endl;
ASSERT_NE(string::npos, output.find("bind_module(\"/tmp/testModulesDiscovery1_t54723/a.xreate\", name(testA))."));
ASSERT_NE(string::npos, output.find("bind_module(\"/tmp/testModulesDiscovery1_t54723/b.xreate\", status(needToTestEvenMore))."));
}
TEST(Modules, Requests1){
}
TEST(Modules, Compilation1){
const std::string dirModulesRoot = "/tmp/testModulesDiscovery1_t54726/";
string codeMain =
R"Code(
module {
discover("/tmp/testModulesDiscovery1_t54726/").
controller("/tmp/testModulesDiscovery1_t54726/controller").
require (superService).
}
test = function:: int; entry {
getYourNumber()
}
)Code";
string codeA =
R"Code(
module:: name(testA); provide(superService); status(needToTestEvenMore).
getYourNumber= function:: int {0}
)Code";
string codeB =
R"Code(
module :: name(testB); provide(superService); status(needToTestMore).
getYourNumber= function:: int {1}
)Code";
string codeController =
R"Code(
status_score(0, needToTestEvenMore).
status_score(1, needToTestMore).
module_include_candidate(Request, Y):-
bind_module(Y, provide(Request)).
module_include_winner(Request, MaxScore) :-
MaxScore = #max{Score: module_include_candidate(Request, Y), bind_module(Y, status(Status)), status_score(Score, Status)};
modules_require(_, Request).
modules_resolution(Request, Y) :-
module_include_winner(Request, MaxScore);
bind_module(Y, provide(Request));
bind_module(Y, status(Status));
status_score(MaxScore, Status).
)Code";
fs::create_directories(dirModulesRoot);
fs::ofstream fileA(dirModulesRoot + "a.xreate");
fileA << codeA;
fileA.close();
fs::ofstream fileB(dirModulesRoot + "b.xreate");
fileB << codeB;
fileB.close();
fs::ofstream fileController(dirModulesRoot + "controller");
fileController << codeController;
fileController.close();
auto man = new XreateManagerImpl<XreateManagerDecoratorModules<XreateManagerDecoratorFull>>();
man->prepareCode(std::move(codeMain));
fs::remove_all(dirModulesRoot);
int (*funcMain)() = (int (*)()) man->run();
int result = funcMain();
ASSERT_EQ(1, result);
}
TEST(Modules, Compilation_AssignModulePath1){
const std::string dirModulesRoot = "/tmp/testModulesDiscovery1_t54725/";
string codeMain =
R"Code(
module {
discover("/tmp/testModulesDiscovery1_t54725/").
controller("/tmp/testModulesDiscovery1_t54725/controller").
require (superService).
}
test = function:: int; entry {
getYourNumber()
}
)Code";
string codeA =
R"Code(
module:: name(testA); provide(superService); status(needToTestEvenMore).
getYourNumber= function:: int {0}
)Code";
string codeController =
R"Code(
modules_resolution(superService, "/tmp/testModulesDiscovery1_t54725/a.xreate").
)Code";
fs::create_directories(dirModulesRoot);
fs::ofstream fileA(dirModulesRoot + "a.xreate");
fileA << codeA;
fileA.close();
fs::ofstream fileController(dirModulesRoot + "controller");
fileController << codeController;
fileController.close();
auto man = new XreateManagerImpl<XreateManagerDecoratorModules<XreateManagerDecoratorFull>>();
man->prepareCode(std::move(codeMain));
fs::remove_all(dirModulesRoot);
int (*funcMain)() = (int (*)()) man->run();
int result = funcMain();
ASSERT_EQ(0, result);
}
TEST(Modules, Doc_Requesting_Modules_1){
string codeExcerpt = getDocumentationExampleById("documentation/Syntax/modules.xml", "Requesting_Modules_1");
string codeController = R"Code(
modules_resolution(logger, "/tmp/logger").
)Code";
Scanner scanner(reinterpret_cast<const unsigned char*>(codeExcerpt.c_str()), codeExcerpt.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.init(move(codeController), parser.module);
std::list<string> result = solver.run(parser.module);
ASSERT_EQ(1, result.size());
ASSERT_STREQ("/tmp/logger", result.front().c_str());
}
TEST(Modules, Doc_Requesting_Modules_2){
string codeExcerpt = getDocumentationExampleById("documentation/Syntax/modules.xml", "Requesting_Modules_2");
string codeController = R"Code(
modules_resolution(stringslib, "/tmp/stringslib").
modules_resolution(mathlib, "/tmp/mathlib").
)Code";
Scanner scanner(reinterpret_cast<const unsigned char*>(codeExcerpt.c_str()), codeExcerpt.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.init(move(codeController), parser.module);
std::list<string> result = solver.run(parser.module);
ASSERT_EQ(2, result.size());
ASSERT_STREQ("/tmp/stringslib", result.front().c_str());
ASSERT_STREQ("/tmp/mathlib", result.back().c_str());
}
TEST(Modules, Doc_ModuleAnnotations_1){
string codeExcerpt = getDocumentationExampleById("documentation/Syntax/modules.xml", "ModuleAnnotations_1");
Scanner scanner(reinterpret_cast<const unsigned char*>(codeExcerpt.c_str()), codeExcerpt.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.init("", parser.module);
string program = solver.__program.str();
ASSERT_NE(string::npos, program.find("bind_module(\"\", status(obsolete))."));
}
TEST(Modules, Doc_ModulesResolution_1){
string codeExcerpt = getDocumentationExampleById("documentation/Syntax/modules.xml", "ModulesResolution_1");
string codeModule = R"Code(
module {require(numlib). require(strings)}
)Code";
//use ModuleA as a current module
codeExcerpt.replace(codeExcerpt.find("moduleA"), 7, "");
Scanner scanner(reinterpret_cast<const unsigned char*>(codeModule.c_str()), codeModule.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.init(codeExcerpt, parser.module);
std::list<string> result = solver.run(parser.module);
ASSERT_EQ(2, result.size());
ASSERT_STREQ("/path/to/numlib", result.front().c_str());
ASSERT_STREQ("/path/to/ansi-lib", result.back().c_str());
}
TEST(Modules, Doc_AdvModRes_1){
string code = getDocumentationExampleById("documentation/Syntax/modules.xml", "AdvModRes_1");
size_t posCodeA = code.find("//First Module");
size_t posCodeB = code.find("//Second Module");
size_t posCodeMain = code.find("//Third Module");
string codeA = code.substr(posCodeA, posCodeB - posCodeA);
string codeB = code.substr(posCodeB, posCodeMain - posCodeB);
string codeMain = code.substr(posCodeMain);
const std::string dirModulesRoot = "/tmp/testModulesDiscovery1_t54724/";
replace(codeMain, string("/modules/path/"), dirModulesRoot);
replace(codeMain, string("/path/to/controller"), dirModulesRoot + "controller");
cout << codeMain << endl;
string codeController =
R"Code(
status_score(0, needToTestEvenMore).
status_score(1, needToTest).
module_include_candidate(Request, Y):-
bind_module(Y, provide(Request)).
module_include_winner(Request, MaxScore) :-
MaxScore = #max{Score: module_include_candidate(Request, Y), bind_module(Y, status(Status)), status_score(Score, Status)};
modules_require(_, Request).
modules_resolution(Request, Y) :-
module_include_winner(Request, MaxScore);
bind_module(Y, provide(Request));
bind_module(Y, status(Status));
status_score(MaxScore, Status).
)Code";
fs::create_directories(dirModulesRoot);
fs::ofstream fileA(dirModulesRoot + "a.xreate");
fileA << codeA;
fileA.close();
fs::ofstream fileB(dirModulesRoot + "b.xreate");
fileB << codeB;
fileB.close();
fs::ofstream fileController(dirModulesRoot + "controller");
fileController << codeController;
fileController.close();
Scanner scanner(reinterpret_cast<const unsigned char*>(codeMain.c_str()), codeMain.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
solver.init("", parser.module);
fs::remove_all(dirModulesRoot);
cout << solver.__program.str() << endl;
std::list<std::string> modulesRequired = solver.run(parser.module);
ASSERT_EQ(1, modulesRequired.size());
string moduleActualRequired = modulesRequired.front();
string moduleExpected = dirModulesRoot + "b.xreate";
ASSERT_EQ(moduleExpected, moduleActualRequired);
}
TEST(Modules_API, Doc_ModAnn_1){
string program = getDocumentationExampleById("documentation/Transcend/modules-api.xml", "ModAnn_1");
string outputExpected = getDocumentationExampleById("documentation/Transcend/modules-api.xml", "Output_ModAnn_1");
replace(outputExpected, "/path/to/module", "");
auto xreate = new xreate::details::tier1::XreateManagerImpl<XreateManagerDecoratorModules<XreateManagerDecoratorFull>>();
testing::internal::CaptureStdout();
xreate->prepareCode(std::move(program));
xreate->analyse();
std::string outputActual = testing::internal::GetCapturedStdout();
ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}
TEST(Modules_API, Doc_ReqMod_1){
string program = getDocumentationExampleById("documentation/Transcend/modules-api.xml", "ReqMod_1");
string outputExpected = getDocumentationExampleById("documentation/Transcend/modules-api.xml", "Output_ReqMod_1");
replace(outputExpected, "/path/to/module", "");
Scanner scanner(reinterpret_cast<const unsigned char*>(program.c_str()), program.size());
Parser parser(&scanner);
parser.Parse();
ModulesSolver solver;
testing::internal::CaptureStdout();
solver.init("", parser.module);
std::string outputActual = testing::internal::GetCapturedStdout();
ASSERT_NE(std::string::npos, outputActual.find(outputExpected));
}

Event Timeline