• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2021 The Pigweed Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License"); you may not
4// use this file except in compliance with the License. You may obtain a copy of
5// the License at
6//
7//     https://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12// License for the specific language governing permissions and limitations under
13// the License.
14
15/* eslint-env browser, jasmine */
16import 'jasmine';
17
18import {SomeMessage} from 'test_protos_tspb/test_protos_tspb_pb/pw_rpc/ts/test2_pb';
19
20import {Call} from './call';
21import {Channel, Method, Service} from './descriptors';
22import {PendingCalls, Rpc} from './rpc_classes';
23
24class FakeRpc {
25  readonly channel: any = undefined;
26  readonly service: any = undefined;
27  readonly method: any = undefined;
28
29  idSet: [number, number, number] = [1, 2, 3];
30  idString = '1.2.3';
31}
32
33describe('Call', () => {
34  let call: Call;
35
36  beforeEach(() => {
37    const noop = () => {};
38    const pendingCalls = new PendingCalls();
39    const channel = jasmine.createSpy();
40    const rpc = new FakeRpc();
41    call = new Call(pendingCalls, rpc, noop, noop, noop);
42  });
43
44  function newMessage(magicNumber = 1): SomeMessage {
45    const message = new SomeMessage();
46    message.setMagicNumber(magicNumber);
47    return message;
48  }
49
50  it('getResponse returns all responses.', async () => {
51    const message1 = newMessage(1);
52    const message2 = newMessage(2);
53    const message3 = newMessage(3);
54
55    // Queue three responses
56    call.handleResponse(message1);
57    call.handleResponse(message2);
58    call.handleResponse(message3);
59
60    let responses = call.getResponses(2);
61    expect((await responses.next()).value).toEqual(message1);
62    expect((await responses.next()).value).toEqual(message2);
63    expect((await responses.next()).done).toBeTrue();
64
65    responses = call.getResponses(1);
66    expect((await responses.next()).value).toEqual(message3);
67    expect((await responses.next()).done).toBeTrue();
68  });
69
70  it('getResponse early returns on stream end.', async () => {
71    const message = newMessage();
72    const responses = call.getResponses(2);
73
74    // Queue one response and an early completion.
75    call.handleResponse(message);
76    call.handleCompletion(0);
77
78    expect((await responses.next()).value).toEqual(message);
79    expect((await responses.next()).done).toBeTrue();
80  });
81
82  it('getResponse promise is rejected on stream error.', async () => {
83    const message = newMessage();
84    const responses = call.getResponses(3);
85
86    call.handleResponse(message);
87    expect((await responses.next()).value).toEqual(message);
88
89    call.handleResponse(message);
90    call.handleError(1);
91
92    // Promise is rejected as soon as an error is received, even if there is a
93    // response in the queue.
94    await expectAsync(responses.next()).toBeRejected();
95  });
96
97  it('getResponse waits if queue is empty', async () => {
98    const message1 = newMessage(1);
99    const message2 = newMessage(2);
100    const responses = call.getResponses(2);
101
102    // Queue two responses after a small delay
103    setTimeout(() => {
104      call.handleResponse(message1);
105      call.handleResponse(message2);
106      call.handleCompletion(0);
107      expect(call.completed).toBeTrue();
108    }, 200);
109
110    expect(call.completed).toBeFalse();
111    expect((await responses.next()).value).toEqual(message1);
112    expect((await responses.next()).value).toEqual(message2);
113    expect((await responses.next()).done).toBeTrue();
114  });
115
116  it('getResponse without count fetches all results', async () => {
117    const message1 = newMessage(1);
118    const message2 = newMessage(2);
119    const responses = call.getResponses();
120
121    call.handleResponse(message1);
122    expect((await responses.next()).value).toEqual(message1);
123
124    setTimeout(() => {
125      call.handleResponse(message2);
126      call.handleCompletion(0);
127      expect(call.completed).toBeTrue();
128    }, 200);
129
130    expect(call.completed).toBeFalse();
131    expect((await responses.next()).value).toEqual(message2);
132    expect((await responses.next()).done).toBeTrue();
133  });
134});
135