88 "github.com/stretchr/testify/require"
99)
1010
11- func TestDiffMethodParams (t * testing.T ) {
11+ func TestDiffMethodParams_TrailingAddition (t * testing.T ) {
1212 oldMethod := spec.MethodSpec {
1313 Name : "registerClient" ,
1414 Params : []spec.ParamSpec {
@@ -31,9 +31,12 @@ func TestDiffMethodParams(t *testing.T) {
3131
3232 result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
3333 require .Len (t , result , 5 )
34- assert .Equal (t , 0 , result [0 ].MinAPILevel ) // appId: present in both
35- assert .Equal (t , 0 , result [3 ].MinAPILevel ) // transport: present in both
34+ assert .Equal (t , 0 , result [0 ].MinAPILevel ) // appId: present in both
35+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
36+ assert .Equal (t , 0 , result [3 ].MinAPILevel ) // transport: present in both
37+ assert .Equal (t , 0 , result [3 ].MaxAPILevel )
3638 assert .Equal (t , 36 , result [4 ].MinAPILevel ) // attributionSource: added in 36
39+ assert .Equal (t , 0 , result [4 ].MaxAPILevel )
3740}
3841
3942func TestDiffMethodParams_NoChange (t * testing.T ) {
@@ -48,7 +51,9 @@ func TestDiffMethodParams_NoChange(t *testing.T) {
4851 result := diffMethodParams (method , method , 34 , 36 )
4952 require .Len (t , result , 2 )
5053 assert .Equal (t , 0 , result [0 ].MinAPILevel )
54+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
5155 assert .Equal (t , 0 , result [1 ].MinAPILevel )
56+ assert .Equal (t , 0 , result [1 ].MaxAPILevel )
5257}
5358
5459func TestDiffMethodParams_AllNew (t * testing.T ) {
@@ -66,5 +71,265 @@ func TestDiffMethodParams_AllNew(t *testing.T) {
6671 result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
6772 require .Len (t , result , 2 )
6873 assert .Equal (t , 36 , result [0 ].MinAPILevel )
74+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
6975 assert .Equal (t , 36 , result [1 ].MinAPILevel )
76+ assert .Equal (t , 0 , result [1 ].MaxAPILevel )
77+ }
78+
79+ func TestDiffMethodParams_ParamRemoval (t * testing.T ) {
80+ oldMethod := spec.MethodSpec {
81+ Name : "configure" ,
82+ Params : []spec.ParamSpec {
83+ {Name : "id" , Type : spec.TypeRef {Name : "int" }},
84+ {Name : "flags" , Type : spec.TypeRef {Name : "int" }},
85+ {Name : "legacy" , Type : spec.TypeRef {Name : "String" }},
86+ },
87+ }
88+ newMethod := spec.MethodSpec {
89+ Name : "configure" ,
90+ Params : []spec.ParamSpec {
91+ {Name : "id" , Type : spec.TypeRef {Name : "int" }},
92+ },
93+ }
94+
95+ result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
96+ require .Len (t , result , 3 )
97+
98+ // id: unchanged
99+ assert .Equal (t , "id" , result [0 ].Name )
100+ assert .Equal (t , 0 , result [0 ].MinAPILevel )
101+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
102+
103+ // flags: removed (only in old)
104+ assert .Equal (t , "flags" , result [1 ].Name )
105+ assert .Equal (t , 0 , result [1 ].MinAPILevel )
106+ assert .Equal (t , 34 , result [1 ].MaxAPILevel )
107+
108+ // legacy: removed (only in old)
109+ assert .Equal (t , "legacy" , result [2 ].Name )
110+ assert .Equal (t , 0 , result [2 ].MinAPILevel )
111+ assert .Equal (t , 34 , result [2 ].MaxAPILevel )
112+ }
113+
114+ func TestDiffMethodParams_TypeChange (t * testing.T ) {
115+ oldMethod := spec.MethodSpec {
116+ Name : "setConfig" ,
117+ Params : []spec.ParamSpec {
118+ {Name : "key" , Type : spec.TypeRef {Name : "String" }},
119+ {Name : "value" , Type : spec.TypeRef {Name : "int" }},
120+ },
121+ }
122+ newMethod := spec.MethodSpec {
123+ Name : "setConfig" ,
124+ Params : []spec.ParamSpec {
125+ {Name : "key" , Type : spec.TypeRef {Name : "String" }},
126+ {Name : "value" , Type : spec.TypeRef {Name : "ParcelableConfig" }},
127+ },
128+ }
129+
130+ result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
131+ require .Len (t , result , 3 )
132+
133+ // key: unchanged
134+ assert .Equal (t , "key" , result [0 ].Name )
135+ assert .Equal (t , "String" , result [0 ].Type .Name )
136+ assert .Equal (t , 0 , result [0 ].MinAPILevel )
137+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
138+
139+ // value (old variant): capped at oldAPI
140+ assert .Equal (t , "value" , result [1 ].Name )
141+ assert .Equal (t , "int" , result [1 ].Type .Name )
142+ assert .Equal (t , 0 , result [1 ].MinAPILevel )
143+ assert .Equal (t , 34 , result [1 ].MaxAPILevel )
144+
145+ // value (new variant): starts at newAPI
146+ assert .Equal (t , "value" , result [2 ].Name )
147+ assert .Equal (t , "ParcelableConfig" , result [2 ].Type .Name )
148+ assert .Equal (t , 36 , result [2 ].MinAPILevel )
149+ assert .Equal (t , 0 , result [2 ].MaxAPILevel )
150+ }
151+
152+ func TestDiffMethodParams_Mixed (t * testing.T ) {
153+ // Scenario: 4 old params, 3 new params.
154+ // Position 0: same type (unchanged)
155+ // Position 1: different type (type change)
156+ // Position 2: same type (unchanged)
157+ // Position 3: only in old (removed)
158+ // No trailing additions in new.
159+ oldMethod := spec.MethodSpec {
160+ Name : "complexMethod" ,
161+ Params : []spec.ParamSpec {
162+ {Name : "ctx" , Type : spec.TypeRef {Name : "IBinder" }},
163+ {Name : "config" , Type : spec.TypeRef {Name : "int" }},
164+ {Name : "name" , Type : spec.TypeRef {Name : "String" }},
165+ {Name : "debug" , Type : spec.TypeRef {Name : "boolean" }},
166+ },
167+ }
168+ newMethod := spec.MethodSpec {
169+ Name : "complexMethod" ,
170+ Params : []spec.ParamSpec {
171+ {Name : "ctx" , Type : spec.TypeRef {Name : "IBinder" }},
172+ {Name : "config" , Type : spec.TypeRef {Name : "Bundle" }},
173+ {Name : "name" , Type : spec.TypeRef {Name : "String" }},
174+ },
175+ }
176+
177+ result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
178+
179+ // Expected: ctx, config(old), config(new), name, debug(removed) = 5 entries.
180+ require .Len (t , result , 5 )
181+
182+ // ctx: unchanged
183+ assert .Equal (t , "ctx" , result [0 ].Name )
184+ assert .Equal (t , "IBinder" , result [0 ].Type .Name )
185+ assert .Equal (t , 0 , result [0 ].MinAPILevel )
186+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
187+
188+ // config (old variant): capped
189+ assert .Equal (t , "config" , result [1 ].Name )
190+ assert .Equal (t , "int" , result [1 ].Type .Name )
191+ assert .Equal (t , 0 , result [1 ].MinAPILevel )
192+ assert .Equal (t , 34 , result [1 ].MaxAPILevel )
193+
194+ // config (new variant): starts at newAPI
195+ assert .Equal (t , "config" , result [2 ].Name )
196+ assert .Equal (t , "Bundle" , result [2 ].Type .Name )
197+ assert .Equal (t , 36 , result [2 ].MinAPILevel )
198+ assert .Equal (t , 0 , result [2 ].MaxAPILevel )
199+
200+ // name: unchanged
201+ assert .Equal (t , "name" , result [3 ].Name )
202+ assert .Equal (t , "String" , result [3 ].Type .Name )
203+ assert .Equal (t , 0 , result [3 ].MinAPILevel )
204+ assert .Equal (t , 0 , result [3 ].MaxAPILevel )
205+
206+ // debug: removed
207+ assert .Equal (t , "debug" , result [4 ].Name )
208+ assert .Equal (t , "boolean" , result [4 ].Type .Name )
209+ assert .Equal (t , 0 , result [4 ].MinAPILevel )
210+ assert .Equal (t , 34 , result [4 ].MaxAPILevel )
211+ }
212+
213+ func TestDiffMethodParams_MixedWithTrailingAddition (t * testing.T ) {
214+ // Position 0: same (unchanged)
215+ // Position 1: different type (type change)
216+ // Position 2: only in new (trailing addition)
217+ oldMethod := spec.MethodSpec {
218+ Name : "update" ,
219+ Params : []spec.ParamSpec {
220+ {Name : "id" , Type : spec.TypeRef {Name : "int" }},
221+ {Name : "data" , Type : spec.TypeRef {Name : "byte" , IsArray : true }},
222+ },
223+ }
224+ newMethod := spec.MethodSpec {
225+ Name : "update" ,
226+ Params : []spec.ParamSpec {
227+ {Name : "id" , Type : spec.TypeRef {Name : "int" }},
228+ {Name : "data" , Type : spec.TypeRef {Name : "ParcelFileDescriptor" }},
229+ {Name : "flags" , Type : spec.TypeRef {Name : "int" }},
230+ },
231+ }
232+
233+ result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
234+
235+ // Expected: id, data(old), data(new), flags = 4 entries.
236+ require .Len (t , result , 4 )
237+
238+ // id: unchanged
239+ assert .Equal (t , "id" , result [0 ].Name )
240+ assert .Equal (t , 0 , result [0 ].MinAPILevel )
241+ assert .Equal (t , 0 , result [0 ].MaxAPILevel )
242+
243+ // data (old): capped
244+ assert .Equal (t , "data" , result [1 ].Name )
245+ assert .Equal (t , "byte" , result [1 ].Type .Name )
246+ assert .Equal (t , 0 , result [1 ].MinAPILevel )
247+ assert .Equal (t , 34 , result [1 ].MaxAPILevel )
248+
249+ // data (new): starts at newAPI
250+ assert .Equal (t , "data" , result [2 ].Name )
251+ assert .Equal (t , "ParcelFileDescriptor" , result [2 ].Type .Name )
252+ assert .Equal (t , 36 , result [2 ].MinAPILevel )
253+ assert .Equal (t , 0 , result [2 ].MaxAPILevel )
254+
255+ // flags: trailing addition
256+ assert .Equal (t , "flags" , result [3 ].Name )
257+ assert .Equal (t , 36 , result [3 ].MinAPILevel )
258+ assert .Equal (t , 0 , result [3 ].MaxAPILevel )
259+ }
260+
261+ func TestDiffMethodParams_GenericTypeArgs (t * testing.T ) {
262+ // Verify that TypeRef.Equal compares TypeArgs recursively.
263+ oldMethod := spec.MethodSpec {
264+ Name : "getItems" ,
265+ Params : []spec.ParamSpec {
266+ {
267+ Name : "items" ,
268+ Type : spec.TypeRef {
269+ Name : "List" ,
270+ TypeArgs : []spec.TypeRef {{Name : "String" }},
271+ },
272+ },
273+ },
274+ }
275+ newMethod := spec.MethodSpec {
276+ Name : "getItems" ,
277+ Params : []spec.ParamSpec {
278+ {
279+ Name : "items" ,
280+ Type : spec.TypeRef {
281+ Name : "List" ,
282+ TypeArgs : []spec.TypeRef {{Name : "ParcelableItem" }},
283+ },
284+ },
285+ },
286+ }
287+
288+ result := diffMethodParams (oldMethod , newMethod , 34 , 36 )
289+ require .Len (t , result , 2 )
290+
291+ // old variant: List<String> capped
292+ assert .Equal (t , "List" , result [0 ].Type .Name )
293+ assert .Equal (t , "String" , result [0 ].Type .TypeArgs [0 ].Name )
294+ assert .Equal (t , 34 , result [0 ].MaxAPILevel )
295+
296+ // new variant: List<ParcelableItem> starts
297+ assert .Equal (t , "List" , result [1 ].Type .Name )
298+ assert .Equal (t , "ParcelableItem" , result [1 ].Type .TypeArgs [0 ].Name )
299+ assert .Equal (t , 36 , result [1 ].MinAPILevel )
300+ }
301+
302+ func TestParamsChanged (t * testing.T ) {
303+ t .Run ("equal" , func (t * testing.T ) {
304+ params := []spec.ParamSpec {
305+ {Name : "a" , Type : spec.TypeRef {Name : "int" }},
306+ {Name : "b" , Type : spec.TypeRef {Name : "String" }},
307+ }
308+ assert .False (t , paramsChanged (params , params ))
309+ })
310+
311+ t .Run ("different_length" , func (t * testing.T ) {
312+ old := []spec.ParamSpec {
313+ {Name : "a" , Type : spec.TypeRef {Name : "int" }},
314+ }
315+ new := []spec.ParamSpec {
316+ {Name : "a" , Type : spec.TypeRef {Name : "int" }},
317+ {Name : "b" , Type : spec.TypeRef {Name : "String" }},
318+ }
319+ assert .True (t , paramsChanged (old , new ))
320+ })
321+
322+ t .Run ("different_type" , func (t * testing.T ) {
323+ old := []spec.ParamSpec {
324+ {Name : "a" , Type : spec.TypeRef {Name : "int" }},
325+ }
326+ new := []spec.ParamSpec {
327+ {Name : "a" , Type : spec.TypeRef {Name : "long" }},
328+ }
329+ assert .True (t , paramsChanged (old , new ))
330+ })
331+
332+ t .Run ("both_empty" , func (t * testing.T ) {
333+ assert .False (t , paramsChanged (nil , nil ))
334+ })
70335}
0 commit comments