Software /
code /
prosody
File
spec/util_datamapper_spec.lua @ 13146:771eb453e03a
util.sqlite3: Deduplicate query methods
There were 3 very similar methods:
- :execute()
- :execute_query()
- :execute_update()
The first one returns the prepared statement and is mainly used
internally in the library for CREATE statements.
The later two only really differ in how the results are returned.
Those two are one main method and one small one that only picks out the
iterator.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 10 Jun 2023 22:02:15 +0200 |
parent | 12818:74ed772ff5fb |
line wrap: on
line source
local st local xml local map setup(function() st = require "util.stanza"; xml = require "util.xml"; map = require "util.datamapper"; end); describe("util.datamapper", function() local s, x, d local disco, disco_info, disco_schema setup(function() -- a convenience function for simple attributes, there's a few of them local attr = {["$ref"]="#/$defs/attr"}; s = { ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; type = "object"; xml = {name = "message"; namespace = "jabber:client"}; properties = { to = attr; from = attr; type = attr; id = attr; body = true; -- should be assumed to be a string lang = {type = "string"; xml = {attribute = true; prefix = "xml"}}; delay = { type = "object"; xml = {namespace = "urn:xmpp:delay"; name = "delay"}; properties = {stamp = attr; from = attr; reason = {type = "string"; xml = {text = true}}}; }; state = { type = "string"; enum = { "active", "inactive", "gone", "composing", "paused", }; xml = {x_name_is_value = true; namespace = "http://jabber.org/protocol/chatstates"}; }; fallback = { type = "boolean"; xml = {x_name_is_value = true; name = "fallback"; namespace = "urn:xmpp:fallback:0"}; }; origin_id = { type = "string"; xml = {name = "origin-id"; namespace = "urn:xmpp:sid:0"; x_single_attribute = "id"}; }; react = { type = "object"; xml = {namespace = "urn:xmpp:reactions:0"; name = "reactions"}; properties = { to = {type = "string"; xml = {attribute = true; name = "id"}}; -- should be assumed to be array since it has 'items' reactions = { items = { xml = { name = "reaction" } } }; }; }; stanza_ids = { type = "array"; items = { xml = {name = "stanza-id"; namespace = "urn:xmpp:sid:0"}; type = "object"; properties = { id = attr; by = attr; }; }; }; }; }; x = xml.parse [[ <message xmlns="jabber:client" xml:lang="en" to="a@test" from="b@test" type="chat" id="1"> <body>Hello</body> <delay xmlns='urn:xmpp:delay' from='test' stamp='2021-03-07T15:59:08+00:00'>Because</delay> <UNRELATED xmlns='http://jabber.org/protocol/chatstates'/> <active xmlns='http://jabber.org/protocol/chatstates'/> <fallback xmlns='urn:xmpp:fallback:0'/> <origin-id xmlns='urn:xmpp:sid:0' id='qgkmMdPB'/> <stanza-id xmlns='urn:xmpp:sid:0' id='abc1' by='muc'/> <stanza-id xmlns='urn:xmpp:sid:0' id='xyz2' by='host'/> <reactions id='744f6e18-a57a-11e9-a656-4889e7820c76' xmlns='urn:xmpp:reactions:0'> <reaction>👋</reaction> <reaction>🐢</reaction> </reactions> </message> ]]; d = { to = "a@test"; from = "b@test"; type = "chat"; id = "1"; lang = "en"; body = "Hello"; delay = {from = "test"; stamp = "2021-03-07T15:59:08+00:00"; reason = "Because"}; state = "active"; fallback = true; origin_id = "qgkmMdPB"; stanza_ids = {{id = "abc1"; by = "muc"}; {id = "xyz2"; by = "host"}}; react = { to = "744f6e18-a57a-11e9-a656-4889e7820c76"; reactions = { "👋", "🐢", }; }; }; disco_schema = { ["$defs"] = { attr = { type = "string"; xml = { attribute = true } } }; type = "object"; xml = { name = "iq"; namespace = "jabber:client" }; properties = { to = attr; from = attr; type = attr; id = attr; disco = { type = "object"; xml = { name = "query"; namespace = "http://jabber.org/protocol/disco#info" }; properties = { features = { type = "array"; items = { type = "string"; xml = { name = "feature"; x_single_attribute = "var"; }; }; }; }; }; }; }; disco_info = xml.parse[[ <iq type="result" id="disco1" from="example.com"> <query xmlns="http://jabber.org/protocol/disco#info"> <feature var="urn:example:feature:1">wrong</feature> <feature var="urn:example:feature:2"/> <feature var="urn:example:feature:3"/> <unrelated var="urn:example:feature:not"/> </query> </iq> ]]; disco = { type="result"; id="disco1"; from="example.com"; disco = { features = { "urn:example:feature:1"; "urn:example:feature:2"; "urn:example:feature:3"; }; }; }; end); describe("parse", function() it("works", function() assert.same(d, map.parse(s, x)); end); it("handles arrays", function () assert.same(disco, map.parse(disco_schema, disco_info)); end); it("deals with locally built stanzas", function() -- FIXME this could also be argued to be a util.stanza problem local ver_schema = { type = "object"; xml = {name = "iq"}; properties = { type = {type = "string"; xml = {attribute = true}}; id = {type = "string"; xml = {attribute = true}}; version = { type = "object"; xml = {name = "query"; namespace = "jabber:iq:version"}; -- properties should be assumed to be strings properties = {name = true; version = {}; os = {}}; }; }; }; local ver_st = st.iq({type = "result"; id = "v1"}) :query("jabber:iq:version") :text_tag("name", "Prosody") :text_tag("version", "trunk") :text_tag("os", "Lua 5.3") :reset(); local data = {type = "result"; id = "v1"; version = {name = "Prosody"; version = "trunk"; os = "Lua 5.3"}} assert.same(data, map.parse(ver_schema, ver_st)); end); end); describe("unparse", function() it("works", function() local u = map.unparse(s, d); assert.equal("message", u.name); assert.same(x.attr, u.attr); assert.equal(x:get_child_text("body"), u:get_child_text("body")); assert.equal(x:get_child_text("delay", "urn:xmpp:delay"), u:get_child_text("delay", "urn:xmpp:delay")); assert.same(x:get_child("delay", "urn:xmpp:delay").attr, u:get_child("delay", "urn:xmpp:delay").attr); assert.same(x:get_child("origin-id", "urn:xmpp:sid:0").attr, u:get_child("origin-id", "urn:xmpp:sid:0").attr); assert.same(x:get_child("reactions", "urn:xmpp:reactions:0").attr, u:get_child("reactions", "urn:xmpp:reactions:0").attr); assert.same(2, #u:get_child("reactions", "urn:xmpp:reactions:0").tags); for _, tag in ipairs(x.tags) do if tag.name ~= "UNRELATED" then assert.truthy(u:get_child(tag.name, tag.attr.xmlns) or u:get_child(tag.name), tag:top_tag()) end end assert.equal(#x.tags-1, #u.tags) end); it("handles arrays", function () local u = map.unparse(disco_schema, disco); assert.equal("urn:example:feature:1", u:find("{http://jabber.org/protocol/disco#info}query/feature/@var")) local n = 0; for child in u:get_child("query", "http://jabber.org/protocol/disco#info"):childtags("feature") do n = n + 1; assert.equal(string.format("urn:example:feature:%d", n), child.attr.var); end end); end); end)