@eleven-am/pondsocket 0.1.50 → 0.1.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/abstracts/abstractRequest.js +58 -0
- package/abstracts/middleware.js +51 -0
- package/channel/channel.js +253 -0
- package/{server/channel → channel}/eventRequest.js +4 -1
- package/channel/eventResponse.js +150 -0
- package/client/channel.js +120 -97
- package/client.d.ts +2 -3
- package/client.js +34 -20
- package/endpoint/endpoint.js +233 -0
- package/endpoint/response.js +86 -0
- package/enums.js +14 -10
- package/errors/pondError.js +27 -0
- package/express.d.ts +2 -2
- package/express.js +3 -3
- package/index.d.ts +1 -2
- package/index.js +1 -4
- package/lobby/joinRequest.js +39 -0
- package/lobby/joinResponse.js +125 -0
- package/lobby/lobby.js +174 -0
- package/matcher/matcher.js +94 -0
- package/node.d.ts +2 -3
- package/node.js +3 -4
- package/package.json +5 -4
- package/presence/presence.js +113 -0
- package/server/pondSocket.js +123 -0
- package/subjects/subject.js +93 -0
- package/types.d.ts +274 -323
- package/client/channel.test.js +0 -546
- package/server/abstracts/abstractRequest.js +0 -40
- package/server/abstracts/abstractRequest.test.js +0 -41
- package/server/abstracts/middleware.js +0 -38
- package/server/abstracts/middleware.test.js +0 -70
- package/server/channel/channelEngine.js +0 -280
- package/server/channel/channelEngine.test.js +0 -377
- package/server/channel/channelRequest.test.js +0 -29
- package/server/channel/channelResponse.test.js +0 -164
- package/server/channel/eventResponse.js +0 -153
- package/server/endpoint/connectionResponse.js +0 -64
- package/server/endpoint/endpoint.js +0 -253
- package/server/endpoint/endpoint.test.js +0 -428
- package/server/endpoint/endpointResponse.test.js +0 -43
- package/server/pondChannel/joinRequest.js +0 -29
- package/server/pondChannel/joinResponse.js +0 -103
- package/server/pondChannel/pondChannel.js +0 -185
- package/server/pondChannel/pondChannelResponse.test.js +0 -109
- package/server/presence/presenceEngine.js +0 -107
- package/server/presence/presenceEngine.test.js +0 -105
- package/server/server/pondSocket.js +0 -121
- package/server/server/server.test.js +0 -121
- package/server/utils/matchPattern.js +0 -108
- package/server/utils/matchPattern.test.js +0 -76
- package/server/utils/subjectUtils.js +0 -68
- package/server/utils/subjectUtils.test.js +0 -128
- /package/{server/abstracts → abstracts}/abstractResponse.js +0 -0
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const http_1 = require("http");
|
|
16
|
-
const superwstest_1 = __importDefault(require("superwstest"));
|
|
17
|
-
const ws_1 = require("ws");
|
|
18
|
-
const pondSocket_1 = require("./pondSocket");
|
|
19
|
-
const enums_1 = require("../../enums");
|
|
20
|
-
const channelEngine_1 = require("../channel/channelEngine");
|
|
21
|
-
const endpoint_1 = require("../endpoint/endpoint");
|
|
22
|
-
describe('server', () => {
|
|
23
|
-
it('should take a server and websocket server if provided', () => {
|
|
24
|
-
const server = (0, http_1.createServer)();
|
|
25
|
-
const socketServer = new ws_1.Server({ noServer: true });
|
|
26
|
-
const socket = new pondSocket_1.PondSocket(server, socketServer);
|
|
27
|
-
expect(socket['_server']).toBe(server);
|
|
28
|
-
expect(socket['_socketServer']).toBe(socketServer);
|
|
29
|
-
});
|
|
30
|
-
it('should be able to listen on a port', () => {
|
|
31
|
-
const socket = new pondSocket_1.PondSocket();
|
|
32
|
-
expect(socket.listen(3001, () => {
|
|
33
|
-
console.log('socket');
|
|
34
|
-
})).toBeDefined();
|
|
35
|
-
socket['_server'].close();
|
|
36
|
-
});
|
|
37
|
-
it('should be able to create an endpoint', () => {
|
|
38
|
-
const socket = new pondSocket_1.PondSocket();
|
|
39
|
-
const endpoint = socket.createEndpoint('/api/socket', () => {
|
|
40
|
-
console.log('socket');
|
|
41
|
-
});
|
|
42
|
-
expect(endpoint).toBeInstanceOf(endpoint_1.Endpoint);
|
|
43
|
-
});
|
|
44
|
-
it('should be able to create multiple endpoints', () => {
|
|
45
|
-
const server = (0, http_1.createServer)();
|
|
46
|
-
const socketServer = new ws_1.Server({ noServer: true });
|
|
47
|
-
const socket = new pondSocket_1.PondSocket(server, socketServer);
|
|
48
|
-
const endpoint = socket.createEndpoint('/api/socket', () => {
|
|
49
|
-
console.log('socket');
|
|
50
|
-
});
|
|
51
|
-
const endpoint2 = socket.createEndpoint('/api/socket2', () => {
|
|
52
|
-
console.log('socket2');
|
|
53
|
-
});
|
|
54
|
-
expect(endpoint).toBeInstanceOf(endpoint_1.Endpoint);
|
|
55
|
-
expect(endpoint2).toBeInstanceOf(endpoint_1.Endpoint);
|
|
56
|
-
});
|
|
57
|
-
it('should be able to reject a socket', () => {
|
|
58
|
-
const server = (0, http_1.createServer)();
|
|
59
|
-
const socketServer = new ws_1.Server({ noServer: true });
|
|
60
|
-
const socket = new pondSocket_1.PondSocket(server, socketServer);
|
|
61
|
-
const socketClient = {
|
|
62
|
-
write: jest.fn(),
|
|
63
|
-
destroy: jest.fn(),
|
|
64
|
-
};
|
|
65
|
-
socket.listen(3001);
|
|
66
|
-
server.emit('upgrade', {}, socketClient);
|
|
67
|
-
server.close();
|
|
68
|
-
// these functions are called because there is no endpoint to accept the socket
|
|
69
|
-
expect(socketClient.write).toHaveBeenCalled();
|
|
70
|
-
expect(socketClient.destroy).toHaveBeenCalled();
|
|
71
|
-
});
|
|
72
|
-
it('should be able to accept a socket if a handler is provided', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
-
const socket = new pondSocket_1.PondSocket();
|
|
74
|
-
const server = socket.listen(3001);
|
|
75
|
-
expect(server).toBeDefined();
|
|
76
|
-
socket.createEndpoint('/api/:path', (req, res) => {
|
|
77
|
-
expect(req.params.path).toBe('socket');
|
|
78
|
-
res.accept();
|
|
79
|
-
});
|
|
80
|
-
yield (0, superwstest_1.default)(server)
|
|
81
|
-
.ws('/api/socket')
|
|
82
|
-
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
83
|
-
.close()
|
|
84
|
-
.expectClosed();
|
|
85
|
-
server.close();
|
|
86
|
-
}));
|
|
87
|
-
it('should be able to reject a socket if the handler rejects', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
88
|
-
const socket = new pondSocket_1.PondSocket();
|
|
89
|
-
const server = socket.listen(3001);
|
|
90
|
-
expect(server).toBeDefined();
|
|
91
|
-
socket.createEndpoint('/api/:path', (req, res) => {
|
|
92
|
-
expect(req.params.path).toBe('socket');
|
|
93
|
-
res.reject();
|
|
94
|
-
});
|
|
95
|
-
yield (0, superwstest_1.default)(server)
|
|
96
|
-
.ws('/api/socket')
|
|
97
|
-
.expectConnectionError();
|
|
98
|
-
server.close();
|
|
99
|
-
}));
|
|
100
|
-
it('should be able to send a message after connection', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
101
|
-
const socket = new pondSocket_1.PondSocket();
|
|
102
|
-
const server = socket.listen(3001);
|
|
103
|
-
expect(server).toBeDefined();
|
|
104
|
-
socket.createEndpoint('/api/:path', (req, res) => {
|
|
105
|
-
expect(req.params.path).toBe('socket');
|
|
106
|
-
res.send('testEvent', { test: 'test' });
|
|
107
|
-
});
|
|
108
|
-
yield (0, superwstest_1.default)(server)
|
|
109
|
-
.ws('/api/socket')
|
|
110
|
-
.expectUpgrade((res) => expect(res.statusCode).toBe(101))
|
|
111
|
-
.expectJson({
|
|
112
|
-
event: 'testEvent',
|
|
113
|
-
channelName: enums_1.SystemSender.ENDPOINT,
|
|
114
|
-
payload: { test: 'test' },
|
|
115
|
-
action: channelEngine_1.ServerActions.SYSTEM,
|
|
116
|
-
})
|
|
117
|
-
.close()
|
|
118
|
-
.expectClosed();
|
|
119
|
-
server.close();
|
|
120
|
-
}));
|
|
121
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MatchPattern = void 0;
|
|
4
|
-
class MatchPattern {
|
|
5
|
-
/**
|
|
6
|
-
* @desc Generates a pond request resolver object
|
|
7
|
-
* @param path - the path to resolve
|
|
8
|
-
* @param address - the address to resolve
|
|
9
|
-
*/
|
|
10
|
-
parseEvent(path, address) {
|
|
11
|
-
if (path === '*') {
|
|
12
|
-
return {
|
|
13
|
-
params: {},
|
|
14
|
-
address,
|
|
15
|
-
query: this._parseQueries(address),
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
const match = this._matchStringToPattern(address, path);
|
|
19
|
-
if (match) {
|
|
20
|
-
return {
|
|
21
|
-
params: match,
|
|
22
|
-
address,
|
|
23
|
-
query: this._parseQueries(address),
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
return null;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* @desc Creates an object from the params of a path
|
|
30
|
-
* @param path - the path to create the object from
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
* /api/id?name=abc should return { name: 'abc' }
|
|
34
|
-
* /api/id?name=abc&age=123 should return { name: 'abc', age: '123' }
|
|
35
|
-
*/
|
|
36
|
-
_parseQueries(path) {
|
|
37
|
-
const obj = {};
|
|
38
|
-
const params = path.split('?')[1];
|
|
39
|
-
if (params) {
|
|
40
|
-
params.split('&').forEach((param) => {
|
|
41
|
-
const [key, value] = param.split('=');
|
|
42
|
-
obj[key] = value;
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
return obj;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* @desc checks if the pattern is matchable
|
|
49
|
-
* @param pattern - the pattern to check
|
|
50
|
-
*/
|
|
51
|
-
_isPatternMatchable(pattern) {
|
|
52
|
-
return typeof pattern === 'string' && pattern.includes(':');
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* @desc compares string to string | regex
|
|
56
|
-
* @param string - the string to compare to the pattern
|
|
57
|
-
* @param pattern - the pattern to compare to the string
|
|
58
|
-
*/
|
|
59
|
-
_compareStringToPattern(string, pattern) {
|
|
60
|
-
if (typeof pattern === 'string') {
|
|
61
|
-
return string.split('?')[0] === pattern;
|
|
62
|
-
}
|
|
63
|
-
return pattern.test(string);
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* @desc Returns the {key: value} matches of a string
|
|
67
|
-
* @param string - the string to create the regex from
|
|
68
|
-
* @param pattern - the pattern to match
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* /api/:id should match /api/123 and return { id: 123 }
|
|
72
|
-
* /api/:id/:name should match /api/123/abc and return { id: 123, name: abc }
|
|
73
|
-
* hello:id should match hello:123 and return { id: 123 }
|
|
74
|
-
* @private
|
|
75
|
-
*/
|
|
76
|
-
_matchString(string, pattern) {
|
|
77
|
-
const replace = pattern.replace(/:[^/]+/g, '([^/]+)');
|
|
78
|
-
const regExp = new RegExp(`^${replace}$`);
|
|
79
|
-
const matches = string.split('?')[0].match(regExp);
|
|
80
|
-
if (matches) {
|
|
81
|
-
const keys = pattern.match(/:[^/]+/g);
|
|
82
|
-
if (keys) {
|
|
83
|
-
const obj = {};
|
|
84
|
-
keys.forEach((key, index) => {
|
|
85
|
-
obj[key.replace(':', '')] = matches[index + 1].replace(/\?.*$/, '');
|
|
86
|
-
});
|
|
87
|
-
return obj;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* @desc matches a string to a pattern and returns its params if any
|
|
94
|
-
* @param string - the string to match
|
|
95
|
-
* @param pattern - the pattern to match to
|
|
96
|
-
*/
|
|
97
|
-
_matchStringToPattern(string, pattern) {
|
|
98
|
-
if (this._isPatternMatchable(pattern)) {
|
|
99
|
-
return this._matchString(string, pattern);
|
|
100
|
-
}
|
|
101
|
-
const valid = this._compareStringToPattern(string, pattern);
|
|
102
|
-
if (valid) {
|
|
103
|
-
return {};
|
|
104
|
-
}
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
exports.MatchPattern = MatchPattern;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const matchPattern_1 = require("./matchPattern");
|
|
4
|
-
describe('BaseClass', () => {
|
|
5
|
-
const baseClass = new matchPattern_1.MatchPattern();
|
|
6
|
-
it('should return true if a string matches a regex | string', () => {
|
|
7
|
-
const regex = new RegExp(/^test/);
|
|
8
|
-
expect(baseClass['_compareStringToPattern']('test', regex)).toBe(true);
|
|
9
|
-
const string = 'test';
|
|
10
|
-
expect(baseClass['_compareStringToPattern']('test', string)).toBe(true);
|
|
11
|
-
});
|
|
12
|
-
it('should return false if a string does not match a regex | string', () => {
|
|
13
|
-
const regex = new RegExp(/^test$/);
|
|
14
|
-
expect(baseClass['_compareStringToPattern']('test2', regex)).toBe(false);
|
|
15
|
-
const string = 'test';
|
|
16
|
-
expect(baseClass['_compareStringToPattern']('test2', string)).toBe(false);
|
|
17
|
-
});
|
|
18
|
-
it('should return the params of a string matching the pattern', () => {
|
|
19
|
-
const pattern = '/test/:id';
|
|
20
|
-
const secondPattern = '/test/:id/:id2';
|
|
21
|
-
const string = '/test/5';
|
|
22
|
-
const secondString = '/test/5/6';
|
|
23
|
-
expect(baseClass['_matchString'](string, pattern)).toEqual({ id: '5' });
|
|
24
|
-
expect(baseClass['_matchString'](secondString, secondPattern)).toEqual({ id: '5',
|
|
25
|
-
id2: '6' });
|
|
26
|
-
// this function fails if the pattern is not a string or regex
|
|
27
|
-
expect(baseClass['_matchString'](secondString, pattern)).toEqual(null);
|
|
28
|
-
// But will return null if the string is smaller than the pattern
|
|
29
|
-
expect(baseClass['_matchString'](string, secondPattern)).toEqual(null);
|
|
30
|
-
// it should also match patterns without the slash
|
|
31
|
-
const thirdPattern = 'test:id';
|
|
32
|
-
const thirdString = 'test5';
|
|
33
|
-
expect(baseClass['_matchString'](thirdString, thirdPattern)).toEqual({ id: '5' });
|
|
34
|
-
});
|
|
35
|
-
it('should return the query of string', () => {
|
|
36
|
-
const string = '/test/5?test=5';
|
|
37
|
-
const secondString = '/test/5?test=5&test2=6';
|
|
38
|
-
expect(baseClass['_parseQueries'](string)).toEqual({ test: '5' });
|
|
39
|
-
expect(baseClass['_parseQueries'](secondString)).toEqual({ test: '5',
|
|
40
|
-
test2: '6' });
|
|
41
|
-
});
|
|
42
|
-
it('should return null if the string does not match the pattern', () => {
|
|
43
|
-
const pattern = 'pondSocket';
|
|
44
|
-
const string = '/test2/5';
|
|
45
|
-
expect(baseClass['_matchStringToPattern'](string, pattern)).toBe(null);
|
|
46
|
-
});
|
|
47
|
-
it('should return the params of a string matching the pattern', () => {
|
|
48
|
-
const pattern = 'pondSocket';
|
|
49
|
-
const string = 'pondSocket';
|
|
50
|
-
expect(baseClass['_matchStringToPattern'](string, pattern)).toEqual({});
|
|
51
|
-
});
|
|
52
|
-
it('should generateEventRequest', () => {
|
|
53
|
-
const pattern = 'pondSocket:test';
|
|
54
|
-
const string = 'pondSockethello?test=5&test2=6';
|
|
55
|
-
expect(baseClass.parseEvent(pattern, string)).toEqual({
|
|
56
|
-
address: string,
|
|
57
|
-
params: { test: 'hello' },
|
|
58
|
-
query: { test: '5',
|
|
59
|
-
test2: '6' },
|
|
60
|
-
});
|
|
61
|
-
const unMatchingString = 'pondocket2hello?test=5&test2=6';
|
|
62
|
-
expect(baseClass.parseEvent(pattern, unMatchingString)).toEqual(null);
|
|
63
|
-
});
|
|
64
|
-
it('should match any string if the path is *', () => {
|
|
65
|
-
const pattern = '*';
|
|
66
|
-
const string = 'pondSockethello?test=5&test2=6';
|
|
67
|
-
expect(baseClass.parseEvent(pattern, string)).toEqual({
|
|
68
|
-
address: string,
|
|
69
|
-
params: {},
|
|
70
|
-
query: {
|
|
71
|
-
test: '5',
|
|
72
|
-
test2: '6',
|
|
73
|
-
},
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// A Subject CLASS that sends a message to all subscribers
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.SimpleBehaviorSubject = exports.SimpleSubject = exports.BehaviorSubject = exports.Subject = void 0;
|
|
5
|
-
class Subject {
|
|
6
|
-
constructor() {
|
|
7
|
-
this._observers = new Map();
|
|
8
|
-
}
|
|
9
|
-
subscribe(identifier, observer) {
|
|
10
|
-
this._observers.set(identifier, observer);
|
|
11
|
-
}
|
|
12
|
-
next(message) {
|
|
13
|
-
this._observers.forEach((observer) => observer(message));
|
|
14
|
-
}
|
|
15
|
-
unsubscribe(identifier) {
|
|
16
|
-
this._observers.delete(identifier);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
exports.Subject = Subject;
|
|
20
|
-
// A behavior subject CLASS that sends the last message to new subscribers
|
|
21
|
-
class BehaviorSubject extends Subject {
|
|
22
|
-
next(message) {
|
|
23
|
-
this._lastMessage = message;
|
|
24
|
-
super.next(message);
|
|
25
|
-
}
|
|
26
|
-
subscribe(identifier, observer) {
|
|
27
|
-
if (this._lastMessage) {
|
|
28
|
-
observer(this._lastMessage);
|
|
29
|
-
}
|
|
30
|
-
return super.subscribe(identifier, observer);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
exports.BehaviorSubject = BehaviorSubject;
|
|
34
|
-
// Simple Subject CLASS
|
|
35
|
-
class SimpleSubject {
|
|
36
|
-
constructor() {
|
|
37
|
-
this._observers = new Set();
|
|
38
|
-
}
|
|
39
|
-
subscribe(observer) {
|
|
40
|
-
this._observers.add(observer);
|
|
41
|
-
return () => this._observers.delete(observer);
|
|
42
|
-
}
|
|
43
|
-
next(message) {
|
|
44
|
-
this._observers.forEach((observer) => observer(message));
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
exports.SimpleSubject = SimpleSubject;
|
|
48
|
-
// Simple BehaviorSubject CLASS
|
|
49
|
-
class SimpleBehaviorSubject extends SimpleSubject {
|
|
50
|
-
constructor(initialValue) {
|
|
51
|
-
super();
|
|
52
|
-
this._lastMessage = initialValue;
|
|
53
|
-
}
|
|
54
|
-
get value() {
|
|
55
|
-
return this._lastMessage;
|
|
56
|
-
}
|
|
57
|
-
next(message) {
|
|
58
|
-
this._lastMessage = message;
|
|
59
|
-
super.next(message);
|
|
60
|
-
}
|
|
61
|
-
subscribe(observer) {
|
|
62
|
-
if (this._lastMessage) {
|
|
63
|
-
observer(this._lastMessage);
|
|
64
|
-
}
|
|
65
|
-
return super.subscribe(observer);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.SimpleBehaviorSubject = SimpleBehaviorSubject;
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const subjectUtils_1 = require("./subjectUtils");
|
|
4
|
-
describe('Subject', () => {
|
|
5
|
-
let testSubject;
|
|
6
|
-
let observer1;
|
|
7
|
-
let observer2;
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
testSubject = new subjectUtils_1.Subject();
|
|
10
|
-
observer1 = jest.fn();
|
|
11
|
-
observer2 = jest.fn();
|
|
12
|
-
testSubject.subscribe('observer1', observer1);
|
|
13
|
-
testSubject.subscribe('observer2', observer2);
|
|
14
|
-
});
|
|
15
|
-
afterEach(() => {
|
|
16
|
-
testSubject.unsubscribe('observer1');
|
|
17
|
-
testSubject.unsubscribe('observer2');
|
|
18
|
-
});
|
|
19
|
-
it('should notify all subscribers when next is called', () => {
|
|
20
|
-
const message = 10;
|
|
21
|
-
testSubject.next(message);
|
|
22
|
-
expect(observer1).toHaveBeenCalledWith(message);
|
|
23
|
-
expect(observer2).toHaveBeenCalledWith(message);
|
|
24
|
-
});
|
|
25
|
-
it('should unsubscribe an observer when unsubscribe is called', () => {
|
|
26
|
-
const identifier = 'observer1';
|
|
27
|
-
testSubject.unsubscribe(identifier);
|
|
28
|
-
expect(testSubject['_observers'].has(identifier)).toBe(false);
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
describe('BehaviorSubject', () => {
|
|
32
|
-
let testSubject;
|
|
33
|
-
let observer1;
|
|
34
|
-
let observer2;
|
|
35
|
-
beforeEach(() => {
|
|
36
|
-
testSubject = new subjectUtils_1.BehaviorSubject();
|
|
37
|
-
observer1 = jest.fn();
|
|
38
|
-
observer2 = jest.fn();
|
|
39
|
-
testSubject.subscribe('observer1', observer1);
|
|
40
|
-
testSubject.subscribe('observer2', observer2);
|
|
41
|
-
});
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
testSubject.unsubscribe('observer1');
|
|
44
|
-
testSubject.unsubscribe('observer2');
|
|
45
|
-
});
|
|
46
|
-
it('should notify all subscribers when next is called', () => {
|
|
47
|
-
const message = 10;
|
|
48
|
-
testSubject.next(message);
|
|
49
|
-
expect(observer1).toHaveBeenCalledWith(message);
|
|
50
|
-
expect(observer2).toHaveBeenCalledWith(message);
|
|
51
|
-
});
|
|
52
|
-
it('should unsubscribe an observer when unsubscribe is called', () => {
|
|
53
|
-
const identifier = 'observer1';
|
|
54
|
-
testSubject.unsubscribe(identifier);
|
|
55
|
-
expect(testSubject['_observers'].has(identifier)).toBe(false);
|
|
56
|
-
});
|
|
57
|
-
it('should notify new subscribers with the last message when subscribe is called', () => {
|
|
58
|
-
const message = 10;
|
|
59
|
-
testSubject.next(message);
|
|
60
|
-
const newObserver = jest.fn();
|
|
61
|
-
testSubject.subscribe('newObserver', newObserver);
|
|
62
|
-
expect(newObserver).toHaveBeenCalledWith(message);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
describe('SimpleSubject', () => {
|
|
66
|
-
let testSubject;
|
|
67
|
-
let observer1;
|
|
68
|
-
let observer2;
|
|
69
|
-
beforeEach(() => {
|
|
70
|
-
testSubject = new subjectUtils_1.SimpleSubject();
|
|
71
|
-
observer1 = jest.fn();
|
|
72
|
-
observer2 = jest.fn();
|
|
73
|
-
testSubject.subscribe(observer1);
|
|
74
|
-
testSubject.subscribe(observer2);
|
|
75
|
-
});
|
|
76
|
-
afterEach(() => {
|
|
77
|
-
testSubject.next(0);
|
|
78
|
-
});
|
|
79
|
-
it('should notify all subscribers when publish is called', () => {
|
|
80
|
-
const message = 10;
|
|
81
|
-
testSubject.next(message);
|
|
82
|
-
expect(observer1).toHaveBeenCalledWith(message);
|
|
83
|
-
expect(observer2).toHaveBeenCalledWith(message);
|
|
84
|
-
});
|
|
85
|
-
it('should unsubscribe an observer when unsubscribe is called', () => {
|
|
86
|
-
const unsubscribe = testSubject.subscribe(observer1);
|
|
87
|
-
unsubscribe();
|
|
88
|
-
expect(testSubject['_observers'].size).toBe(1);
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('SimpleBehaviorSubject', () => {
|
|
92
|
-
let testSubject;
|
|
93
|
-
let observer1;
|
|
94
|
-
let observer2;
|
|
95
|
-
beforeEach(() => {
|
|
96
|
-
testSubject = new subjectUtils_1.SimpleBehaviorSubject(0);
|
|
97
|
-
observer1 = jest.fn();
|
|
98
|
-
observer2 = jest.fn();
|
|
99
|
-
testSubject.subscribe(observer1);
|
|
100
|
-
testSubject.subscribe(observer2);
|
|
101
|
-
});
|
|
102
|
-
afterEach(() => {
|
|
103
|
-
testSubject.next(0);
|
|
104
|
-
});
|
|
105
|
-
it('should notify all subscribers when publish is called', () => {
|
|
106
|
-
const message = 10;
|
|
107
|
-
testSubject.next(message);
|
|
108
|
-
expect(observer1).toHaveBeenCalledWith(message);
|
|
109
|
-
expect(observer2).toHaveBeenCalledWith(message);
|
|
110
|
-
});
|
|
111
|
-
it('should unsubscribe an observer when unsubscribe is called', () => {
|
|
112
|
-
const unsubscribe = testSubject.subscribe(observer1);
|
|
113
|
-
unsubscribe();
|
|
114
|
-
expect(testSubject['_observers'].size).toBe(1);
|
|
115
|
-
});
|
|
116
|
-
it('should notify new subscribers with the last message when subscribe is called', () => {
|
|
117
|
-
const message = 10;
|
|
118
|
-
testSubject.next(message);
|
|
119
|
-
const newObserver = jest.fn();
|
|
120
|
-
testSubject.subscribe(newObserver);
|
|
121
|
-
expect(newObserver).toHaveBeenCalledWith(message);
|
|
122
|
-
});
|
|
123
|
-
it('should return the last message when value is called', () => {
|
|
124
|
-
const message = 10;
|
|
125
|
-
testSubject.next(message);
|
|
126
|
-
expect(testSubject.value).toBe(message);
|
|
127
|
-
});
|
|
128
|
-
});
|
|
File without changes
|