Annotate

spec/util_events_spec.lua @ 13652:a08065207ef0

net.server_epoll: Call :shutdown() on TLS sockets when supported Comment from Matthew: This fixes a potential issue where the Prosody process gets blocked on sockets waiting for them to close. Unlike non-TLS sockets, closing a TLS socket sends layer 7 data, and this can cause problems for sockets which are in the process of being cleaned up. This depends on LuaSec changes which are not yet upstream. From Martijn's original email: So first my analysis of luasec. in ssl.c the socket is put into blocking mode right before calling SSL_shutdown() inside meth_destroy(). My best guess to why this is is because meth_destroy is linked to the __close and __gc methods, which can't exactly be called multiple times and luasec does want to make sure that a tls session is shutdown as clean as possible. I can't say I disagree with this reasoning and don't want to change this behaviour. My solution to this without changing the current behaviour is to introduce a shutdown() method. I am aware that this overlaps in a conflicting way with tcp's shutdown method, but it stays close to the OpenSSL name. This method calls SSL_shutdown() in the current (non)blocking mode of the underlying socket and returns a boolean whether or not the shutdown is completed (matching SSL_shutdown()'s 0 or 1 return values), and returns the familiar ssl_ioerror() strings on error with a false for completion. This error can then be used to determine if we have wantread/wantwrite to finalize things. Once meth_shutdown() has been called once a shutdown flag will be set, which indicates to meth_destroy() that the SSL_shutdown() has been handled by the application and it shouldn't be needed to set the socket to blocking mode. I've left the SSL_shutdown() call in the LSEC_STATE_CONNECTED to prevent TOCTOU if the application reaches a timeout for the shutdown code, which might allow SSL_shutdown() to clean up anyway at the last possible moment. Another thing I've changed to luasec is the call to socket_setblocking() right before calling close(2) in socket_destroy() in usocket.c. According to the latest POSIX[0]: Note that the requirement for close() on a socket to block for up to the current linger interval is not conditional on the O_NONBLOCK setting. Which I read to mean that removing O_NONBLOCK on the socket before close doesn't impact the behaviour and only causes noise in system call tracers. I didn't touch the windows bits of this, since I don't do windows. For the prosody side of things I've made the TLS shutdown bits resemble interface:onwritable(), and put it under a combined guard of self._tls and self.conn.shutdown. The self._tls bit is there to prevent getting stuck on this condition, and self.conn.shutdown is there to prevent the code being called by instances where the patched luasec isn't deployed. The destroy() method can be called from various places and is read by me as the "we give up" error path. To accommodate for these unexpected entrypoints I've added a single call to self.conn:shutdown() to prevent the socket being put into blocking mode. I have no expectations that there is any other use here. Same as previous, the self.conn.shutdown check is there to make sure it's not called on unpatched luasec deployments and self._tls is there to make sure we don't call shutdown() on tcp sockets. I wouldn't recommend logging of the conn:shutdown() error inside close(), since a lot of clients simply close the connection before SSL_shutdown() is done.
author Martijn van Duren <martijn@openbsd.org>
date Thu, 06 Feb 2025 15:04:38 +0000
parent 11060:19dd9522f107
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8760
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 local events = require "util.events";
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 describe("util.events", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 it("should export a new() function", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 assert.is_function(events.new);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 describe("new()", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 it("should return return a new events object", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 local e = events.new();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 assert.is_function(e.add_handler);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 assert.is_function(e.remove_handler);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
13 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 local e, h;
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 describe("API", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 before_each(function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 e = events.new();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 h = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 it("should call handlers when an event is fired", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 e.fire_event("myevent");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27 assert.spy(h).was_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 it("should not call handlers when a different event is fired", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 e.fire_event("notmyevent");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33 assert.spy(h).was_not_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 it("should pass the data argument to handlers", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38 e.fire_event("myevent", "mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 assert.spy(h).was_called_with("mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42 it("should support non-string events", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 local myevent = {};
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44 e.add_handler(myevent, h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45 e.fire_event(myevent, "mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 assert.spy(h).was_called_with("mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 it("should call handlers in priority order", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50 local data = {};
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 e.add_handler("myevent", function () table.insert(data, "h1"); end, 5);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52 e.add_handler("myevent", function () table.insert(data, "h2"); end, 3);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 e.add_handler("myevent", function () table.insert(data, "h3"); end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 e.fire_event("myevent", "mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55 assert.same(data, { "h1", "h2", "h3" });
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 it("should support non-integer priority values", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59 local data = {};
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 e.add_handler("myevent", function () table.insert(data, "h1"); end, 1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 e.add_handler("myevent", function () table.insert(data, "h2"); end, 0.5);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62 e.add_handler("myevent", function () table.insert(data, "h3"); end, 0.25);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 e.fire_event("myevent", "mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 assert.same(data, { "h1", "h2", "h3" });
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 it("should support negative priority values", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68 local data = {};
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69 e.add_handler("myevent", function () table.insert(data, "h1"); end, 1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 e.add_handler("myevent", function () table.insert(data, "h2"); end, 0);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 e.add_handler("myevent", function () table.insert(data, "h3"); end, -1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72 e.fire_event("myevent", "mydata");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73 assert.same(data, { "h1", "h2", "h3" });
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 it("should support removing handlers", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78 e.fire_event("myevent");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 e.remove_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 e.fire_event("myevent");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 assert.spy(h).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84 it("should support adding multiple handlers at the same time", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 local ht = {
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 myevent1 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 myevent2 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 myevent3 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89 };
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90 e.add_handlers(ht);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 e.fire_event("myevent1");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 e.fire_event("myevent2");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 assert.spy(ht.myevent1).was_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 assert.spy(ht.myevent2).was_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 assert.spy(ht.myevent3).was_not_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 it("should support removing multiple handlers at the same time", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 local ht = {
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 myevent1 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 myevent2 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102 myevent3 = spy.new(function () end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103 };
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 e.add_handlers(ht);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105 e.remove_handlers(ht);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106 e.fire_event("myevent1");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107 e.fire_event("myevent2");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 assert.spy(ht.myevent1).was_not_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 assert.spy(ht.myevent2).was_not_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 assert.spy(ht.myevent3).was_not_called();
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 pending("should support adding handlers within an event handler")
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 pending("should support removing handlers within an event handler")
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115
8761
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
116 it("should support getting the current handlers for an event", function ()
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
117 e.add_handler("myevent", h);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
118 local handlers = e.get_handlers("myevent");
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
119 assert.equal(h, handlers[1]);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
120 end);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
121
8760
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 describe("wrappers", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 local w
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 before_each(function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 w = spy.new(function (handlers, event_name, event_data)
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 assert.is_function(handlers);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 assert.equal("myevent", event_name)
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128 assert.equal("abc", event_data);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129 return handlers(event_name, event_data);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 it("should get called", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 e.add_wrapper("myevent", w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 assert.spy(w).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 assert.spy(h).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141 it("should be removable", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 e.add_wrapper("myevent", w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 e.remove_wrapper("myevent", w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 assert.spy(w).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 assert.spy(h).was_called(2);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 it("should allow multiple wrappers", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 local w2 = spy.new(function (handlers, event_name, event_data)
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 return handlers(event_name, event_data);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 e.add_wrapper("myevent", w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 e.add_wrapper("myevent", w2);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 e.remove_wrapper("myevent", w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 assert.spy(w).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 assert.spy(w2).was_called(2);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 assert.spy(h).was_called(2);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164 end);
8761
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
165
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
166 it("should support a mix of global and event wrappers", function ()
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
167 local w2 = spy.new(function (handlers, event_name, event_data)
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
168 return handlers(event_name, event_data);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
169 end);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
170 e.add_wrapper(false, w);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
171 e.add_handler("myevent", h);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
172 e.add_wrapper("myevent", w2);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
173 e.fire_event("myevent", "abc");
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
174 e.remove_wrapper(false, w);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
175 e.fire_event("myevent", "abc");
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
176 assert.spy(w).was_called(1);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
177 assert.spy(w2).was_called(2);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
178 assert.spy(h).was_called(2);
b6e193e33145 util.events: Add more tests (100% line coverage)
Matthew Wild <mwild1@gmail.com>
parents: 8760
diff changeset
179 end);
8760
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 describe("global wrappers", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 local w
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 before_each(function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 w = spy.new(function (handlers, event_name, event_data)
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 assert.is_function(handlers);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 assert.equal("myevent", event_name)
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 assert.equal("abc", event_data);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 return handlers(event_name, event_data);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 it("should get called", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 e.add_wrapper(false, w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 assert.spy(w).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 assert.spy(h).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 it("should be removable", function ()
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 e.add_wrapper(false, w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203 e.add_handler("myevent", h);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 e.remove_wrapper(false, w);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 e.fire_event("myevent", "abc");
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 assert.spy(w).was_called(1);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 assert.spy(h).was_called(2);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 end);
11058
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
211
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
212 describe("debug hooks", function ()
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
213 it("should get called", function ()
11060
19dd9522f107 util.event: Add luacheck annotation to unused parameter in tests
Matthew Wild <mwild1@gmail.com>
parents: 11058
diff changeset
214 local d = spy.new(function (handler, event_name, event_data) --luacheck: ignore 212/event_name
11058
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
215 return handler(event_data);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
216 end);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
217
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
218 e.add_handler("myevent", h);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
219 e.fire_event("myevent");
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
220
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
221 assert.spy(h).was_called(1);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
222 assert.spy(d).was_called(0);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
223
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
224 assert.is_nil(e.set_debug_hook(d));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
225
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
226 e.fire_event("myevent", { mydata = true });
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
227
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
228 assert.spy(h).was_called(2);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
229 assert.spy(d).was_called(1);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
230 assert.spy(d).was_called_with(h, "myevent", { mydata = true });
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
231
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
232 assert.equal(d, e.set_debug_hook(nil));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
233
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
234 e.fire_event("myevent", { mydata = false });
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
235
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
236 assert.spy(h).was_called(3);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
237 assert.spy(d).was_called(1);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
238 end);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
239 it("setting should return any existing debug hook", function ()
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
240 local function f() end
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
241 local function g() end
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
242 assert.is_nil(e.set_debug_hook(f));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
243 assert.is_equal(f, e.set_debug_hook(g));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
244 assert.is_equal(g, e.set_debug_hook(f));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
245 assert.is_equal(f, e.set_debug_hook(nil));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
246 assert.is_nil(e.set_debug_hook(f));
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
247 end);
c99afee1c548 util.events: Add set_debug_hook() method
Matthew Wild <mwild1@gmail.com>
parents: 8802
diff changeset
248 end);
8760
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 end);
6f3c3bb768cb util.events: Add tests
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 end);