88732782cb3466bfc3fb3131077b8ca8df345bc4
[Sone.git] / src / test / java / net / pterodactylus / sone / Matchers.java
1 /*
2  * Sone - Matchers.java - Copyright © 2013 David Roden
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 package net.pterodactylus.sone;
19
20 import static java.util.Arrays.asList;
21 import static java.util.regex.Pattern.compile;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.Collection;
26 import java.util.Iterator;
27 import java.util.List;
28
29 import com.google.common.base.Objects;
30 import com.google.common.collect.Lists;
31 import org.hamcrest.Description;
32 import org.hamcrest.Matcher;
33 import org.hamcrest.TypeSafeMatcher;
34
35 /**
36  * Matchers used throughout the tests.
37  *
38  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
39  */
40 public class Matchers {
41
42         public static Matcher<String> matches(final String regex) {
43                 return new TypeSafeMatcher<String>() {
44                         @Override
45                         protected boolean matchesSafely(String item) {
46                                 return compile(regex).matcher(item).find();
47                         }
48
49                         @Override
50                         public void describeTo(Description description) {
51                                 description.appendText("matches: ").appendValue(regex);
52                         }
53                 };
54         }
55
56         public static <T> Matcher<Iterator<T>> contains(T... items) {
57                 return contains(asList(items));
58         }
59
60         public static <T> Matcher<Iterator<T>> contains(final Collection<T> items) {
61                 return new TypeSafeMatcher<Iterator<T>>() {
62                         @Override
63                         protected boolean matchesSafely(Iterator<T> iterator) {
64                                 for (T item : items) {
65                                         if (!iterator.hasNext()) {
66                                                 return false;
67                                         }
68                                         T nextItem = iterator.next();
69                                         if (!Objects.equal(item, nextItem)) {
70                                                 return false;
71                                         }
72                                 }
73                                 if (iterator.hasNext()) {
74                                         return false;
75                                 }
76                                 return true;
77                         }
78
79                         @Override
80                         public void describeTo(Description description) {
81                                 description.appendText("contains ").appendValue(items);
82                         }
83                 };
84         }
85
86         public static <T> Matcher<Iterator<T>> containsInAnyOrder(T... items) {
87                 return containsInAnyOrder(asList(items));
88         }
89
90         public static <T> Matcher<Iterator<T>> containsInAnyOrder(final Collection<T> items) {
91                 return new TypeSafeMatcher<Iterator<T>>() {
92                         private final List<T> remainingItems = Lists.newArrayList(items);
93                         @Override
94                         protected boolean matchesSafely(Iterator<T> iterator) {
95                                 while (iterator.hasNext()) {
96                                         T item = iterator.next();
97                                         if (remainingItems.isEmpty()) {
98                                                 return false;
99                                         }
100                                         if (!remainingItems.remove(item)) {
101                                                 return false;
102                                         }
103                                 }
104                                 if (!remainingItems.isEmpty()) {
105                                         return false;
106                                 }
107                                 return true;
108                         }
109
110                         @Override
111                         public void describeTo(Description description) {
112                                 description.appendText("contains ").appendValue(items);
113                         }
114                 };
115         }
116
117         public static Matcher<InputStream> delivers(final byte[] data) {
118                 return new TypeSafeMatcher<InputStream>() {
119                         byte[] readData = new byte[data.length];
120
121                         @Override
122                         protected boolean matchesSafely(InputStream inputStream) {
123                                 int offset = 0;
124                                 try {
125                                         while (true) {
126                                                 int r = inputStream.read();
127                                                 if (r == -1) {
128                                                         return offset == data.length;
129                                                 }
130                                                 if (offset == data.length) {
131                                                         return false;
132                                                 }
133                                                 if (data[offset] != (readData[offset] = (byte) r)) {
134                                                         return false;
135                                                 }
136                                                 offset++;
137                                         }
138                                 } catch (IOException ioe1) {
139                                         return false;
140                                 }
141                         }
142
143                         @Override
144                         public void describeTo(Description description) {
145                                 description.appendValue(data);
146                         }
147
148                         @Override
149                         protected void describeMismatchSafely(InputStream item, Description mismatchDescription) {
150                                 mismatchDescription.appendValue(readData);
151                         }
152                 };
153         }
154
155 }