scansion/stanzacmp.lua

Sun, 30 Dec 2018 09:43:36 +0000

author
Matthew Wild <mwild1@gmail.com>
date
Sun, 30 Dec 2018 09:43:36 +0000
changeset 164
14500a149b31
parent 153
f83ea6e5c3d8
child 170
db73c4c317ce
permissions
-rw-r--r--

client: Ignore timeout timer if we received a stanza

6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 -- This is my attempt at a utility library to compare two XMPP stanzas
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 -- It is not testing for exact equivalency, but through some vague rules that felt right.
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 -- For example, the second stanza passed to stanzas_match() is allowed to have unexpected
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 -- elements and attributes at the top level. Beyond this, they must match exactly, except
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 -- for whitespace differences only.
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 --
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 -- There are probably bugs, and it can probably be smarter, but I don't want to spend too
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 -- much time on it right now.
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 local function trim(s)
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 return (s:gsub("^%s+", ""):gsub("%s+$", ""));
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13
153
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
14 local function wants_strict(tag, default)
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
15 local opt = tag.attr["scansion:strict"] or default or "yes";
99
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
16 if opt == "no" or opt == "false" or opt == "0" then
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
17 return false;
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
18 elseif opt == "yes" or opt == "true" or opt == "1" then
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
19 return true;
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
20 end
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
21 error("Unexpected scansion:strict value: "..opt);
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
22 end
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
23
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 local function stanzas_strict_match(stanza1, stanza2)
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 if stanza1.name ~= stanza2.name or stanza1.attr.xmlns ~= stanza2.attr.xmlns then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 for k, v in pairs(stanza1.attr) do
99
dc56d434e406 stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour
Matthew Wild <mwild1@gmail.com>
parents: 92
diff changeset
30 if not k:match("^scansion:") and v ~= "{scansion:any}" and stanza2.attr[k] ~= v then
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 for k, v in pairs(stanza2.attr) do
116
b8296f44a9d1 stanzacmp: Don't look for scansion control attrs in comparison stanza
Matthew Wild <mwild1@gmail.com>
parents: 101
diff changeset
36 if stanza1.attr[k] ~= "{scansion:any}" and stanza1.attr[k] ~= v then
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 if #stanza1.tags ~= #stanza2.tags then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 local stanza2_pos = 1;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 for _, child in ipairs(stanza1) do
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 if type(child) == "table" or child:match("%S") then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 local match;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 local child2 = stanza2[stanza2_pos];
32
0eabed6c91e7 stanzacmp: Check the correct side of the comparsion for whitespace
Kim Alvefur <zash@zash.se>
parents: 6
diff changeset
50 while child2 and not(type(child2) == "table" or child2:match("%S")) do
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 stanza2_pos = stanza2_pos + 1;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 child2 = stanza2[stanza2_pos];
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 if type(child) ~= type(child2) then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 if type(child) == "table" and child2.name == child.name and child2.attr.xmlns == child.attr.xmlns then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 -- Strict deep match
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 match = stanzas_strict_match(child, child2);
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 elseif type(child) == "string" then -- Text nodes, must be equal, ignoring leading/trailing whitespace
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 match = trim(child) == trim(child2);
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 if not match then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 end
101
91a9e557e0e5 stanzacmp + tests: Advance through matching stanza on successful match
Matthew Wild <mwild1@gmail.com>
parents: 99
diff changeset
66 stanza2_pos = stanza2_pos + 1;
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 return true;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 -- Everything in stanza1 should be present in stanza2
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 local function stanzas_match(stanza1, stanza2)
153
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
75 if wants_strict(stanza1, stanza1.attr.xmlns == nil and "no" or "yes") then
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
76 return stanzas_strict_match(stanza1, stanza2);
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
77 end
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 if stanza1.name ~= stanza2.name or stanza1.attr.xmlns ~= stanza2.attr.xmlns then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 for k, v in pairs(stanza1.attr) do
151
8191f165b9dd stanzacmp: Fix for {scansion:any} in top-level attributes being ignored
Matthew Wild <mwild1@gmail.com>
parents: 116
diff changeset
83 if not k:match("^scansion:") and v ~= "{scansion:any}" and stanza2.attr[k] ~= v then
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
88 local matched_children = {};
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 for _, child in ipairs(stanza1) do
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 if type(child) == "table" or child:match("%S") then
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 local match;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 -- Iterate through remaining nodes in stanza2, looking for a match
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
93 local stanza2_pos = 1;
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 while stanza2_pos <= #stanza2 do
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
95 if not matched_children[stanza2_pos] then
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
96 local child2 = stanza2[stanza2_pos];
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
97 stanza2_pos = stanza2_pos + 1;
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
99 if type(child2) == type(child) then
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
100 if type(child) == "table" and child2.name == child.name and child2.attr.xmlns == child.attr.xmlns then
153
f83ea6e5c3d8 stanzacmp: Allow scansion:strict at the top level of the stanza
Matthew Wild <mwild1@gmail.com>
parents: 151
diff changeset
101 match = stanzas_match(child, child2);
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
102 elseif type(child) == "string" then -- Text nodes, must be equal, ignoring leading/trailing whitespace
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
103 match = trim(child) == trim(child2);
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
104 end
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
105 if match then
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
106 break;
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
107 end
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 if not match then
92
9a58c8ee0757 stanzacmp: A new iteration of the stanza matching algorithm
Matthew Wild <mwild1@gmail.com>
parents: 91
diff changeset
112 --print(_, "No match for ", child:pretty_print())
6
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 return false;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 return true;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 end
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 return {
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 stanzas_match = stanzas_match;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 stanzas_strict_match = stanzas_strict_match;
0c94ea0cabec client: Implement send/receive, including new stanzacmp library
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 };

mercurial