@@ -98,4 +98,148 @@ describe('resultTransformers', () => {
9898 } )
9999 } )
100100 } )
101+
102+ describe ( '.mappedResultTransformer' , ( ) => {
103+ describe ( 'with a valid result' , ( ) => {
104+ it ( 'should map and collect the result' , async ( ) => {
105+ const {
106+ rawRecords,
107+ result,
108+ keys,
109+ meta,
110+ query,
111+ params
112+ } = scenario ( )
113+
114+ const map = jest . fn ( ( record ) => record . get ( 'a' ) as number )
115+ const collect = jest . fn ( ( records : number [ ] , summary : ResultSummary , keys : string [ ] ) => ( {
116+ as : records ,
117+ db : summary . database . name ,
118+ ks : keys
119+ } ) )
120+
121+ const transform = resultTransformers . mappedResultTransformer ( { map, collect } )
122+
123+ const { as, db, ks } : { as : number [ ] , db : string | undefined | null , ks : string [ ] } = await transform ( result )
124+
125+ expect ( as ) . toEqual ( rawRecords . map ( rec => rec [ 0 ] ) )
126+ expect ( db ) . toEqual ( meta . db )
127+ expect ( ks ) . toEqual ( keys )
128+
129+ expect ( map ) . toHaveBeenCalledTimes ( rawRecords . length )
130+
131+ for ( const rawRecord of rawRecords ) {
132+ expect ( map ) . toHaveBeenCalledWith ( new Record ( keys , rawRecord ) )
133+ }
134+
135+ expect ( collect ) . toHaveBeenCalledTimes ( 1 )
136+ expect ( collect ) . toHaveBeenCalledWith ( rawRecords . map ( rec => rec [ 0 ] ) , new ResultSummary ( query , params , meta ) , keys )
137+ } )
138+
139+ it ( 'should map the records' , async ( ) => {
140+ const {
141+ rawRecords,
142+ result,
143+ keys,
144+ meta,
145+ query,
146+ params
147+ } = scenario ( )
148+
149+ const map = jest . fn ( ( record ) => record . get ( 'a' ) as number )
150+
151+ const transform = resultTransformers . mappedResultTransformer ( { map } )
152+
153+ const { records : as , summary, keys : receivedKeys } : { records : number [ ] , summary : ResultSummary , keys : string [ ] } = await transform ( result )
154+
155+ expect ( as ) . toEqual ( rawRecords . map ( rec => rec [ 0 ] ) )
156+ expect ( summary ) . toEqual ( new ResultSummary ( query , params , meta ) )
157+ expect ( receivedKeys ) . toEqual ( keys )
158+
159+ expect ( map ) . toHaveBeenCalledTimes ( rawRecords . length )
160+
161+ for ( const rawRecord of rawRecords ) {
162+ expect ( map ) . toHaveBeenCalledWith ( new Record ( keys , rawRecord ) )
163+ }
164+ } )
165+
166+ it ( 'should collect the result' , async ( ) => {
167+ const {
168+ rawRecords,
169+ result,
170+ keys,
171+ meta,
172+ query,
173+ params
174+ } = scenario ( )
175+
176+ const collect = jest . fn ( ( records : Record [ ] , summary : ResultSummary , keys : string [ ] ) => ( {
177+ recordsFetched : records . length ,
178+ db : summary . database . name ,
179+ ks : keys
180+ } ) )
181+
182+ const transform = resultTransformers . mappedResultTransformer ( { collect } )
183+
184+ const { recordsFetched, db, ks } : { recordsFetched : number , db : string | undefined | null , ks : string [ ] } = await transform ( result )
185+
186+ expect ( recordsFetched ) . toEqual ( rawRecords . length )
187+ expect ( db ) . toEqual ( meta . db )
188+ expect ( ks ) . toEqual ( keys )
189+
190+ expect ( collect ) . toHaveBeenCalledTimes ( 1 )
191+ expect ( collect ) . toHaveBeenCalledWith ( rawRecords . map ( rec => new Record ( keys , rec ) ) , new ResultSummary ( query , params , meta ) , keys )
192+ } )
193+
194+ it . each ( [
195+ undefined ,
196+ null ,
197+ { } ,
198+ { Map : ( ) => { } } ,
199+ { Collect : ( ) => { } }
200+ ] ) ( 'should throw if miss-configured [config=%o]' , ( config ) => {
201+ // @ts -expect-error
202+ expect ( ( ) => resultTransformers . mappedResultTransformer ( config ) )
203+ . toThrow ( newError ( 'Requires a map or/and a collect functions.' ) )
204+ } )
205+
206+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
207+ function scenario ( ) {
208+ const resultStreamObserverMock = new ResultStreamObserverMock ( )
209+ const query = 'Query'
210+ const params = { a : 1 }
211+ const meta = { db : 'adb' }
212+ const result = new Result ( Promise . resolve ( resultStreamObserverMock ) , query , params )
213+ const keys = [ 'a' , 'b' ]
214+ const rawRecord1 = [ 1 , 2 ]
215+ const rawRecord2 = [ 3 , 4 ]
216+ resultStreamObserverMock . onKeys ( keys )
217+ resultStreamObserverMock . onNext ( rawRecord1 )
218+ resultStreamObserverMock . onNext ( rawRecord2 )
219+ resultStreamObserverMock . onCompleted ( meta )
220+
221+ return {
222+ resultStreamObserverMock,
223+ result,
224+ meta,
225+ params,
226+ keys,
227+ query,
228+ rawRecords : [ rawRecord1 , rawRecord2 ]
229+ }
230+ }
231+ } )
232+
233+ describe ( 'when results fail' , ( ) => {
234+ it ( 'should propagate the exception' , async ( ) => {
235+ const expectedError = newError ( 'expected error' )
236+ const result = new Result ( Promise . reject ( expectedError ) , 'query' )
237+ const transformer = resultTransformers . mappedResultTransformer ( {
238+ collect : ( records ) => records
239+ } )
240+
241+ await expect ( transformer ( result ) ) . rejects . toThrow ( expectedError )
242+ } )
243+ } )
244+ } )
101245} )
0 commit comments