1package org.robolectric.shadows;
2
3import static org.robolectric.Shadows.shadowOf;
4
5import android.content.Context;
6import android.view.View;
7import android.widget.TextView;
8import android.widget.Toast;
9import java.util.List;
10import org.robolectric.RuntimeEnvironment;
11import org.robolectric.annotation.Implementation;
12import org.robolectric.annotation.Implements;
13import org.robolectric.annotation.RealObject;
14
15@SuppressWarnings({"UnusedDeclaration"})
16@Implements(Toast.class)
17public class ShadowToast {
18  private String text;
19  private int duration;
20  private int gravity;
21  private int xOffset;
22  private int yOffset;
23  private View view;
24
25  @RealObject Toast toast;
26
27  @Implementation
28  public void __constructor__(Context context) {}
29
30  @Implementation
31  public static Toast makeText(Context context, int resId, int duration) {
32    return makeText(context, context.getResources().getString(resId), duration);
33  }
34
35  @Implementation
36  public static Toast makeText(Context context, CharSequence text, int duration) {
37    Toast toast = new Toast(context);
38    toast.setDuration(duration);
39    shadowOf(toast).text = text.toString();
40    return toast;
41  }
42
43  @Implementation
44  public void show() {
45    shadowOf(RuntimeEnvironment.application).getShownToasts().add(toast);
46  }
47
48  @Implementation
49  public void setText(int resId) {
50    this.text = RuntimeEnvironment.application.getString(resId);
51  }
52
53  @Implementation
54  public void setText(CharSequence text) {
55    this.text = text.toString();
56  }
57
58  @Implementation
59  public void setView(View view) {
60    this.view = view;
61  }
62
63  @Implementation
64  public View getView() {
65    return view;
66  }
67
68  @Implementation
69  public void setGravity(int gravity, int xOffset, int yOffset) {
70    this.gravity = gravity;
71    this.xOffset = xOffset;
72    this.yOffset = yOffset;
73  }
74
75  @Implementation
76  public int getGravity() {
77    return gravity;
78  }
79
80  @Implementation
81  public int getXOffset() {
82    return xOffset;
83  }
84
85  @Implementation
86  public int getYOffset() {
87    return yOffset;
88  }
89
90  @Implementation
91  public void setDuration(int duration) {
92    this.duration = duration;
93  }
94
95  @Implementation
96  public int getDuration() {
97    return duration;
98  }
99
100  @Implementation
101  public void cancel() {
102  }
103
104  /**
105   * Discards the recorded {@code Toast}s. Shown toasts are automatically cleared between
106   * tests. This method allows the user to discard recorded toasts during the test in order to make assertions clearer
107   * e.g:
108   *
109   * <pre>
110   *
111   *   // Show a single toast
112   *   myClass.showToast();
113   *
114   *   assertThat(ShadowToast.shownToastCount()).isEqualTo(1);
115   *   ShadowToast.reset();
116   *
117   *    // Show another toast
118   *   myClass.showToast();
119   *
120   *   assertThat(ShadowToast.shownToastCount()).isEqualTo(1);
121   *
122   * </pre>
123   */
124  public static void reset() {
125    shadowOf(RuntimeEnvironment.application).getShownToasts().clear();
126  }
127
128  /**
129   * Returns the number of {@code Toast} requests that have been made during this test run
130   * or since {@link #reset()} has been called.
131   *
132   * @return the number of {@code Toast} requests that have been made during this test run
133   *         or since {@link #reset()} has been called.
134   */
135  public static int shownToastCount() {
136    return shadowOf(RuntimeEnvironment.application).getShownToasts().size();
137  }
138
139  /**
140   * Returns whether or not a particular custom {@code Toast} has been shown.
141   *
142   * @param message the message to search for
143   * @param layoutResourceIdToCheckForMessage
144   *                the id of the resource that contains the toast messages
145   * @return whether the {@code Toast} was requested
146   */
147  public static boolean showedCustomToast(CharSequence message, int layoutResourceIdToCheckForMessage) {
148    for (Toast toast : shadowOf(RuntimeEnvironment.application).getShownToasts()) {
149      String text = ((TextView) toast.getView().findViewById(layoutResourceIdToCheckForMessage)).getText().toString();
150      if (text.equals(message.toString())) {
151        return true;
152      }
153    }
154    return false;
155  }
156
157  /**
158   * query method that returns whether or not a particular {@code Toast} has been shown.
159   *
160   * @param message the message to search for
161   * @return whether the {@code Toast} was requested
162   */
163  public static boolean showedToast(CharSequence message) {
164    for (Toast toast : shadowOf(RuntimeEnvironment.application).getShownToasts()) {
165      String text = shadowOf(toast).text;
166      if (text != null && text.equals(message.toString())) {
167        return true;
168      }
169    }
170    return false;
171  }
172
173  /**
174   * Returns the text of the most recently shown {@code Toast}.
175   *
176   * @return the text of the most recently shown {@code Toast}
177   */
178  public static String getTextOfLatestToast() {
179    List<Toast> shownToasts = shadowOf(RuntimeEnvironment.application).getShownToasts();
180    return (shownToasts.size() == 0) ? null : shadowOf(shownToasts.get(shownToasts.size() - 1)).text;
181  }
182
183  /**
184   * Returns the most recently shown {@code Toast}.
185   *
186   * @return the most recently shown {@code Toast}
187   */
188  public static Toast getLatestToast() {
189    List<Toast> shownToasts = shadowOf(RuntimeEnvironment.application).getShownToasts();
190    return (shownToasts.size() == 0) ? null : shownToasts.get(shownToasts.size() - 1);
191  }
192}
193