blob: e0085576726dd2749cb0d64355c3964ede37cfae [file] [log] [blame]
/*
* Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
* Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
*
* Written by Václav Kubernát <kubervac@fit.cvut.cz>
*
*/
#include "trompeloeil_doctest.hpp"
#include "ast_commands.hpp"
#include "parser.hpp"
#include "pretty_printers.hpp"
#include "static_schema.hpp"
TEST_CASE("ls")
{
auto schema = std::make_shared<StaticSchema>();
schema->addModule("example");
schema->addModule("second");
schema->addContainer("/", "example:a");
schema->addList("/example:a", "example:listInCont", {"number"});
schema->addContainer("/example:a/example:listInCont", "example:contInList");
schema->addContainer("/", "second:a");
schema->addContainer("/", "example:b");
schema->addContainer("/example:a", "example:a2");
schema->addContainer("/example:b", "example:b2");
schema->addContainer("/example:a/example:a2", "example:a3");
schema->addContainer("/example:b/example:b2", "example:b3");
schema->addList("/", "example:list", {"number"});
schema->addLeaf("/example:list", "example:number", yang::Int32{});
schema->addContainer("/example:list", "example:contInList");
schema->addList("/", "example:twoKeyList", {"number", "name"});
schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Parser parser(schema);
std::string input;
std::ostringstream errorStream;
SECTION("valid input")
{
ls_ expected;
SECTION("no arguments")
{
SECTION("ls")
{
input = "ls";
}
SECTION("ls --recursive")
{
input = "ls --recursive";
expected.m_options.emplace_back(LsOption::Recursive);
}
}
SECTION("with path argument")
{
SECTION("ls example:a")
{
input = "ls example:a";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}};
}
SECTION("ls /example:a")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /example:a";
expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"})}};
}
SECTION("ls /")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /";
expected.m_path = dataPath_{Scope::Absolute, {}};
}
SECTION("going up from a node with no children")
{
parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"second"}, container_{"a"})}});
REQUIRE(schema->availableNodes(parser.currentPath(), Recursion::NonRecursive) == std::set<ModuleNodePair>{});
input = "ls ../example:a";
expected.m_path = dataPath_{Scope::Relative, {
dataNode_{nodeup_{}},
dataNode_{module_{"example"}, container_{"a"}}
}};
}
SECTION("ls example:a/a2")
{
input = "ls example:a/a2";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
dataNode_(container_{"a2"})}};
}
SECTION("ls a2")
{
parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});
input = "ls a2";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(container_{"a2"})}};
}
SECTION("ls /example:a/a2")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /example:a/a2";
expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"}),
dataNode_(container_{"a2"})}};
}
SECTION("ls example:a/example:a2")
{
input = "ls example:a/example:a2";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls example:a2")
{
parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}});
input = "ls example:a2";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls /example:a/example:a2")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /example:a/example:a2";
expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"}),
dataNode_(module_{"example"}, container_{"a2"})}};
}
SECTION("ls --recursive /example:a")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls --recursive /example:a";
expected.m_options.emplace_back(LsOption::Recursive);
expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, container_{"a"})}};
}
SECTION("ls example:list")
{
input = "ls example:list";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, list_{"list"})}};
}
SECTION("ls /example:list")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /example:list";
expected.m_path = dataPath_{Scope::Absolute, {dataNode_(module_{"example"}, list_{"list"})}};
}
SECTION("ls example:a/example:listInCont")
{
input = "ls example:a/example:listInCont";
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"}),
dataNode_(module_{"example"}, list_{"listInCont"})}};
}
SECTION("ls example:a/example:listInCont/example:contInList")
{
input = "ls example:a/example:listInCont/example:contInList";
expected.m_path = schemaPath_{Scope::Relative, {schemaNode_(module_{"example"}, container_{"a"}),
schemaNode_(module_{"example"}, list_{"listInCont"}),
schemaNode_(module_{"example"}, container_{"contInList"})}};
}
SECTION("ls example:list[number=342]/contInList")
{
input = "ls example:list[number=342]/contInList";
auto keys = ListInstance{
{"number", int32_t{342}}};
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, listElement_{"list", keys}),
dataNode_(container_{"contInList"})}};
}
SECTION("ls example:list/contInList")
{
input = "ls example:list/contInList";
expected.m_path = schemaPath_{Scope::Relative, {schemaNode_(module_{"example"}, list_{"list"}),
schemaNode_(container_{"contInList"})}};
}
SECTION("ls example:list/example:contInList")
{
input = "ls example:list/example:contInList";
expected.m_path = schemaPath_{Scope::Relative, {schemaNode_(module_{"example"}, list_{"list"}),
schemaNode_(module_{"example"},container_{"contInList"})}};
}
SECTION("ls example:list[number=343]/..")
{
input = "ls example:list[number=343]/..";
auto keys = ListInstance{
{"number", int32_t{343}}};
expected.m_path = dataPath_{Scope::Relative, {dataNode_(module_{"example"}, listElement_{"list", keys}), dataNode_{nodeup_{}}}};
}
SECTION("ls example:list/..")
{
input = "ls example:list/..";
expected.m_path = schemaPath_{Scope::Relative, {schemaNode_(module_{"example"}, list_{"list"}), schemaNode_{nodeup_{}}}};
}
SECTION("ls example:*")
{
input = "ls example:*";
expected.m_path = module_{"example"};
}
}
command_ command = parser.parseCommand(input, errorStream);
REQUIRE(command.type() == typeid(ls_));
REQUIRE(boost::get<ls_>(command) == expected);
}
SECTION("invalid input")
{
SECTION("invalid path")
{
SECTION("ls example:nonexistent")
input = "ls example:nonexistent";
SECTION("ls /example:nonexistent")
input = "ls /example:nonexistent";
SECTION("ls /exa")
{
SECTION("cwd: /") { }
SECTION("cwd: /example:a") { parser.changeNode(dataPath_{Scope::Relative, {dataNode_(module_{"example"}, container_{"a"})}}); }
input = "ls /exa";
}
SECTION("ls /bad:nonexistent")
input = "ls /bad:nonexistent";
SECTION("ls example:a/nonexistent")
input = "ls example:a/nonexistent";
SECTION("ls /example:a/nonexistent")
input = "ls /example:a/nonexistent";
}
SECTION("whitespace before path")
{
SECTION("ls --recursive/")
input = "ls --recursive/";
SECTION("ls/")
input = "ls/";
SECTION("ls --recursive/example:a")
input = "ls --recursive/example:a";
SECTION("ls/example:a")
input = "ls/example:a";
SECTION("lssecond:a")
input = "lssecond:a";
}
REQUIRE_THROWS_AS(parser.parseCommand(input, errorStream), InvalidCommandException);
}
}