particle-api-js 10.3.0 → 10.3.1

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.
@@ -5,255 +5,255 @@ const { EventEmitter } = require('events');
5
5
  const EventStream = require('../src/EventStream');
6
6
 
7
7
  describe('EventStream', () => {
8
- afterEach(() => {
9
- sinon.restore();
10
- });
11
-
12
- function makeRequest() {
13
- const fakeRequest = new EventEmitter();
14
- fakeRequest.end = sinon.spy();
15
- fakeRequest.setTimeout = sinon.spy();
16
- return fakeRequest;
17
- }
18
-
19
- function makeResponse(statusCode) {
20
- const fakeResponse = new EventEmitter();
21
- fakeResponse.statusCode = statusCode;
22
- return fakeResponse;
23
- }
24
-
25
- describe('constructor', () => {
26
- it('creates an EventStream objects', () => {
27
- const eventStream = new EventStream('uri', 'token');
28
-
29
- expect(eventStream).to.own.include({ uri: 'uri', token: 'token' });
30
- });
31
- });
32
-
33
- describe('connect', () => {
34
- it('successfully connects to http', () => {
35
- sinon.useFakeTimers({ shouldAdvanceTime: true });
36
- const fakeRequest = makeRequest();
37
- sinon.stub(http, 'request').callsFake(() => {
38
- setImmediate(() => {
39
- const fakeResponse = makeResponse(200);
40
- fakeRequest.emit('response', fakeResponse);
41
- });
42
-
43
- return fakeRequest;
44
- });
45
-
46
- const eventStream = new EventStream('http://hostname:8080/path', 'token');
47
-
48
- return eventStream.connect().then(() => {
49
- expect(http.request).to.have.been.calledWith({
50
- hostname: 'hostname',
51
- protocol: 'http:',
52
- path: '/path?access_token=token',
53
- method: 'get',
54
- port: 8080,
55
- mode: 'prefer-streaming'
56
- });
57
- });
58
- });
59
-
60
- it('returns http errors on connect', () => {
61
- sinon.useFakeTimers({ shouldAdvanceTime: true });
62
- const fakeRequest = makeRequest();
63
- sinon.stub(http, 'request').callsFake(() => {
64
- setImmediate(() => {
65
- const fakeResponse = makeResponse(500);
66
- fakeRequest.emit('response', fakeResponse);
67
- setImmediate(() => {
68
- fakeResponse.emit('data', '{"error":"unknown"}');
69
- fakeResponse.emit('end');
70
- });
71
- });
72
-
73
- return fakeRequest;
74
- });
75
-
76
- const eventStream = new EventStream('http://hostname:8080/path', 'token');
77
-
78
- return eventStream.connect().then(() => {
79
- throw new Error('expected to throw error');
80
- }, (reason) => {
81
- expect(reason).to.eql({
82
- statusCode: 500,
83
- errorDescription: 'HTTP error 500 from http://hostname:8080/path',
84
- body: {
85
- error: 'unknown'
86
- }
87
- });
88
- });
89
- });
90
- });
91
-
92
- describe('parse', () => {
93
- let eventStream;
94
- beforeEach(() => {
95
- eventStream = new EventStream();
96
- sinon.stub(eventStream, 'parseEventStreamLine');
97
- });
98
-
99
- it('accumulates date into the buffer before parsing line', () => {
100
- eventStream.parse('wo');
101
- eventStream.parse('rd');
102
-
103
- expect(eventStream.buf).to.eql('word');
104
- expect(eventStream.parseEventStreamLine).not.to.have.been.called;
105
- });
106
-
107
- it('parses a line ending with \\n', () => {
108
- const line = 'field: value\n';
109
-
110
- eventStream.parse(line);
111
-
112
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\n'));
113
- });
114
-
115
- it('parses 2 lines ending with \\n', () => {
116
- const line1 = 'field: value\n';
117
- const line2 = 'field2: value2\n';
118
-
119
- eventStream.parse(line1 + line2);
120
-
121
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\n'));
122
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\n'));
123
- });
124
-
125
-
126
- it('parses a line ending with \\r\\n', () => {
127
- const line = 'field: value\r\n';
128
-
129
- eventStream.parse(line);
130
-
131
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\r'));
132
- });
133
-
134
- it('parses 2 lines ending with \\r\\n', () => {
135
- const line1 = 'field: value\r\n';
136
- const line2 = 'field2: value2\r\n';
137
-
138
- eventStream.parse(line1 + line2);
139
-
140
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\r'));
141
- expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\r'));
142
- });
143
-
144
- it('clears buffer after parsing full lines', () => {
145
- eventStream.parse('field: value\n');
146
-
147
- expect(eventStream.buf).to.eql('');
148
- });
149
-
150
- it('keeps partial lines in buffer after parsing full lines', () => {
151
- eventStream.parse('field: value\nfield2');
152
-
153
- expect(eventStream.buf).to.eql('field2');
154
- });
155
- });
156
-
157
- describe('parseEventStreamLine', () => {
158
- let eventStream;
159
- beforeEach(() => {
160
- eventStream = new EventStream();
161
- });
162
-
163
- it('ignores comments', () => {
164
- // comments starts with : at column 0
165
- const line = ':ok\n';
166
- eventStream.buf = line;
8
+ afterEach(() => {
9
+ sinon.restore();
10
+ });
11
+
12
+ function makeRequest() {
13
+ const fakeRequest = new EventEmitter();
14
+ fakeRequest.end = sinon.spy();
15
+ fakeRequest.setTimeout = sinon.spy();
16
+ return fakeRequest;
17
+ }
18
+
19
+ function makeResponse(statusCode) {
20
+ const fakeResponse = new EventEmitter();
21
+ fakeResponse.statusCode = statusCode;
22
+ return fakeResponse;
23
+ }
24
+
25
+ describe('constructor', () => {
26
+ it('creates an EventStream objects', () => {
27
+ const eventStream = new EventStream('uri', 'token');
28
+
29
+ expect(eventStream).to.own.include({ uri: 'uri', token: 'token' });
30
+ });
31
+ });
32
+
33
+ describe('connect', () => {
34
+ it('successfully connects to http', () => {
35
+ sinon.useFakeTimers({ shouldAdvanceTime: true });
36
+ const fakeRequest = makeRequest();
37
+ sinon.stub(http, 'request').callsFake(() => {
38
+ setImmediate(() => {
39
+ const fakeResponse = makeResponse(200);
40
+ fakeRequest.emit('response', fakeResponse);
41
+ });
42
+
43
+ return fakeRequest;
44
+ });
45
+
46
+ const eventStream = new EventStream('http://hostname:8080/path', 'token');
47
+
48
+ return eventStream.connect().then(() => {
49
+ expect(http.request).to.have.been.calledWith({
50
+ hostname: 'hostname',
51
+ protocol: 'http:',
52
+ path: '/path?access_token=token',
53
+ method: 'get',
54
+ port: 8080,
55
+ mode: 'prefer-streaming'
56
+ });
57
+ });
58
+ });
59
+
60
+ it('returns http errors on connect', () => {
61
+ sinon.useFakeTimers({ shouldAdvanceTime: true });
62
+ const fakeRequest = makeRequest();
63
+ sinon.stub(http, 'request').callsFake(() => {
64
+ setImmediate(() => {
65
+ const fakeResponse = makeResponse(500);
66
+ fakeRequest.emit('response', fakeResponse);
67
+ setImmediate(() => {
68
+ fakeResponse.emit('data', '{"error":"unknown"}');
69
+ fakeResponse.emit('end');
70
+ });
71
+ });
72
+
73
+ return fakeRequest;
74
+ });
75
+
76
+ const eventStream = new EventStream('http://hostname:8080/path', 'token');
77
+
78
+ return eventStream.connect().then(() => {
79
+ throw new Error('expected to throw error');
80
+ }, (reason) => {
81
+ expect(reason).to.eql({
82
+ statusCode: 500,
83
+ errorDescription: 'HTTP error 500 from http://hostname:8080/path',
84
+ body: {
85
+ error: 'unknown'
86
+ }
87
+ });
88
+ });
89
+ });
90
+ });
91
+
92
+ describe('parse', () => {
93
+ let eventStream;
94
+ beforeEach(() => {
95
+ eventStream = new EventStream();
96
+ sinon.stub(eventStream, 'parseEventStreamLine');
97
+ });
98
+
99
+ it('accumulates date into the buffer before parsing line', () => {
100
+ eventStream.parse('wo');
101
+ eventStream.parse('rd');
102
+
103
+ expect(eventStream.buf).to.eql('word');
104
+ expect(eventStream.parseEventStreamLine).not.to.have.been.called;
105
+ });
106
+
107
+ it('parses a line ending with \\n', () => {
108
+ const line = 'field: value\n';
109
+
110
+ eventStream.parse(line);
111
+
112
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\n'));
113
+ });
114
+
115
+ it('parses 2 lines ending with \\n', () => {
116
+ const line1 = 'field: value\n';
117
+ const line2 = 'field2: value2\n';
118
+
119
+ eventStream.parse(line1 + line2);
120
+
121
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\n'));
122
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\n'));
123
+ });
124
+
125
+
126
+ it('parses a line ending with \\r\\n', () => {
127
+ const line = 'field: value\r\n';
128
+
129
+ eventStream.parse(line);
130
+
131
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line.indexOf(':'), line.indexOf('\r'));
132
+ });
133
+
134
+ it('parses 2 lines ending with \\r\\n', () => {
135
+ const line1 = 'field: value\r\n';
136
+ const line2 = 'field2: value2\r\n';
137
+
138
+ eventStream.parse(line1 + line2);
139
+
140
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(0, line1.indexOf(':'), line1.indexOf('\r'));
141
+ expect(eventStream.parseEventStreamLine).to.have.been.calledWith(line1.length, line2.indexOf(':'), line2.indexOf('\r'));
142
+ });
143
+
144
+ it('clears buffer after parsing full lines', () => {
145
+ eventStream.parse('field: value\n');
146
+
147
+ expect(eventStream.buf).to.eql('');
148
+ });
149
+
150
+ it('keeps partial lines in buffer after parsing full lines', () => {
151
+ eventStream.parse('field: value\nfield2');
152
+
153
+ expect(eventStream.buf).to.eql('field2');
154
+ });
155
+ });
156
+
157
+ describe('parseEventStreamLine', () => {
158
+ let eventStream;
159
+ beforeEach(() => {
160
+ eventStream = new EventStream();
161
+ });
162
+
163
+ it('ignores comments', () => {
164
+ // comments starts with : at column 0
165
+ const line = ':ok\n';
166
+ eventStream.buf = line;
167
167
 
168
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
168
+ eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
169
169
 
170
- expect(eventStream.event).not.to.be.ok;
171
- expect(eventStream.data).to.be.eql('');
172
- });
170
+ expect(eventStream.event).not.to.be.ok;
171
+ expect(eventStream.data).to.be.eql('');
172
+ });
173
173
 
174
- it('saves event name', () => {
175
- const line = 'event: testevent\n';
176
- eventStream.buf = line;
174
+ it('saves event name', () => {
175
+ const line = 'event: testevent\n';
176
+ eventStream.buf = line;
177
177
 
178
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
178
+ eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
179
179
 
180
- expect(eventStream.event).to.be.true;
181
- expect(eventStream.eventName).to.eql('testevent');
182
- });
180
+ expect(eventStream.event).to.be.true;
181
+ expect(eventStream.eventName).to.eql('testevent');
182
+ });
183
183
 
184
- it('saves event data', () => {
185
- const line = 'data: {"data":"test"}\n';
186
- eventStream.buf = line;
184
+ it('saves event data', () => {
185
+ const line = 'data: {"data":"test"}\n';
186
+ eventStream.buf = line;
187
187
 
188
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
188
+ eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
189
189
 
190
- expect(eventStream.data).to.eql('{"data":"test"}\n');
191
- });
190
+ expect(eventStream.data).to.eql('{"data":"test"}\n');
191
+ });
192
192
 
193
- it('saves event name and data on separate lines', () => {
194
- const lines = ['event: testevent\n', 'data: {"data":"test"}\n'];
195
- for (let line of lines) {
196
- eventStream.buf = line;
193
+ it('saves event name and data on separate lines', () => {
194
+ const lines = ['event: testevent\n', 'data: {"data":"test"}\n'];
195
+ for (let line of lines) {
196
+ eventStream.buf = line;
197
197
 
198
- eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
199
- }
198
+ eventStream.parseEventStreamLine(0, line.indexOf(':'), line.indexOf('\n'));
199
+ }
200
200
 
201
- expect(eventStream.event).to.be.true;
202
- expect(eventStream.eventName).to.eql('testevent');
203
- expect(eventStream.data).to.eql('{"data":"test"}\n');
204
- });
201
+ expect(eventStream.event).to.be.true;
202
+ expect(eventStream.eventName).to.eql('testevent');
203
+ expect(eventStream.data).to.eql('{"data":"test"}\n');
204
+ });
205
205
 
206
- it('emits event on blank line after saving event name and data', () => {
207
- const handler = sinon.spy();
208
- eventStream.event = true;
209
- eventStream.eventName = 'testevent';
210
- eventStream.data = '{"data":"test"}\n';
211
- eventStream.on('event', handler);
206
+ it('emits event on blank line after saving event name and data', () => {
207
+ const handler = sinon.spy();
208
+ eventStream.event = true;
209
+ eventStream.eventName = 'testevent';
210
+ eventStream.data = '{"data":"test"}\n';
211
+ eventStream.on('event', handler);
212
212
 
213
- eventStream.parseEventStreamLine(0, -1, 0);
213
+ eventStream.parseEventStreamLine(0, -1, 0);
214
214
 
215
- expect(handler).to.have.been.calledWith({
216
- name: 'testevent',
217
- data: 'test'
218
- });
219
- });
215
+ expect(handler).to.have.been.calledWith({
216
+ name: 'testevent',
217
+ data: 'test'
218
+ });
219
+ });
220
220
 
221
- it('emits error if the event handler crashes', () => {
222
- const errorHandler = sinon.spy();
223
- eventStream.event = true;
224
- eventStream.eventName = 'testevent';
225
- eventStream.data = '{"data":"test"}\n';
226
- eventStream.on('error', errorHandler);
227
- eventStream.on('event', () => {
228
- throw new Error('failed!');
229
- });
221
+ it('emits error if the event handler crashes', () => {
222
+ const errorHandler = sinon.spy();
223
+ eventStream.event = true;
224
+ eventStream.eventName = 'testevent';
225
+ eventStream.data = '{"data":"test"}\n';
226
+ eventStream.on('error', errorHandler);
227
+ eventStream.on('event', () => {
228
+ throw new Error('failed!');
229
+ });
230
230
 
231
- eventStream.parseEventStreamLine(0, -1, 0);
231
+ eventStream.parseEventStreamLine(0, -1, 0);
232
232
 
233
- expect(errorHandler).to.have.been.called;
234
- });
233
+ expect(errorHandler).to.have.been.called;
234
+ });
235
235
 
236
- it('clears the event after emitting it', () => {
237
- eventStream.event = true;
238
- eventStream.eventName = 'testevent';
239
- eventStream.data = '{"data":"test"}\n';
236
+ it('clears the event after emitting it', () => {
237
+ eventStream.event = true;
238
+ eventStream.eventName = 'testevent';
239
+ eventStream.data = '{"data":"test"}\n';
240
240
 
241
- eventStream.parseEventStreamLine(0, -1, 0);
241
+ eventStream.parseEventStreamLine(0, -1, 0);
242
242
 
243
- expect(eventStream.event).to.be.false;
244
- expect(eventStream.eventName).to.be.undefined;
245
- expect(eventStream.data).to.eql('');
246
- });
247
-
248
- it('ignores multiple blank lines in succession', () => {
249
- const handler = sinon.spy();
250
- eventStream.on('event', handler);
251
-
252
- eventStream.parseEventStreamLine(0, -1, 0);
253
- eventStream.parseEventStreamLine(0, -1, 0);
254
- eventStream.parseEventStreamLine(0, -1, 0);
255
-
256
- expect(handler).not.to.have.been.called;
257
- });
258
- });
243
+ expect(eventStream.event).to.be.false;
244
+ expect(eventStream.eventName).to.be.undefined;
245
+ expect(eventStream.data).to.eql('');
246
+ });
247
+
248
+ it('ignores multiple blank lines in succession', () => {
249
+ const handler = sinon.spy();
250
+ eventStream.on('event', handler);
251
+
252
+ eventStream.parseEventStreamLine(0, -1, 0);
253
+ eventStream.parseEventStreamLine(0, -1, 0);
254
+ eventStream.parseEventStreamLine(0, -1, 0);
255
+
256
+ expect(handler).not.to.have.been.called;
257
+ });
258
+ });
259
259
  });
