1package com.xtremelabs.robolectric.shadows;
2
3import android.content.Context;
4import android.view.View;
5import android.widget.TextView;
6import android.widget.Toast;
7import com.xtremelabs.robolectric.Robolectric;
8import com.xtremelabs.robolectric.internal.Implementation;
9import com.xtremelabs.robolectric.internal.Implements;
10import com.xtremelabs.robolectric.internal.RealObject;
11
12import java.util.List;
13
14import static com.xtremelabs.robolectric.Robolectric.shadowOf;
15
16/**
17 * Shadow of {@code Toast} that tracks {@code Toast} requests. Hear hear! (*clink*)
18 */
19@SuppressWarnings({"UnusedDeclaration"})
20@Implements(Toast.class)
21public class ShadowToast {
22    private String text;
23    private int duration;
24    private int gravity;
25    private View view;
26
27    @RealObject Toast toast;
28
29    @Implementation
30    public static Toast makeText(Context context, int resId, int duration) {
31        return makeText(context, context.getResources().getString(resId), duration);
32    }
33
34    @Implementation(i18nSafe=false)
35    public static Toast makeText(Context context, CharSequence text, int duration) {
36        Toast toast = new Toast(null);
37        toast.setDuration(duration);
38        shadowOf(toast).text = text.toString();
39        return toast;
40    }
41
42    @Implementation
43    public void show() {
44        Robolectric.getShadowApplication().getShownToasts().add(toast);
45    }
46
47    @Implementation
48    public void setView(View view) {
49        this.view = view;
50    }
51
52    @Implementation
53    public View getView() {
54        return view;
55    }
56
57    @Implementation
58    public void setGravity(int gravity, int xOffset, int yOffset) {
59        this.gravity = gravity;
60    }
61
62    @Implementation
63    public int getGravity() {
64        return gravity;
65    }
66
67    @Implementation
68    public void setDuration(int duration) {
69        this.duration = duration;
70    }
71
72    @Implementation
73    public int getDuration() {
74        return duration;
75    }
76
77    /**
78     * Non-Android accessor that discards the recorded {@code Toast}s
79     */
80    public static void reset() {
81        Robolectric.getShadowApplication().getShownToasts().clear();
82    }
83
84    /**
85     * Non-Android accessor that returns the number of {@code Toast} requests that have been made during this test run
86     * or since {@link #reset()} has been called.
87     *
88     * @return the number of {@code Toast} requests that have been made during this test run
89     *         or since {@link #reset()} has been called.
90     */
91    public static int shownToastCount() {
92        return Robolectric.getShadowApplication().getShownToasts().size();
93    }
94
95    /**
96     * Non-Android query method that returns whether or not a particular custom {@code Toast} has been shown.
97     *
98     * @param message the message to search for
99     * @param layoutResourceIdToCheckForMessage
100     *                the id of the resource that contains the toast messages
101     * @return whether the {@code Toast} was requested
102     */
103    public static boolean showedCustomToast(CharSequence message, int layoutResourceIdToCheckForMessage) {
104        for (Toast toast : Robolectric.getShadowApplication().getShownToasts()) {
105            String text = ((TextView) toast.getView().findViewById(layoutResourceIdToCheckForMessage)).getText().toString();
106            if (text.equals(message.toString())) {
107                return true;
108            }
109        }
110        return false;
111    }
112
113    /**
114     * query method that returns whether or not a particular {@code Toast} has been shown.
115     *
116     * @param message the message to search for
117     * @return whether the {@code Toast} was requested
118     */
119    public static boolean showedToast(CharSequence message) {
120        for (Toast toast : Robolectric.getShadowApplication().getShownToasts()) {
121            String text = shadowOf(toast).text;
122            if (text != null && text.equals(message.toString())) {
123                return true;
124            }
125        }
126        return false;
127    }
128
129    /**
130     * Non-Android accessor that returns the text of the most recently shown {@code Toast}
131     *
132     * @return the text of the most recently shown {@code Toast}
133     */
134    public static String getTextOfLatestToast() {
135        List<Toast> shownToasts = Robolectric.getShadowApplication().getShownToasts();
136        return (shownToasts.size() == 0) ? null : shadowOf(shownToasts.get(shownToasts.size() - 1)).text;
137    }
138
139    /**
140     * Non-Android accessor that returns the most recently shown {@code Toast}
141     *
142     * @return the most recently shown {@code Toast}
143     */
144    public static Toast getLatestToast() {
145        List<Toast> shownToasts = Robolectric.getShadowApplication().getShownToasts();
146        return (shownToasts.size() == 0) ? null : shownToasts.get(shownToasts.size() - 1);
147    }
148}
149