Changeset

8797:7b621a4a2e8d

util.iterators: Add join() method and tests
author Matthew Wild <mwild1@gmail.com>
date Fri, 18 May 2018 14:57:39 +0100
parents 8796:51375b007239
children 8798:505722879b55
files spec/util_events_spec.lua util/iterators.lua
diffstat 2 files changed, 67 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/spec/util_events_spec.lua	Wed May 16 23:59:30 2018 +0100
+++ b/spec/util_events_spec.lua	Fri May 18 14:57:39 2018 +0100
@@ -208,5 +208,26 @@
 				assert.spy(h).was_called(2);
 			end);
 		end);
+
+		describe("chaining", function ()
+			local e2;
+			before_each(function ()
+				e2 = events.new(e);
+				h2 = spy.new(function () end);
+			end);
+			it("should fire parent handlers when an event is fired", function ()
+				e.add_handler("myevent", h);
+				e2.add_handler("myevent", h2);
+				e2.fire_event("myevent", "abc");
+				assert.spy(h).was_called(1);
+				assert.spy(h).was_called.with("abc");
+				assert.spy(h2).was_called(1);
+				assert.spy(h2).was_called.with("abc");
+			end);
+			it("should handle changes in the parent's handlers", function ()
+			end);
+			it("should fire wrappers in child and parent", function ()
+			end);
+		end);
 	end);
 end);
--- a/util/iterators.lua	Wed May 16 23:59:30 2018 +0100
+++ b/util/iterators.lua	Fri May 18 14:57:39 2018 +0100
@@ -14,6 +14,11 @@
 local select, next = select, next;
 local unpack = table.unpack or unpack; --luacheck: ignore 113 143
 local pack = table.pack or function (...) return { n = select("#", ...), ... }; end -- luacheck: ignore 143
+local type = type;
+local table, setmetatable = table, setmetatable;
+
+local _ENV = nil;
+--luacheck: std none
 
 -- Reverse an iterator
 function it.reverse(f, s, var)
@@ -184,4 +189,45 @@
 	return t;
 end
 
+local function _join_iter(j_s, j_var)
+	local iterators, current_idx = j_s[1], j_s[2];
+	local f, s, var = unpack(iterators[current_idx], 1, 3);
+	if j_var ~= nil then
+		var = j_var;
+	end
+	local ret = pack(f(s, var));
+	local var1 = ret[1];
+	if var1 == nil then
+		-- End of this iterator, advance to next
+		if current_idx == #iterators then
+			-- No more iterators, return nil
+			return;
+		end
+		j_s[2] = current_idx + 1;
+		return _join_iter(j_s);
+	end
+	return unpack(ret, 1, ret.n);
+end
+local join_methods = {};
+local join_mt = {
+	__index = join_methods;
+	__call = function (t, s, var) --luacheck: ignore 212/t
+		return _join_iter(s, var);
+	end;
+};
+
+function join_methods:append(f, s, var)
+	table.insert(self, { f, s, var });
+	return self, { self, 1 };
+end
+
+function join_methods:prepend(f, s, var)
+	table.insert(self, { f, s, var }, 1);
+	return self, { self, 1 };
+end
+
+function it.join(f, s, var)
+	return setmetatable({ {f, s, var} }, join_mt);
+end
+
 return it;