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