stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour

Thu, 06 Sep 2018 18:26:01 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 06 Sep 2018 18:26:01 +0100
changeset 99
dc56d434e406
parent 98
88a3e03f4b9f
child 100
f2b3e8e6690f

stanzacmp+tests: Add support for scansion:strict to allow override of default behaviour

scansion/stanzacmp.lua file | annotate | diff | comparison | revisions
spec/stanzacmp_spec.lua file | annotate | diff | comparison | revisions
--- a/scansion/stanzacmp.lua	Thu Sep 06 18:23:56 2018 +0100
+++ b/scansion/stanzacmp.lua	Thu Sep 06 18:26:01 2018 +0100
@@ -11,19 +11,29 @@
 	return (s:gsub("^%s+", ""):gsub("%s+$", ""));
 end
 
+local function wants_strict(tag)
+	local opt = tag.attr["scansion:strict"] or "yes";
+	if opt == "no" or opt == "false" or opt == "0" then
+		return false;
+	elseif opt == "yes" or opt == "true" or opt == "1" then
+		return true;
+	end
+	error("Unexpected scansion:strict value: "..opt);
+end
+
 local function stanzas_strict_match(stanza1, stanza2)
 	if stanza1.name ~= stanza2.name or stanza1.attr.xmlns ~= stanza2.attr.xmlns then
 		return false;
 	end
 	
 	for k, v in pairs(stanza1.attr) do
-		if v ~= "{scansion:any}" and stanza2.attr[k] ~= v then
+		if not k:match("^scansion:") and v ~= "{scansion:any}" and stanza2.attr[k] ~= v then
 			return false;
 		end
 	end
 	
 	for k, v in pairs(stanza2.attr) do
-		if stanza1.attr[k] ~= "{scansion:any}" and stanza1.attr[k] ~= v then
+		if not k:match("^scansion:") and stanza1.attr[k] ~= "{scansion:any}" and stanza1.attr[k] ~= v then
 			return false;
 		end
 	end
@@ -66,7 +76,7 @@
 	end
 	
 	for k, v in pairs(stanza1.attr) do
-		if stanza2.attr[k] ~= v then
+		if not k:match("^scansion:") and stanza2.attr[k] ~= v then
 			return false;
 		end
 	end
@@ -84,8 +94,12 @@
 
 					if type(child2) == type(child) then
 						if type(child) == "table" and child2.name == child.name and child2.attr.xmlns == child.attr.xmlns then
-							-- Strict deep match
-							match = stanzas_strict_match(child, child2);
+							if wants_strict(child) then
+								-- Strict deep match
+								match = stanzas_strict_match(child, child2);
+							else
+								match = stanzas_match(child, child2);
+							end
 						elseif type(child) == "string" then -- Text nodes, must be equal, ignoring leading/trailing whitespace
 							match = trim(child) == trim(child2);
 						end
--- a/spec/stanzacmp_spec.lua	Thu Sep 06 18:23:56 2018 +0100
+++ b/spec/stanzacmp_spec.lua	Thu Sep 06 18:26:01 2018 +0100
@@ -109,4 +109,16 @@
 		
 		yes(s01, s02);
 	end);
+
+	it("should match unordered children at the top level", function ()
+		yes("<foo><one/><two/></foo>", "<foo><two/><one/></foo>");
+	end);
+
+	it("should not match unordered children", function ()
+		no("<foo><one><a/><b/></one></foo>", "<foo><one><b/><a/></one></foo>");
+	end);
+
+	it("should be possible to disable ordered matching", function ()
+		yes("<foo><one scansion:strict='no'><a/><b/></one></foo>", "<foo><one><b/><a/></one></foo>");
+	end);
 end);

mercurial