Move field set matcher to Matchers.
[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 com.google.common.base.Objects.equal;
21 import static com.google.common.collect.Iterators.size;
22 import static java.util.Arrays.asList;
23 import static java.util.regex.Pattern.compile;
24
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.Collection;
28 import java.util.Iterator;
29 import java.util.List;
30
31 import freenet.support.SimpleFieldSet;
32
33 import com.google.common.base.Objects;
34 import com.google.common.collect.Lists;
35 import org.hamcrest.Description;
36 import org.hamcrest.Matcher;
37 import org.hamcrest.TypeSafeMatcher;
38
39 /**
40  * Matchers used throughout the tests.
41  *
42  * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
43  */
44 public class Matchers {
45
46         public static Matcher<String> matches(final String regex) {
47                 return new TypeSafeMatcher<String>() {
48                         @Override
49                         protected boolean matchesSafely(String item) {
50                                 return compile(regex).matcher(item).find();
51                         }
52
53                         @Override
54                         public void describeTo(Description description) {
55                                 description.appendText("matches: ").appendValue(regex);
56                         }
57                 };
58         }
59
60         public static <T> Matcher<Iterator<T>> contains(T... items) {
61                 return contains(asList(items));
62         }
63
64         public static <T> Matcher<Iterator<T>> contains(final Collection<T> items) {
65                 return new TypeSafeMatcher<Iterator<T>>() {
66                         @Override
67                         protected boolean matchesSafely(Iterator<T> iterator) {
68                                 for (T item : items) {
69                                         if (!iterator.hasNext()) {
70                                                 return false;
71                                         }
72                                         T nextItem = iterator.next();
73                                         if (!Objects.equal(item, nextItem)) {
74                                                 return false;
75                                         }
76                                 }
77                                 if (iterator.hasNext()) {
78                                         return false;
79                                 }
80                                 return true;
81                         }
82
83                         @Override
84                         public void describeTo(Description description) {
85                                 description.appendText("contains ").appendValue(items);
86                         }
87                 };
88         }
89
90         public static <T> Matcher<Iterator<T>> containsInAnyOrder(T... items) {
91                 return containsInAnyOrder(asList(items));
92         }
93
94         public static <T> Matcher<Iterator<T>> containsInAnyOrder(final Collection<T> items) {
95                 return new TypeSafeMatcher<Iterator<T>>() {
96                         private final List<T> remainingItems = Lists.newArrayList(items);
97                         @Override
98                         protected boolean matchesSafely(Iterator<T> iterator) {
99                                 while (iterator.hasNext()) {
100                                         T item = iterator.next();
101                                         if (remainingItems.isEmpty()) {
102                                                 return false;
103                                         }
104                                         if (!remainingItems.remove(item)) {
105                                                 return false;
106                                         }
107                                 }
108                                 if (!remainingItems.isEmpty()) {
109                                         return false;
110                                 }
111                                 return true;
112                         }
113
114                         @Override
115                         public void describeTo(Description description) {
116                                 description.appendText("contains ").appendValue(items);
117                         }
118                 };
119         }
120
121         public static Matcher<InputStream> delivers(final byte[] data) {
122                 return new TypeSafeMatcher<InputStream>() {
123                         byte[] readData = new byte[data.length];
124
125                         @Override
126                         protected boolean matchesSafely(InputStream inputStream) {
127                                 int offset = 0;
128                                 try {
129                                         while (true) {
130                                                 int r = inputStream.read();
131                                                 if (r == -1) {
132                                                         return offset == data.length;
133                                                 }
134                                                 if (offset == data.length) {
135                                                         return false;
136                                                 }
137                                                 if (data[offset] != (readData[offset] = (byte) r)) {
138                                                         return false;
139                                                 }
140                                                 offset++;
141                                         }
142                                 } catch (IOException ioe1) {
143                                         return false;
144                                 }
145                         }
146
147                         @Override
148                         public void describeTo(Description description) {
149                                 description.appendValue(data);
150                         }
151
152                         @Override
153                         protected void describeMismatchSafely(InputStream item, Description mismatchDescription) {
154                                 mismatchDescription.appendValue(readData);
155                         }
156                 };
157         }
158
159         public static Matcher<SimpleFieldSet> matches(final SimpleFieldSet fieldSetToMatch) {
160                 return new TypeSafeMatcher<SimpleFieldSet>() {
161                         @Override
162                         protected boolean matchesSafely(SimpleFieldSet fieldSet) {
163                                 if (size(fieldSet.keyIterator()) != size(fieldSetToMatch.keyIterator())) {
164                                         return false;
165                                 }
166                                 for (Iterator<String> keys = fieldSetToMatch.keyIterator(); keys.hasNext(); ) {
167                                         String key = keys.next();
168                                         if (!equal(fieldSet.get(key), fieldSetToMatch.get(key))) {
169                                                 return false;
170                                         }
171                                 }
172                                 return true;
173                         }
174
175                         @Override
176                         public void describeTo(Description description) {
177                                 description.appendText("is ").appendValue(fieldSetToMatch);
178                         }
179                 };
180         }
181
182 }