blob: 7b28ea837bca29c9950eaa2abad1d584362ad3a5 [file] [log] [blame]
Václav Kubernát43908fb2020-01-02 19:05:51 +01001/*
2 * Copyright (C) 2020 CESNET, https://photonics.cesnet.cz/
3 *
4 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
5 *
6*/
7
8#include <experimental/iterator>
9#include <iostream>
Václav Kubernát26b56082020-02-03 18:28:56 +010010#include "trompeloeil_doctest.hpp"
Václav Kubernát43908fb2020-01-02 19:05:51 +010011#include "ast_commands.hpp"
12#include "datastoreaccess_mock.hpp"
13#include "parser.hpp"
Václav Kubernáted824d02020-06-09 15:48:30 +020014#include "pretty_printers.hpp"
Václav Kubernát43908fb2020-01-02 19:05:51 +010015#include "static_schema.hpp"
16
Václav Kubernát43908fb2020-01-02 19:05:51 +010017
18TEST_CASE("keyvalue_completion")
19{
20 auto schema = std::make_shared<StaticSchema>();
21 schema->addModule("example");
22 schema->addContainer("/", "example:a");
23 schema->addContainer("/", "example:b");
24 schema->addList("/", "example:list", {"number"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020025 schema->addLeaf("/example:list", "example:number", yang::Int32{});
Václav Kubernát43908fb2020-01-02 19:05:51 +010026 schema->addList("/", "example:twoKeyList", {"number", "name"});
Václav Kubernát3a99f002020-03-31 02:27:41 +020027 schema->addLeaf("/example:twoKeyList", "example:number", yang::Int32{});
28 schema->addLeaf("/example:twoKeyList", "example:name", yang::String{});
Václav Kubernát43908fb2020-01-02 19:05:51 +010029 auto mockDatastore = std::make_shared<MockDatastoreAccess>();
30
31 // DataQuery gets the schema from DatastoreAccess once
32 auto expectation = NAMED_REQUIRE_CALL(*mockDatastore, schema())
33 .RETURN(schema);
34 auto dataQuery = std::make_shared<DataQuery>(*mockDatastore);
35 expectation.reset();
Václav Kubernát28cf3362020-06-29 17:52:51 +020036 Parser parser(schema, WritableOps::No, dataQuery);
Václav Kubernát43908fb2020-01-02 19:05:51 +010037 std::string input;
38 std::ostringstream errorStream;
39
40 std::set<std::string> expected;
Václav Kubernátf8ce1bc2020-06-11 10:33:49 +020041 std::vector<std::unique_ptr<trompeloeil::expectation>> queryExpectations;
Václav Kubernát43908fb2020-01-02 19:05:51 +010042 std::vector<ListInstance> queryReturn;
43
44 SECTION("get example:list[number=")
45 {
46 input = "get example:list[number=";
47 queryReturn = {
48 {{"number", 1}},
49 {{"number", 7}},
50 {{"number", 9}},
51 {{"number", 42}}
52 };
53 expected = {
54 "1",
55 "7",
56 "9",
57 "42"
58 };
Václav Kubernátfaacd022020-07-08 16:44:38 +020059 queryExpectations.emplace_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:list")).RETURN(queryReturn));
Václav Kubernát43908fb2020-01-02 19:05:51 +010060 }
61
62 SECTION("get example:twoKeyList[number=")
63 {
64 queryReturn = {
65 {{"number", 1}, {"name", std::string{"Petr"}}},
66 {{"number", 7}, {"name", std::string{"Petr"}}},
67 {{"number", 10}, {"name", std::string{"Petr"}}},
68 {{"number", 10}, {"name", std::string{"Honza"}}},
69 {{"number", 100}, {"name", std::string{"Honza"}}},
70 };
71 input = "get example:twoKeyList[";
72 SECTION("no keys set")
73 {
74 SECTION("number")
75 {
76 input += "number=";
77 expected = { "1", "7", "10", "100" };
78 }
79 SECTION("name")
80 {
81 input += "name=";
82 expected = { "'Petr'", "'Honza'"};
83 }
Václav Kubernátfaacd022020-07-08 16:44:38 +020084 queryExpectations.emplace_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList")).RETURN(queryReturn));
Václav Kubernát43908fb2020-01-02 19:05:51 +010085 }
86
87 SECTION("name is set")
88 {
89 input += "name=";
90 SECTION("Petr")
91 {
92 input += "'Petr'";
93 expected = { "1", "7", "10"};
94 }
95 SECTION("Honza")
96 {
97 input += "'Honza'";
98 expected = { "10", "100" };
99 }
100 input += "][number=";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200101 queryExpectations.emplace_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
Václav Kubernát43908fb2020-01-02 19:05:51 +0100102 .TIMES(2)
103 .RETURN(queryReturn));
104 }
105
106 SECTION("number is set")
107 {
108 input += "number=";
109 SECTION("1")
110 {
111 input += "1";
112 expected = { "'Petr'" };
113 }
114 SECTION("7")
115 {
116 input += "7";
117 expected = { "'Petr'" };
118 }
119 SECTION("10")
120 {
121 input += "10";
122 expected = { "'Honza'", "'Petr'" };
123 }
124 SECTION("100")
125 {
126 input += "100";
127 expected = { "'Honza'" };
128 }
129 input += "][name=";
Václav Kubernátfaacd022020-07-08 16:44:38 +0200130 queryExpectations.emplace_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
Václav Kubernát43908fb2020-01-02 19:05:51 +0100131 .TIMES(2)
132 .RETURN(queryReturn));
133 }
134
135 SECTION("both keys are set")
136 {
137 SECTION("get example:twoKeyList[number=123][name='Petr'")
138 {
139 input = "get example:twoKeyList[number=123][name='Petr'";
140 expected = {"]/"};
141 }
142 SECTION("get example:twoKeyList[number=123][name='Petr']")
143 {
144 input = "get example:twoKeyList[number=123][name='Petr']";
145 expected = {"]/"};
146 }
147 SECTION("get example:twoKeyList[number=123][name='Petr'][")
148 {
149 input = "get example:twoKeyList[number=123][name='Petr'][";
150 }
151 // I use ALLOW_CALL here, all this stuff calls it different number of times
Václav Kubernátfaacd022020-07-08 16:44:38 +0200152 queryExpectations.emplace_back(NAMED_ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
Václav Kubernát43908fb2020-01-02 19:05:51 +0100153 .RETURN(queryReturn));
154 }
155
156 }
157
158 REQUIRE(parser.completeCommand(input, errorStream).m_completions == expected);
Václav Kubernát43908fb2020-01-02 19:05:51 +0100159}