package/test/FakeAgent.js CHANGED
@@ -1,26 +1,26 @@
1
1
  class FakeAgent {
2
- get({ uri, auth, headers, query, context }){
3
- return this.request({ uri, method: 'get', auth, headers, query, context });
4
- }
2
+ get({ uri, auth, headers, query, context }){
3
+ return this.request({ uri, method: 'get', auth, headers, query, context });
4
+ }
5
5
 
6
- head({ uri, auth, headers, query, context }){
7
- return this.request({ uri, method: 'head', auth, headers, query, context });
8
- }
6
+ head({ uri, auth, headers, query, context }){
7
+ return this.request({ uri, method: 'head', auth, headers, query, context });
8
+ }
9
9
 
10
- post({ uri, headers, data, auth, context }){
11
- return this.request({ uri, method: 'post', auth, headers, data, context });
12
- }
10
+ post({ uri, headers, data, auth, context }){
11
+ return this.request({ uri, method: 'post', auth, headers, data, context });
12
+ }
13
13
 
14
- put({ uri, auth, headers, data, context }){
15
- return this.request({ uri, method: 'put', auth, headers, data, context });
16
- }
14
+ put({ uri, auth, headers, data, context }){
15
+ return this.request({ uri, method: 'put', auth, headers, data, context });
16
+ }
17
17
 
18
- delete({ uri, auth, headers, data, context }){
19
- return this.request({ uri, method: 'delete', auth, headers, data, context });
20
- }
18
+ delete({ uri, auth, headers, data, context }){
19
+ return this.request({ uri, method: 'delete', auth, headers, data, context });
20
+ }
21
21
 
22
- request(opts){
23
- return new Promise((resolve) => resolve(opts));
24
- }
22
+ request(opts){
23
+ return new Promise((resolve) => resolve(opts));
24
+ }
25
25
  }
