UNPKG

3.07 kBJavaScriptView Raw
1var Frames = require('../lib/frame');
2var PassThrough =
3 require('stream').PassThrough ||
4 require('readable-stream/passthrough');
5var defer = require('when').defer;
6var defs = require('../lib/defs');
7
8// Assume Frames works fine, now test Connection.
9
10// Set up a socket pair {client, server}, such that writes to the
11// client are readable from the server, and writes to the server are
12// readable at the client.
13//
14// +---+ +---+
15// | C | | S |
16// --write->| l |----->| e |--read-->
17// | i | | r |
18// <--read--| e |<-----| v |<-write--
19// | n | | e |
20// | t | | r |
21// +---+ +---+
22//
23// I also need to make sure that end called on either socket affects
24// the other.
25
26function socketPair() {
27 var server = new PassThrough();
28 var client = new PassThrough();
29 server.write = client.push.bind(client);
30 client.write = server.push.bind(server);
31 function end(chunk, encoding) {
32 if (chunk) this.push(chunk, encoding);
33 this.push(null);
34 }
35 server.end = end.bind(client);
36 client.end = end.bind(server);
37
38 return {client: client, server: server};
39}
40
41function runServer(socket, run) {
42 var frames = new Frames(socket);
43
44 function send(id, fields, channel, content) {
45 channel = channel || 0;
46 if (!id && content) {
47 frames.sendContent(channel, defs.BasicProperties, fields, content);
48 }
49 else {
50 frames.sendMethod(channel, id, fields);
51 }
52 }
53
54 function await(method) {
55 return function() {
56 var d = defer();
57 if (method) {
58 frames.accept = function(f) {
59 if (f.id === method)
60 d.resolve(f);
61 else
62 d.reject(new Error("Expected method: " + method +
63 ", got " + f.id));
64 };
65 }
66 else {
67 frames.accept = d.resolve.bind(d);
68 }
69 frames.step();
70 return d.promise;
71 };
72 }
73 run(send, await);
74 return frames;
75}
76
77// Produce a callback that will complete the test successfully
78function succeed(done) {
79 return function() { done(); }
80}
81
82// Produce a callback that will fail the test, given either an error
83// (to be used as a failure continuation) or any other value (to be
84// used as a success continuation when failure is expected)
85function fail(done) {
86 return function(err) {
87 if (err instanceof Error) done(err);
88 else done(new Error("Expected to fail, instead got " + err.toString()));
89 }
90}
91
92// Create a function that will call done once it's been called itself
93// `count` times. If it's called with an error value, it will
94// immediately call done with that error value.
95function latch(count, done) {
96 var awaiting = count;
97 var alive = true;
98 return function(err) {
99 if (err instanceof Error && alive) {
100 alive = false;
101 done(err);
102 }
103 else {
104 awaiting--;
105 if (awaiting === 0 && alive) {
106 alive = false;
107 done();
108 }
109 }
110 };
111}
112
113module.exports = {
114 socketPair: socketPair,
115 runServer: runServer,
116 succeed: succeed,
117 fail: fail,
118 latch: latch
119};