1
+ import { fromProtobufObject } from "../src" ;
2
+ import { BookStore } from "./test-data/generated/book-store_pb" ;
3
+ import { PhoneShop } from "./test-data/generated/phone-shop_pb" ;
4
+ import { Forest } from "./test-data/generated/forest_pb" ;
5
+ import { Universe } from "./test-data/generated/universe_pb" ;
6
+ import { Spices } from "./test-data/generated/spices_pb" ;
7
+ import { Newspaper } from "./test-data/generated/newspaper_pb" ;
8
+
9
+ describe ( 'fromProtobufObject' , ( ) => {
10
+ it ( 'Should work with easy structure' , ( ) => {
11
+ const obj = {
12
+ name : 'Harry Potter' ,
13
+ shelf : 3 ,
14
+ } satisfies BookStore . AsObject ;
15
+ const bookStore = fromProtobufObject ( BookStore , obj ) ;
16
+ expect ( bookStore . toObject ( ) ) . toEqual ( obj ) ;
17
+ } ) ;
18
+
19
+ it ( 'Should work with nested structure' , ( ) => {
20
+ const obj = {
21
+ id : 1 ,
22
+ phone : {
23
+ model : 'iPhone 11' ,
24
+ diagonal : 6 ,
25
+ price : 999 ,
26
+ company : {
27
+ name : 'Apple' ,
28
+ country : 'USA' ,
29
+ } ,
30
+ } ,
31
+ } satisfies PhoneShop . AsObject ;
32
+ const phoneShop = fromProtobufObject ( PhoneShop , obj ) ;
33
+ expect ( phoneShop . toObject ( ) ) . toEqual ( obj ) ;
34
+ } ) ;
35
+
36
+ it ( 'Should ignore extra params' , ( ) => {
37
+ const planetsList = [ 'Earth' , 'Mars' , 'Venus' ] ;
38
+ const obj = {
39
+ planetsList,
40
+ extra : 'data' ,
41
+ } as Universe . AsObject ;
42
+ const universe = fromProtobufObject ( Universe , obj ) ;
43
+ expect ( universe . toObject ( ) ) . toEqual ( { planetsList } satisfies Universe . AsObject ) ;
44
+ } ) ;
45
+
46
+ it ( 'Should throw when lack of params' , ( ) => {
47
+ const obj = {
48
+ name : 'Esperanto' ,
49
+ } as BookStore . AsObject ;
50
+ expect ( ( ) => fromProtobufObject ( BookStore , obj ) ) . toThrowError ( `Missing property 'shelf'` ) ;
51
+ } ) ;
52
+
53
+ it ( 'Should not throw when lack of array params' , ( ) => {
54
+ const obj = { } as Universe . AsObject ;
55
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . not . toThrowError ( `Missing property 'planetsList'` ) ;
56
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . not . toThrow ( ) ;
57
+ } ) ;
58
+
59
+ it ( 'Should throw when null value' , ( ) => {
60
+ const obj = {
61
+ planetsList : null ,
62
+ } as unknown as Universe . AsObject ;
63
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . toThrowError ( `Null value for key 'planetsList'` ) ;
64
+ } ) ;
65
+
66
+ it ( 'Should not throw when extra null value' , ( ) => {
67
+ const obj = {
68
+ planetsList : [ 'Saturn' ] ,
69
+ extra : null ,
70
+ } as Universe . AsObject ;
71
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . not . toThrowError ( `Null value for key 'extra'` ) ;
72
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . not . toThrow ( ) ;
73
+ } ) ;
74
+ } ) ;
75
+
76
+ describe ( 'Oneof rule' , ( ) => {
77
+ it ( 'Should work with oneof rule' , ( ) => {
78
+ const objNews = {
79
+ id : 1 ,
80
+ name : 'The New York Times' ,
81
+ isAds : true ,
82
+ isNews : true ,
83
+ contentByPageMap : [ ] ,
84
+ adsByPageMap : [ ] ,
85
+ } satisfies Newspaper . AsObject ;
86
+ const objAds = {
87
+ id : 2 ,
88
+ name : 'RBK' ,
89
+ isNews : true ,
90
+ isAds : true ,
91
+ contentByPageMap : [ ] ,
92
+ adsByPageMap : [ ] ,
93
+ } satisfies Newspaper . AsObject ;
94
+ const newspaperNews = fromProtobufObject ( Newspaper , objNews ) ;
95
+ const newspaperAds = fromProtobufObject ( Newspaper , objAds ) ;
96
+ expect ( newspaperNews . toObject ( ) ) . toEqual ( { ...objNews , isAds : false } ) ;
97
+ expect ( newspaperAds . toObject ( ) ) . toEqual ( { ...objAds , isNews : false } ) ;
98
+ } ) ;
99
+ } ) ;
100
+
101
+ describe ( 'Validation' , ( ) => {
102
+ it ( 'Should validate simple type' , ( ) => {
103
+ const obj = {
104
+ name : 'Harry Potter' ,
105
+ shelf : 'second' ,
106
+ } as unknown as BookStore . AsObject ;
107
+ expect ( ( ) => fromProtobufObject ( BookStore , obj ) ) . toThrowError ( `Invalid type for 'shelf' (expected 'number', got 'string')` ) ;
108
+ } ) ;
109
+
110
+ it ( 'Should validate nested structure' , ( ) => {
111
+ const obj = {
112
+ id : 1 ,
113
+ phone : 123 ,
114
+ } as unknown as PhoneShop . AsObject ;
115
+ expect ( ( ) => fromProtobufObject ( PhoneShop , obj ) ) . toThrowError ( `Invalid type for 'phone' (expected 'object', got 'number')` ) ;
116
+ } ) ;
117
+
118
+ it ( 'Should not throw on undefined objects' , ( ) => {
119
+ const obj = {
120
+ id : 1 ,
121
+ phone : undefined ,
122
+ } satisfies PhoneShop . AsObject ;
123
+ expect ( ( ) => fromProtobufObject ( PhoneShop , obj ) ) . not . toThrow ( ) ;
124
+ } ) ;
125
+
126
+ it ( 'Should validate simple array' , ( ) => {
127
+ const obj = {
128
+ planetsList : true ,
129
+ } as unknown as Universe . AsObject ;
130
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . toThrowError ( `Invalid type for 'planetsList' (expected array, got 'boolean')` ) ;
131
+ } ) ;
132
+
133
+ it ( 'Should validate simple false array' , ( ) => {
134
+ const obj = {
135
+ name : 'Gary Garrison' ,
136
+ shelf : [ 4 , 2 ] ,
137
+ } as unknown as BookStore . AsObject ;
138
+ expect ( ( ) => fromProtobufObject ( BookStore , obj ) ) . toThrowError ( `Invalid type for 'shelf' (expected 'number', got array)` ) ;
139
+ } ) ;
140
+ } ) ;
141
+
142
+ describe ( 'Repeated rule' , ( ) => {
143
+ it ( 'Should work with simple array' , ( ) => {
144
+ const obj = {
145
+ planetsList : [ 'Earth' , 'Mars' , 'Venus' ] ,
146
+ } satisfies Universe . AsObject ;
147
+ const universe = fromProtobufObject ( Universe , obj ) ;
148
+ expect ( universe . toObject ( ) ) . toEqual ( obj ) ;
149
+ } ) ;
150
+
151
+ it ( 'Should work with empty array' , ( ) => {
152
+ const obj = {
153
+ planetsList : [ ] ,
154
+ } satisfies Universe . AsObject ;
155
+ const universe = fromProtobufObject ( Universe , obj ) ;
156
+ expect ( universe . toObject ( ) ) . toEqual ( obj ) ;
157
+ } ) ;
158
+
159
+
160
+ it ( 'Should work with array structure' , ( ) => {
161
+ const obj = {
162
+ treesList : [
163
+ { age : 1 , height : 10 } ,
164
+ { age : 5 , height : 42 } ,
165
+ ] ,
166
+ info : {
167
+ name : 'Forest' ,
168
+ numberOfTrees : 4000 ,
169
+ } ,
170
+ } satisfies Forest . AsObject ;
171
+ const forest = fromProtobufObject ( Forest , obj ) ;
172
+ expect ( forest . toObject ( ) ) . toEqual ( obj ) ;
173
+ } ) ;
174
+
175
+ it ( 'Should throw when null in array' , ( ) => {
176
+ const obj = {
177
+ planetsList : [ null ] ,
178
+ } as unknown as Universe . AsObject ;
179
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . toThrowError ( `Null value for key 'planetsList'` ) ;
180
+ } ) ;
181
+
182
+ it ( 'Should throw when mixed array' , ( ) => {
183
+ const obj = {
184
+ planetsList : [ 'Saturn' , { } ] ,
185
+ } as Universe . AsObject ;
186
+ expect ( ( ) => fromProtobufObject ( Universe , obj ) ) . toThrowError ( `Mixed array for 'planetsList'` ) ;
187
+ } ) ;
188
+ } ) ;
189
+
190
+ describe ( 'Recursive messages' , ( ) => {
191
+ it ( 'Should work with recursive' , ( ) => {
192
+ const obj = {
193
+ name : 'Pork' ,
194
+ mixed : {
195
+ spicesList : [
196
+ { name : 'Pepper' } ,
197
+ {
198
+ name : 'Salt' ,
199
+ mixed : {
200
+ spicesList : [ {
201
+ name : 'Dark' ,
202
+ mixed : { spicesList : [ { name : 'Void' } ] } ,
203
+ } ] ,
204
+ } ,
205
+ } ,
206
+ ] ,
207
+ } ,
208
+ } satisfies Spices . AsObject ;
209
+ const spices = fromProtobufObject ( Spices , obj ) ;
210
+ expect ( spices . toObject ( ) ) . toEqual ( obj ) ;
211
+ } ) ;
212
+ } ) ;
213
+
214
+ describe ( 'Map rule' , ( ) => {
215
+ it ( 'Should work with simple map' , ( ) => {
216
+ const obj = {
217
+ id : 1 ,
218
+ name : 'The New York Times' ,
219
+ isAds : false ,
220
+ isNews : true ,
221
+ contentByPageMap : [
222
+ [ 1 , 'fist page' ] ,
223
+ [ 2 , 'second page' ] ,
224
+ ] ,
225
+ adsByPageMap : [ ] ,
226
+ } satisfies Newspaper . AsObject ;
227
+
228
+ const newspaper = fromProtobufObject ( Newspaper , obj ) ;
229
+ expect ( newspaper . toObject ( ) ) . toEqual ( obj ) ;
230
+ } ) ;
231
+
232
+ it ( 'Should work with nested type' , ( ) => {
233
+ const obj = {
234
+ id : 1 ,
235
+ name : 'The New York Times' ,
236
+ isAds : false ,
237
+ isNews : true ,
238
+ contentByPageMap : [ ] ,
239
+ adsByPageMap : [
240
+ [ 1 , { data : 'Google' } ] ,
241
+ [ 2 , { data : 'Facebook' } ] ,
242
+ ] ,
243
+ } satisfies Newspaper . AsObject ;
244
+
245
+ const newspaper = fromProtobufObject ( Newspaper , obj ) ;
246
+ expect ( newspaper . toObject ( ) ) . toEqual ( obj ) ;
247
+ } ) ;
248
+ } ) ;
0 commit comments