26
26
  module.exports = FakeAgent;
@@ -5,35 +5,35 @@ let client = {};
5
5
 
6
6
 
7
7
  describe('Library', () => {
8
- describe('constructor', () => {
9
- it('sets attributes', () => {
10
- const library = new Library(client, {
11
- attributes: {
12
- name: 'testlib',
13
- version: '1.0.0'
14
- }
15
- });
16
- expect(library.name).to.equal('testlib');
17
- expect(library.version).to.equal('1.0.0');
18
- });
19
- });
8
+ describe('constructor', () => {
9
+ it('sets attributes', () => {
10
+ const library = new Library(client, {
11
+ attributes: {
12
+ name: 'testlib',
13
+ version: '1.0.0'
14
+ }
15
+ });
16
+ expect(library.name).to.equal('testlib');
17
+ expect(library.version).to.equal('1.0.0');
18
+ });
19
+ });
20
20
 
21
- describe('download', () => {
22
- it('return the file contents', () => {
23
- client.downloadFile = (url) => {
24
- return Promise.resolve(`${url}-content`);
25
- };
21
+ describe('download', () => {
22
+ it('return the file contents', () => {
23
+ client.downloadFile = (url) => {
24
+ return Promise.resolve(`${url}-content`);
25
+ };
26
26
 
27
- const library = new Library(client, {
28
- attributes: {
29
- name: 'testlib',
30
- version: '1.0.0'
31
- },
32
- links: {
33
- download: 'url'
34
- }
35
- });
36
- expect(library.download()).to.eventually.equal('url-content');
37
- });
38
- });
27
+ const library = new Library(client, {
28
+ attributes: {
29
+ name: 'testlib',
30
+ version: '1.0.0'
31
+ },
32
+ links: {
33
+ download: 'url'
34
+ }
35
+ });
36
+ expect(library.download()).to.eventually.equal('url-content');
37
+ });
38
+ });
39
39
  });