Mercurial > hg > orthanc
comparison OrthancServer/UnitTestsSources/LuaTests.cpp @ 4044:d25f4c0fa160 framework
splitting code into OrthancFramework and OrthancServer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 10 Jun 2020 20:30:34 +0200 |
parents | UnitTestsSources/LuaTests.cpp@058b5ade8acd |
children | 05b8fd21089c |
comparison
equal
deleted
inserted
replaced
4043:6c6239aec462 | 4044:d25f4c0fa160 |
---|---|
1 /** | |
2 * Orthanc - A Lightweight, RESTful DICOM Store | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2020 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU General Public License as | |
9 * published by the Free Software Foundation, either version 3 of the | |
10 * License, or (at your option) any later version. | |
11 * | |
12 * In addition, as a special exception, the copyright holders of this | |
13 * program give permission to link the code of its release with the | |
14 * OpenSSL project's "OpenSSL" library (or with modified versions of it | |
15 * that use the same license as the "OpenSSL" library), and distribute | |
16 * the linked executables. You must obey the GNU General Public License | |
17 * in all respects for all of the code used other than "OpenSSL". If you | |
18 * modify file(s) with this exception, you may extend this exception to | |
19 * your version of the file(s), but you are not obligated to do so. If | |
20 * you do not wish to do so, delete this exception statement from your | |
21 * version. If you delete this exception statement from all source files | |
22 * in the program, then also delete it here. | |
23 * | |
24 * This program is distributed in the hope that it will be useful, but | |
25 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
27 * General Public License for more details. | |
28 * | |
29 * You should have received a copy of the GNU General Public License | |
30 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
31 **/ | |
32 | |
33 | |
34 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK == 1 | |
35 # include <OrthancFramework.h> | |
36 #endif | |
37 | |
38 #include "PrecompiledHeadersUnitTests.h" | |
39 #include "gtest/gtest.h" | |
40 | |
41 #include "../Core/OrthancException.h" | |
42 #include "../Core/Toolbox.h" | |
43 #include "../Core/Lua/LuaFunctionCall.h" | |
44 | |
45 #include <OrthancServerResources.h> | |
46 | |
47 #include <boost/lexical_cast.hpp> | |
48 | |
49 #if !defined(UNIT_TESTS_WITH_HTTP_CONNEXIONS) | |
50 #error "Please set UNIT_TESTS_WITH_HTTP_CONNEXIONS to 0 or 1" | |
51 #endif | |
52 | |
53 | |
54 TEST(Lua, Json) | |
55 { | |
56 Orthanc::LuaContext lua; | |
57 | |
58 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK != 1 | |
59 { | |
60 std::string command; | |
61 Orthanc::ServerResources::GetFileResource(command, Orthanc::ServerResources::LUA_TOOLBOX); | |
62 lua.Execute(command); | |
63 } | |
64 #endif | |
65 | |
66 lua.Execute("a={}"); | |
67 lua.Execute("a['x'] = 10"); | |
68 lua.Execute("a['y'] = {}"); | |
69 lua.Execute("a['y'][1] = 20"); | |
70 lua.Execute("a['y'][2] = 20"); | |
71 | |
72 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK != 1 | |
73 lua.Execute("PrintRecursive(a)"); | |
74 #endif | |
75 | |
76 lua.Execute("function f(a) print(a.bool) return a.bool,20,30,40,50,60 end"); | |
77 | |
78 Json::Value v, vv, o; | |
79 //v["a"] = "b"; | |
80 v.append("hello"); | |
81 v.append("world"); | |
82 v.append("42"); | |
83 vv.append("sub"); | |
84 vv.append("set"); | |
85 v.append(vv); | |
86 o = Json::objectValue; | |
87 o["x"] = 10; | |
88 o["y"] = 20; | |
89 o["z"] = 20.5f; | |
90 v.append(o); | |
91 | |
92 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK != 1 | |
93 { | |
94 Orthanc::LuaFunctionCall f(lua, "PrintRecursive"); | |
95 f.PushJson(v); | |
96 f.Execute(); | |
97 } | |
98 #endif | |
99 | |
100 { | |
101 Orthanc::LuaFunctionCall f(lua, "f"); | |
102 f.PushJson(o); | |
103 ASSERT_THROW(f.ExecutePredicate(), Orthanc::OrthancException); | |
104 } | |
105 | |
106 o["bool"] = false; | |
107 | |
108 { | |
109 Orthanc::LuaFunctionCall f(lua, "f"); | |
110 f.PushJson(o); | |
111 ASSERT_FALSE(f.ExecutePredicate()); | |
112 } | |
113 | |
114 o["bool"] = true; | |
115 | |
116 { | |
117 Orthanc::LuaFunctionCall f(lua, "f"); | |
118 f.PushJson(o); | |
119 ASSERT_TRUE(f.ExecutePredicate()); | |
120 } | |
121 } | |
122 | |
123 | |
124 TEST(Lua, Existing) | |
125 { | |
126 Orthanc::LuaContext lua; | |
127 lua.Execute("a={}"); | |
128 lua.Execute("function f() end"); | |
129 | |
130 ASSERT_TRUE(lua.IsExistingFunction("f")); | |
131 ASSERT_FALSE(lua.IsExistingFunction("a")); | |
132 ASSERT_FALSE(lua.IsExistingFunction("Dummy")); | |
133 } | |
134 | |
135 | |
136 #if ORTHANC_UNIT_TESTS_LINK_FRAMEWORK != 1 | |
137 TEST(Lua, Simple) | |
138 { | |
139 Orthanc::LuaContext lua; | |
140 | |
141 { | |
142 std::string command; | |
143 Orthanc::ServerResources::GetFileResource(command, Orthanc::ServerResources::LUA_TOOLBOX); | |
144 lua.Execute(command); | |
145 } | |
146 | |
147 { | |
148 Orthanc::LuaFunctionCall f(lua, "PrintRecursive"); | |
149 f.PushString("hello"); | |
150 f.Execute(); | |
151 } | |
152 | |
153 { | |
154 Orthanc::LuaFunctionCall f(lua, "PrintRecursive"); | |
155 f.PushBoolean(true); | |
156 f.Execute(); | |
157 } | |
158 | |
159 { | |
160 Orthanc::LuaFunctionCall f(lua, "PrintRecursive"); | |
161 f.PushInteger(42); | |
162 f.Execute(); | |
163 } | |
164 | |
165 { | |
166 Orthanc::LuaFunctionCall f(lua, "PrintRecursive"); | |
167 f.PushDouble(3.1415); | |
168 f.Execute(); | |
169 } | |
170 } | |
171 #endif | |
172 | |
173 | |
174 TEST(Lua, ReturnJson) | |
175 { | |
176 Json::Value b = Json::objectValue; | |
177 b["a"] = 42; | |
178 b["b"] = 44.37; | |
179 b["c"] = -43; | |
180 | |
181 Json::Value c = Json::arrayValue; | |
182 c.append("test3"); | |
183 c.append("test1"); | |
184 c.append("test2"); | |
185 | |
186 Json::Value a = Json::objectValue; | |
187 a["Hello"] = "World"; | |
188 a["List"] = Json::arrayValue; | |
189 a["List"].append(b); | |
190 a["List"].append(c); | |
191 | |
192 Orthanc::LuaContext lua; | |
193 | |
194 // This is the identity function (it simply returns its input) | |
195 lua.Execute("function identity(a) return a end"); | |
196 | |
197 { | |
198 Orthanc::LuaFunctionCall f(lua, "identity"); | |
199 f.PushJson("hello"); | |
200 Json::Value v; | |
201 f.ExecuteToJson(v, false); | |
202 ASSERT_EQ("hello", v.asString()); | |
203 } | |
204 | |
205 { | |
206 Orthanc::LuaFunctionCall f(lua, "identity"); | |
207 f.PushJson(42.25); | |
208 Json::Value v; | |
209 f.ExecuteToJson(v, false); | |
210 ASSERT_FLOAT_EQ(42.25f, v.asFloat()); | |
211 } | |
212 | |
213 { | |
214 Orthanc::LuaFunctionCall f(lua, "identity"); | |
215 f.PushJson(-42); | |
216 Json::Value v; | |
217 f.ExecuteToJson(v, false); | |
218 ASSERT_EQ(-42, v.asInt()); | |
219 } | |
220 | |
221 { | |
222 Orthanc::LuaFunctionCall f(lua, "identity"); | |
223 Json::Value vv = Json::arrayValue; | |
224 f.PushJson(vv); | |
225 Json::Value v; | |
226 f.ExecuteToJson(v, false); | |
227 ASSERT_EQ(Json::arrayValue, v.type()); | |
228 } | |
229 | |
230 { | |
231 Orthanc::LuaFunctionCall f(lua, "identity"); | |
232 Json::Value vv = Json::objectValue; | |
233 f.PushJson(vv); | |
234 Json::Value v; | |
235 f.ExecuteToJson(v, false); | |
236 // Lua does not make the distinction between empty lists and empty objects | |
237 ASSERT_EQ(Json::arrayValue, v.type()); | |
238 } | |
239 | |
240 { | |
241 Orthanc::LuaFunctionCall f(lua, "identity"); | |
242 f.PushJson(b); | |
243 Json::Value v; | |
244 f.ExecuteToJson(v, false); | |
245 ASSERT_EQ(Json::objectValue, v.type()); | |
246 ASSERT_FLOAT_EQ(42.0f, v["a"].asFloat()); | |
247 ASSERT_FLOAT_EQ(44.37f, v["b"].asFloat()); | |
248 ASSERT_FLOAT_EQ(-43.0f, v["c"].asFloat()); | |
249 } | |
250 | |
251 { | |
252 Orthanc::LuaFunctionCall f(lua, "identity"); | |
253 f.PushJson(c); | |
254 Json::Value v; | |
255 f.ExecuteToJson(v, false); | |
256 ASSERT_EQ(Json::arrayValue, v.type()); | |
257 ASSERT_EQ("test3", v[0].asString()); | |
258 ASSERT_EQ("test1", v[1].asString()); | |
259 ASSERT_EQ("test2", v[2].asString()); | |
260 } | |
261 | |
262 { | |
263 Orthanc::LuaFunctionCall f(lua, "identity"); | |
264 f.PushJson(a); | |
265 Json::Value v; | |
266 f.ExecuteToJson(v, false); | |
267 ASSERT_EQ("World", v["Hello"].asString()); | |
268 ASSERT_EQ(Json::intValue, v["List"][0]["a"].type()); | |
269 ASSERT_EQ(Json::realValue, v["List"][0]["b"].type()); | |
270 ASSERT_EQ(Json::intValue, v["List"][0]["c"].type()); | |
271 ASSERT_EQ(42, v["List"][0]["a"].asInt()); | |
272 ASSERT_FLOAT_EQ(44.37f, v["List"][0]["b"].asFloat()); | |
273 ASSERT_EQ(44, v["List"][0]["b"].asInt()); | |
274 ASSERT_EQ(-43, v["List"][0]["c"].asInt()); | |
275 ASSERT_EQ("test3", v["List"][1][0].asString()); | |
276 ASSERT_EQ("test1", v["List"][1][1].asString()); | |
277 ASSERT_EQ("test2", v["List"][1][2].asString()); | |
278 } | |
279 | |
280 { | |
281 Orthanc::LuaFunctionCall f(lua, "identity"); | |
282 f.PushJson(a); | |
283 Json::Value v; | |
284 f.ExecuteToJson(v, true); | |
285 ASSERT_EQ("World", v["Hello"].asString()); | |
286 ASSERT_EQ(Json::stringValue, v["List"][0]["a"].type()); | |
287 ASSERT_EQ(Json::stringValue, v["List"][0]["b"].type()); | |
288 ASSERT_EQ(Json::stringValue, v["List"][0]["c"].type()); | |
289 ASSERT_FLOAT_EQ(42.0f, boost::lexical_cast<float>(v["List"][0]["a"].asString())); | |
290 ASSERT_FLOAT_EQ(44.37f, boost::lexical_cast<float>(v["List"][0]["b"].asString())); | |
291 ASSERT_FLOAT_EQ(-43.0f, boost::lexical_cast<float>(v["List"][0]["c"].asString())); | |
292 ASSERT_EQ("test3", v["List"][1][0].asString()); | |
293 ASSERT_EQ("test1", v["List"][1][1].asString()); | |
294 ASSERT_EQ("test2", v["List"][1][2].asString()); | |
295 } | |
296 | |
297 { | |
298 Orthanc::LuaFunctionCall f(lua, "DumpJson"); | |
299 f.PushJson(a); | |
300 std::string s; | |
301 f.ExecuteToString(s); | |
302 | |
303 Json::FastWriter writer; | |
304 std::string t = writer.write(a); | |
305 | |
306 ASSERT_EQ(s, t); | |
307 } | |
308 } | |
309 | |
310 | |
311 | |
312 TEST(Lua, Http) | |
313 { | |
314 Orthanc::LuaContext lua; | |
315 | |
316 #if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1 | |
317 // The "http://www.orthanc-server.com/downloads/third-party/" does | |
318 // not automatically redirect to HTTPS, so we cas use it even if the | |
319 // OpenSSL/HTTPS support is disabled in curl | |
320 const std::string BASE = "http://www.orthanc-server.com/downloads/third-party/"; | |
321 | |
322 #if LUA_VERSION_NUM >= 502 | |
323 // Since Lua >= 5.2.0, the function "loadstring" has been replaced by "load" | |
324 lua.Execute("JSON = load(HttpGet('" + BASE + "JSON.lua')) ()"); | |
325 #else | |
326 lua.Execute("JSON = loadstring(HttpGet('" + BASE + "JSON.lua')) ()"); | |
327 #endif | |
328 | |
329 const std::string url(BASE + "Product.json"); | |
330 #endif | |
331 | |
332 std::string s; | |
333 lua.Execute(s, "print(HttpGet({}))"); | |
334 ASSERT_EQ("nil", Orthanc::Toolbox::StripSpaces(s)); | |
335 | |
336 #if UNIT_TESTS_WITH_HTTP_CONNEXIONS == 1 | |
337 lua.Execute(s, "print(string.len(HttpGet(\"" + url + "\")))"); | |
338 ASSERT_LE(100, boost::lexical_cast<int>(Orthanc::Toolbox::StripSpaces(s))); | |
339 | |
340 // Parse a JSON file | |
341 lua.Execute(s, "print(JSON:decode(HttpGet(\"" + url + "\")) ['Product'])"); | |
342 ASSERT_EQ("OrthancClient", Orthanc::Toolbox::StripSpaces(s)); | |
343 | |
344 #if 0 | |
345 // This part of the test can only be executed if one instance of | |
346 // Orthanc is running on the localhost | |
347 | |
348 lua.Execute("modality = {}"); | |
349 lua.Execute("table.insert(modality, 'ORTHANC')"); | |
350 lua.Execute("table.insert(modality, 'localhost')"); | |
351 lua.Execute("table.insert(modality, 4242)"); | |
352 | |
353 lua.Execute(s, "print(HttpPost(\"http://localhost:8042/tools/execute-script\", \"print('hello world')\"))"); | |
354 ASSERT_EQ("hello world", Orthanc::Toolbox::StripSpaces(s)); | |
355 | |
356 lua.Execute(s, "print(JSON:decode(HttpPost(\"http://localhost:8042/tools/execute-script\", \"print('[10,42,1000]')\")) [2])"); | |
357 ASSERT_EQ("42", Orthanc::Toolbox::StripSpaces(s)); | |
358 | |
359 // Add/remove a modality with Lua | |
360 Json::Value v; | |
361 lua.Execute(s, "print(HttpGet('http://localhost:8042/modalities/lua'))"); | |
362 ASSERT_EQ(0, Orthanc::Toolbox::StripSpaces(s).size()); | |
363 lua.Execute(s, "print(HttpPut('http://localhost:8042/modalities/lua', JSON:encode(modality)))"); | |
364 lua.Execute(v, "print(HttpGet('http://localhost:8042/modalities/lua'))"); | |
365 ASSERT_TRUE(v.type() == Json::arrayValue); | |
366 lua.Execute(s, "print(HttpDelete('http://localhost:8042/modalities/lua'))"); | |
367 lua.Execute(s, "print(HttpGet('http://localhost:8042/modalities/lua'))"); | |
368 ASSERT_EQ(0, Orthanc::Toolbox::StripSpaces(s).size()); | |
369 #endif | |
370 | |
371 #endif | |
372 } |