1/*
2 * Copyright (c) 2007 Mockito contributors
3 * This program is made available under the terms of the MIT License.
4 */
5
6package org.mockito;
7
8import org.hamcrest.BaseMatcher;
9import org.hamcrest.Description;
10import org.hamcrest.Matcher;
11import org.mockito.internal.util.Decamelizer;
12
13/**
14 * Allows creating customized argument matchers.
15 * <p>
16 * ArgumentMatcher is an hamcrest {@link Matcher} with predefined describeTo() method.
17 * In case of failure, ArgumentMatcher generates description based on <b>decamelized class name</b> - to promote meaningful class names.
18 * For example <b>StringWithStrongLanguage</b> matcher will generate 'String with strong language' description.
19 * You can always override describeTo() method and provide detailed description.
20 * <p>
21 * Use {@link Matchers#argThat} method and pass an instance of hamcrest {@link Matcher}, e.g:
22 *
23 * <pre class="code"><code class="java">
24 * class IsListOfTwoElements extends ArgumentMatcher&lt;List&gt; {
25 *     public boolean matches(Object list) {
26 *         return ((List) list).size() == 2;
27 *     }
28 * }
29 *
30 * List mock = mock(List.class);
31 *
32 * when(mock.addAll(argThat(new IsListOfTwoElements()))).thenReturn(true);
33 *
34 * mock.addAll(Arrays.asList(&quot;one&quot;, &quot;two&quot;));
35 *
36 * verify(mock).addAll(argThat(new IsListOfTwoElements()));
37 * </code></pre>
38 *
39 * To keep it readable you may want to extract method, e.g:
40 *
41 * <pre class="code"><code class="java">
42 *   verify(mock).addAll(<b>argThat(new IsListOfTwoElements())</b>);
43 *   //becomes
44 *   verify(mock).addAll(<b>listOfTwoElements()</b>);
45 * </code></pre>
46 *
47 * <b>Warning:</b> Be reasonable with using complicated argument matching, especially custom argument matchers, as it can make the test less readable.
48 * Sometimes it's better to implement equals() for arguments that are passed to mocks
49 * (Mockito naturally uses equals() for argument matching).
50 * This can make the test cleaner.
51 * <p>
52 * Also, <b>sometimes {@link ArgumentCaptor} may be a better fit</b> than custom matcher.
53 * For example, if custom argument matcher is not likely to be reused
54 * or you just need it to assert on argument values to complete verification of behavior.
55 * <p>
56 * Read more about other matchers in javadoc for {@link Matchers} class
57 *
58 * @param <T> type of argument
59 */
60public abstract class ArgumentMatcher<T> extends BaseMatcher<T> {
61
62    private static final long serialVersionUID = -2145234737829370369L;
63
64    /**
65     * Returns whether this matcher accepts the given argument.
66     * <p>
67     * The method should <b>never</b> assert if the argument doesn't match. It
68     * should only return false.
69     *
70     * @param argument
71     *            the argument
72     * @return whether this matcher accepts the given argument.
73     */
74    public abstract boolean matches(Object argument);
75
76    /**
77     * By default this method decamelizes matchers name to promote meaningful names for matchers.
78     * <p>
79     * For example <b>StringWithStrongLanguage</b> matcher will generate 'String with strong language' description in case of failure.
80     * <p>
81     * You might want to override this method to
82     * provide more specific description of the matcher (useful when
83     * verification failures are reported).
84     *
85     * @param description the description to which the matcher description is
86     * appended.
87     */
88    public void describeTo(Description description) {
89        String className = getClass().getSimpleName();
90        description.appendText(Decamelizer.decamelizeMatcher(className));
91    }
92}