blob: b725dff242a4def9306362ce12bb0bbe459b767e [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();
36 Parser parser(schema, dataQuery);
37 std::string input;
38 std::ostringstream errorStream;
39
40 std::set<std::string> expected;
41 std::vector<std::shared_ptr<trompeloeil::expectation>> queryExpectations;
42 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 };
59 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:list"))
60 .RETURN(queryReturn));
61 }
62
63 SECTION("get example:twoKeyList[number=")
64 {
65 queryReturn = {
66 {{"number", 1}, {"name", std::string{"Petr"}}},
67 {{"number", 7}, {"name", std::string{"Petr"}}},
68 {{"number", 10}, {"name", std::string{"Petr"}}},
69 {{"number", 10}, {"name", std::string{"Honza"}}},
70 {{"number", 100}, {"name", std::string{"Honza"}}},
71 };
72 input = "get example:twoKeyList[";
73 SECTION("no keys set")
74 {
75 SECTION("number")
76 {
77 input += "number=";
78 expected = { "1", "7", "10", "100" };
79 }
80 SECTION("name")
81 {
82 input += "name=";
83 expected = { "'Petr'", "'Honza'"};
84 }
85 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
86 .RETURN(queryReturn));
87 }
88
89 SECTION("name is set")
90 {
91 input += "name=";
92 SECTION("Petr")
93 {
94 input += "'Petr'";
95 expected = { "1", "7", "10"};
96 }
97 SECTION("Honza")
98 {
99 input += "'Honza'";
100 expected = { "10", "100" };
101 }
102 input += "][number=";
103 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
104 .TIMES(2)
105 .RETURN(queryReturn));
106 }
107
108 SECTION("number is set")
109 {
110 input += "number=";
111 SECTION("1")
112 {
113 input += "1";
114 expected = { "'Petr'" };
115 }
116 SECTION("7")
117 {
118 input += "7";
119 expected = { "'Petr'" };
120 }
121 SECTION("10")
122 {
123 input += "10";
124 expected = { "'Honza'", "'Petr'" };
125 }
126 SECTION("100")
127 {
128 input += "100";
129 expected = { "'Honza'" };
130 }
131 input += "][name=";
132 queryExpectations.push_back(NAMED_REQUIRE_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
133 .TIMES(2)
134 .RETURN(queryReturn));
135 }
136
137 SECTION("both keys are set")
138 {
139 SECTION("get example:twoKeyList[number=123][name='Petr'")
140 {
141 input = "get example:twoKeyList[number=123][name='Petr'";
142 expected = {"]/"};
143 }
144 SECTION("get example:twoKeyList[number=123][name='Petr']")
145 {
146 input = "get example:twoKeyList[number=123][name='Petr']";
147 expected = {"]/"};
148 }
149 SECTION("get example:twoKeyList[number=123][name='Petr'][")
150 {
151 input = "get example:twoKeyList[number=123][name='Petr'][";
152 }
153 // I use ALLOW_CALL here, all this stuff calls it different number of times
154 queryExpectations.push_back(NAMED_ALLOW_CALL(*mockDatastore, listInstances("/example:twoKeyList"))
155 .RETURN(queryReturn));
156 }
157
158 }
159
160 REQUIRE(parser.completeCommand(input, errorStream).m_completions == expected);
161 for (auto& it : queryExpectations) {
162 it.reset();
163 }
164}