1/*
2 * Copyright 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package androidx.fragment.app;
17
18import android.os.SystemClock;
19
20import org.mockito.exceptions.base.MockitoAssertionError;
21import org.mockito.internal.verification.VerificationModeFactory;
22import org.mockito.internal.verification.api.VerificationData;
23import org.mockito.invocation.Invocation;
24import org.mockito.verification.VerificationMode;
25
26import java.util.List;
27
28public class CtsMockitoUtils {
29    private CtsMockitoUtils() {}
30
31    public static VerificationMode within(long timeout) {
32        return new Within(timeout);
33    }
34
35    public static class Within implements VerificationMode {
36        private static final long TIME_SLICE = 50;
37        private final long mTimeout;
38
39        public Within(long timeout) {
40            mTimeout = timeout;
41        }
42
43        @Override
44        public void verify(VerificationData data) {
45            long timeout = mTimeout;
46            MockitoAssertionError errorToRethrow = null;
47            // Loop in the same way we do in PollingCheck, sleeping and then testing for the target
48            // invocation
49            while (timeout > 0) {
50                SystemClock.sleep(TIME_SLICE);
51
52                try {
53                    final List<Invocation> actualInvocations = data.getAllInvocations();
54                    // Iterate over all invocations so far to see if we have a match
55                    for (Invocation invocation : actualInvocations) {
56                        if (data.getWanted().matches(invocation)) {
57                            // Found our match within our timeout. Mark all invocations as verified
58                            markAllInvocationsAsVerified(data);
59                            // and return
60                            return;
61                        }
62                    }
63                } catch (MockitoAssertionError assertionError) {
64                    errorToRethrow = assertionError;
65                }
66
67                timeout -= TIME_SLICE;
68            }
69
70            if (errorToRethrow != null) {
71                throw errorToRethrow;
72            }
73
74            throw new MockitoAssertionError("Timed out while waiting " + mTimeout + "ms for "
75                    + data.getWanted().toString());
76        }
77
78        @Override
79        public VerificationMode description(String description) {
80            return VerificationModeFactory.description(this, description);
81        }
82
83        private void markAllInvocationsAsVerified(VerificationData data) {
84            for (Invocation invocation : data.getAllInvocations()) {
85                invocation.markVerified();
86                data.getWanted().captureArgumentsFrom(invocation);
87            }
88        }
89    }
90
91}
92