1 // SPDX-FileCopyrightText: 2020 Robin Krahl <[email protected]>
2 // SPDX-License-Identifier: Apache-2.0 or MIT
3 
4 #![cfg(feature = "derive")]
5 
6 use merge::Merge;
7 
test<T: std::fmt::Debug + Merge + PartialEq>(expected: T, mut left: T, right: T)8 fn test<T: std::fmt::Debug + Merge + PartialEq>(expected: T, mut left: T, right: T) {
9     left.merge(right);
10     assert_eq!(expected, left);
11 }
12 
13 #[test]
test_one_option_field()14 fn test_one_option_field() {
15     #[derive(Debug, Merge, PartialEq)]
16     struct S {
17         field1: Option<usize>,
18     }
19 
20     impl S {
21         pub fn new(field1: Option<usize>) -> S {
22             S { field1 }
23         }
24     }
25 
26     test(S::new(Some(1)), S::new(Some(1)), S::new(Some(2)));
27     test(S::new(Some(1)), S::new(Some(1)), S::new(None));
28     test(S::new(Some(2)), S::new(None), S::new(Some(2)));
29     test(S::new(None), S::new(None), S::new(None));
30 }
31 
32 #[test]
test_two_option_fields()33 fn test_two_option_fields() {
34     #[derive(Debug, Merge, PartialEq)]
35     struct S {
36         field1: Option<usize>,
37         field2: Option<usize>,
38     }
39 
40     impl S {
41         pub fn new(field1: Option<usize>, field2: Option<usize>) -> S {
42             S { field1, field2 }
43         }
44     }
45 
46     // left.field1 == Some(1)
47     // right.field1 == Some(2)
48     test(
49         S::new(Some(1), Some(1)),
50         S::new(Some(1), Some(1)),
51         S::new(Some(2), Some(2)),
52     );
53     test(
54         S::new(Some(1), Some(1)),
55         S::new(Some(1), Some(1)),
56         S::new(Some(2), None),
57     );
58     test(
59         S::new(Some(1), Some(2)),
60         S::new(Some(1), None),
61         S::new(Some(2), Some(2)),
62     );
63     test(
64         S::new(Some(1), None),
65         S::new(Some(1), None),
66         S::new(Some(2), None),
67     );
68 
69     // left.field1 == Some(1)
70     // right.field1 == None
71     test(
72         S::new(Some(1), Some(1)),
73         S::new(Some(1), Some(1)),
74         S::new(None, Some(2)),
75     );
76     test(
77         S::new(Some(1), Some(1)),
78         S::new(Some(1), Some(1)),
79         S::new(None, None),
80     );
81     test(
82         S::new(Some(1), Some(2)),
83         S::new(Some(1), None),
84         S::new(None, Some(2)),
85     );
86     test(
87         S::new(Some(1), None),
88         S::new(Some(1), None),
89         S::new(None, None),
90     );
91 
92     // left.field1 == None
93     // right.field1 == Some(2)
94     test(
95         S::new(Some(2), Some(1)),
96         S::new(None, Some(1)),
97         S::new(Some(2), Some(2)),
98     );
99     test(
100         S::new(Some(2), Some(1)),
101         S::new(None, Some(1)),
102         S::new(Some(2), None),
103     );
104     test(
105         S::new(Some(2), Some(2)),
106         S::new(None, None),
107         S::new(Some(2), Some(2)),
108     );
109     test(
110         S::new(Some(2), None),
111         S::new(None, None),
112         S::new(Some(2), None),
113     );
114 
115     // left.field1 == None
116     // right.field1 == None
117     test(
118         S::new(None, Some(1)),
119         S::new(None, Some(1)),
120         S::new(None, Some(2)),
121     );
122     test(
123         S::new(None, Some(1)),
124         S::new(None, Some(1)),
125         S::new(None, None),
126     );
127     test(
128         S::new(None, Some(2)),
129         S::new(None, None),
130         S::new(None, Some(2)),
131     );
132     test(S::new(None, None), S::new(None, None), S::new(None, None));
133 }
134 
135 #[test]
test_skip_valid()136 fn test_skip_valid() {
137     #[derive(Debug, Merge, PartialEq)]
138     struct S {
139         field1: Option<usize>,
140         #[merge(skip)]
141         field2: Option<usize>,
142     }
143 
144     impl S {
145         pub fn new(field1: Option<usize>, field2: Option<usize>) -> S {
146             S { field1, field2 }
147         }
148     }
149 
150     // left.field1 == Some(1)
151     // right.field1 == Some(2)
152     test(
153         S::new(Some(1), Some(1)),
154         S::new(Some(1), Some(1)),
155         S::new(Some(2), Some(2)),
156     );
157     test(
158         S::new(Some(1), Some(1)),
159         S::new(Some(1), Some(1)),
160         S::new(Some(2), None),
161     );
162     test(
163         S::new(Some(1), None),
164         S::new(Some(1), None),
165         S::new(Some(2), Some(2)),
166     );
167     test(
168         S::new(Some(1), None),
169         S::new(Some(1), None),
170         S::new(Some(2), None),
171     );
172 
173     // left.field1 == Some(1)
174     // right.field1 == None
175     test(
176         S::new(Some(1), Some(1)),
177         S::new(Some(1), Some(1)),
178         S::new(None, Some(2)),
179     );
180     test(
181         S::new(Some(1), Some(1)),
182         S::new(Some(1), Some(1)),
183         S::new(None, None),
184     );
185     test(
186         S::new(Some(1), None),
187         S::new(Some(1), None),
188         S::new(None, Some(2)),
189     );
190     test(
191         S::new(Some(1), None),
192         S::new(Some(1), None),
193         S::new(None, None),
194     );
195 
196     // left.field1 == None
197     // right.field1 == Some(2)
198     test(
199         S::new(Some(2), Some(1)),
200         S::new(None, Some(1)),
201         S::new(Some(2), Some(2)),
202     );
203     test(
204         S::new(Some(2), Some(1)),
205         S::new(None, Some(1)),
206         S::new(Some(2), None),
207     );
208     test(
209         S::new(Some(2), None),
210         S::new(None, None),
211         S::new(Some(2), Some(2)),
212     );
213     test(
214         S::new(Some(2), None),
215         S::new(None, None),
216         S::new(Some(2), None),
217     );
218 
219     // left.field1 == None
220     // right.field1 == None
221     test(
222         S::new(None, Some(1)),
223         S::new(None, Some(1)),
224         S::new(None, Some(2)),
225     );
226     test(
227         S::new(None, Some(1)),
228         S::new(None, Some(1)),
229         S::new(None, None),
230     );
231     test(
232         S::new(None, None),
233         S::new(None, None),
234         S::new(None, Some(2)),
235     );
236     test(S::new(None, None), S::new(None, None), S::new(None, None));
237 }
238 
239 #[test]
test_skip_invalid()240 fn test_skip_invalid() {
241     #[derive(Debug, Merge, PartialEq)]
242     struct S {
243         field1: Option<usize>,
244         #[merge(skip)]
245         field2: usize,
246     }
247 
248     impl S {
249         pub fn new(field1: Option<usize>, field2: usize) -> S {
250             S { field1, field2 }
251         }
252     }
253 
254     // left.field1 == Some(1)
255     // right.field1 == Some(2)
256     test(S::new(Some(1), 1), S::new(Some(1), 1), S::new(Some(2), 2));
257     test(S::new(Some(1), 1), S::new(Some(1), 1), S::new(Some(2), 0));
258     test(S::new(Some(1), 0), S::new(Some(1), 0), S::new(Some(2), 2));
259     test(S::new(Some(1), 0), S::new(Some(1), 0), S::new(Some(2), 0));
260 
261     // left.field1 == Some(1)
262     // right.field1 == None
263     test(S::new(Some(1), 1), S::new(Some(1), 1), S::new(None, 2));
264     test(S::new(Some(1), 1), S::new(Some(1), 1), S::new(None, 0));
265     test(S::new(Some(1), 0), S::new(Some(1), 0), S::new(None, 2));
266     test(S::new(Some(1), 0), S::new(Some(1), 0), S::new(None, 0));
267 
268     // left.field1 == None
269     // right.field1 == Some(2)
270     test(S::new(Some(2), 1), S::new(None, 1), S::new(Some(2), 2));
271     test(S::new(Some(2), 1), S::new(None, 1), S::new(Some(2), 0));
272     test(S::new(Some(2), 0), S::new(None, 0), S::new(Some(2), 2));
273     test(S::new(Some(2), 0), S::new(None, 0), S::new(Some(2), 0));
274 
275     // left.field1 == None
276     // right.field1 == None
277     test(S::new(None, 1), S::new(None, 1), S::new(None, 2));
278     test(S::new(None, 1), S::new(None, 1), S::new(None, 0));
279     test(S::new(None, 0), S::new(None, 0), S::new(None, 2));
280     test(S::new(None, 0), S::new(None, 0), S::new(None, 0));
281 }
282 
283 #[test]
test_strategy_usize_add()284 fn test_strategy_usize_add() {
285     #[derive(Debug, Merge, PartialEq)]
286     struct S {
287         #[merge(strategy = add)]
288         field1: usize,
289     }
290 
291     impl S {
292         pub fn new(field1: usize) -> S {
293             S { field1 }
294         }
295     }
296 
297     fn add(left: &mut usize, right: usize) {
298         *left = *left + right;
299     }
300 
301     test(S::new(0), S::new(0), S::new(0));
302     test(S::new(1), S::new(1), S::new(0));
303     test(S::new(1), S::new(0), S::new(1));
304     test(S::new(2), S::new(1), S::new(1));
305 }
306 
307 #[test]
test_strategy_vec_append()308 fn test_strategy_vec_append() {
309     #[derive(Debug, Merge, PartialEq)]
310     struct S {
311         #[merge(strategy = append)]
312         field1: Vec<usize>,
313     }
314 
315     impl S {
316         pub fn new(field1: Vec<usize>) -> S {
317             S { field1 }
318         }
319     }
320 
321     fn append(left: &mut Vec<usize>, mut right: Vec<usize>) {
322         left.append(&mut right);
323     }
324 
325     test(
326         S::new(vec![0, 1, 2, 3]),
327         S::new(vec![0, 1]),
328         S::new(vec![2, 3]),
329     );
330     test(
331         S::new(vec![0, 1, 2, 3]),
332         S::new(vec![0, 1, 2, 3]),
333         S::new(vec![]),
334     );
335     test(
336         S::new(vec![0, 1, 2, 3]),
337         S::new(vec![]),
338         S::new(vec![0, 1, 2, 3]),
339     );
340 }
341 
342 #[test]
test_unnamed_fields()343 fn test_unnamed_fields() {
344     #[derive(Debug, Merge, PartialEq)]
345     struct S(Option<usize>, Option<usize>);
346 
347     impl S {
348         pub fn new(field1: Option<usize>, field2: Option<usize>) -> S {
349             S(field1, field2)
350         }
351     }
352 
353     // left.field1 == Some(1)
354     // right.field1 == Some(2)
355     test(
356         S::new(Some(1), Some(1)),
357         S::new(Some(1), Some(1)),
358         S::new(Some(2), Some(2)),
359     );
360     test(
361         S::new(Some(1), Some(1)),
362         S::new(Some(1), Some(1)),
363         S::new(Some(2), None),
364     );
365     test(
366         S::new(Some(1), Some(2)),
367         S::new(Some(1), None),
368         S::new(Some(2), Some(2)),
369     );
370     test(
371         S::new(Some(1), None),
372         S::new(Some(1), None),
373         S::new(Some(2), None),
374     );
375 
376     // left.field1 == Some(1)
377     // right.field1 == None
378     test(
379         S::new(Some(1), Some(1)),
380         S::new(Some(1), Some(1)),
381         S::new(None, Some(2)),
382     );
383     test(
384         S::new(Some(1), Some(1)),
385         S::new(Some(1), Some(1)),
386         S::new(None, None),
387     );
388     test(
389         S::new(Some(1), Some(2)),
390         S::new(Some(1), None),
391         S::new(None, Some(2)),
392     );
393     test(
394         S::new(Some(1), None),
395         S::new(Some(1), None),
396         S::new(None, None),
397     );
398 
399     // left.field1 == None
400     // right.field1 == Some(2)
401     test(
402         S::new(Some(2), Some(1)),
403         S::new(None, Some(1)),
404         S::new(Some(2), Some(2)),
405     );
406     test(
407         S::new(Some(2), Some(1)),
408         S::new(None, Some(1)),
409         S::new(Some(2), None),
410     );
411     test(
412         S::new(Some(2), Some(2)),
413         S::new(None, None),
414         S::new(Some(2), Some(2)),
415     );
416     test(
417         S::new(Some(2), None),
418         S::new(None, None),
419         S::new(Some(2), None),
420     );
421 
422     // left.field1 == None
423     // right.field1 == None
424     test(
425         S::new(None, Some(1)),
426         S::new(None, Some(1)),
427         S::new(None, Some(2)),
428     );
429     test(
430         S::new(None, Some(1)),
431         S::new(None, Some(1)),
432         S::new(None, None),
433     );
434     test(
435         S::new(None, Some(2)),
436         S::new(None, None),
437         S::new(None, Some(2)),
438     );
439     test(S::new(None, None), S::new(None, None), S::new(None, None));
440 }
441 
442 #[test]
test_unnamed_fields_skip()443 fn test_unnamed_fields_skip() {
444     #[derive(Debug, Merge, PartialEq)]
445     struct S(Option<usize>, #[merge(skip)] Option<usize>);
446 
447     impl S {
448         pub fn new(field1: Option<usize>, field2: Option<usize>) -> S {
449             S(field1, field2)
450         }
451     }
452 
453     // left.field1 == Some(1)
454     // right.field1 == Some(2)
455     test(
456         S::new(Some(1), Some(1)),
457         S::new(Some(1), Some(1)),
458         S::new(Some(2), Some(2)),
459     );
460     test(
461         S::new(Some(1), Some(1)),
462         S::new(Some(1), Some(1)),
463         S::new(Some(2), None),
464     );
465     test(
466         S::new(Some(1), None),
467         S::new(Some(1), None),
468         S::new(Some(2), Some(2)),
469     );
470     test(
471         S::new(Some(1), None),
472         S::new(Some(1), None),
473         S::new(Some(2), None),
474     );
475 
476     // left.field1 == Some(1)
477     // right.field1 == None
478     test(
479         S::new(Some(1), Some(1)),
480         S::new(Some(1), Some(1)),
481         S::new(None, Some(2)),
482     );
483     test(
484         S::new(Some(1), Some(1)),
485         S::new(Some(1), Some(1)),
486         S::new(None, None),
487     );
488     test(
489         S::new(Some(1), None),
490         S::new(Some(1), None),
491         S::new(None, Some(2)),
492     );
493     test(
494         S::new(Some(1), None),
495         S::new(Some(1), None),
496         S::new(None, None),
497     );
498 
499     // left.field1 == None
500     // right.field1 == Some(2)
501     test(
502         S::new(Some(2), Some(1)),
503         S::new(None, Some(1)),
504         S::new(Some(2), Some(2)),
505     );
506     test(
507         S::new(Some(2), Some(1)),
508         S::new(None, Some(1)),
509         S::new(Some(2), None),
510     );
511     test(
512         S::new(Some(2), None),
513         S::new(None, None),
514         S::new(Some(2), Some(2)),
515     );
516     test(
517         S::new(Some(2), None),
518         S::new(None, None),
519         S::new(Some(2), None),
520     );
521 
522     // left.field1 == None
523     // right.field1 == None
524     test(
525         S::new(None, Some(1)),
526         S::new(None, Some(1)),
527         S::new(None, Some(2)),
528     );
529     test(
530         S::new(None, Some(1)),
531         S::new(None, Some(1)),
532         S::new(None, None),
533     );
534     test(
535         S::new(None, None),
536         S::new(None, None),
537         S::new(None, Some(2)),
538     );
539     test(S::new(None, None), S::new(None, None), S::new(None, None));
540 }
541