1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.api.util;
20
21 import java.util.ArrayList;
22 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Iterator;
25 import java.util.List;
26 import java.util.Set;
27
28 import org.apache.maven.surefire.api.testset.TestSetFailedException;
29
30 import static java.lang.Math.max;
31
32
33
34
35
36
37
38 public class TestsToRun implements Iterable<Class<?>> {
39 private final List<Class<?>> locatedClasses;
40
41 private volatile boolean finished;
42
43 private int iteratedCount;
44
45
46
47
48
49
50 public TestsToRun(Set<Class<?>> locatedClasses) {
51 this.locatedClasses = new ArrayList<>(locatedClasses);
52 }
53
54 public static TestsToRun fromClass(Class<?> clazz) throws TestSetFailedException {
55 return new TestsToRun(Collections.<Class<?>>singleton(clazz));
56 }
57
58
59
60
61 public Iterator<Class<?>> iterated() {
62 return newWeakIterator();
63 }
64
65
66
67
68
69
70 @Override
71 public Iterator<Class<?>> iterator() {
72 return new ClassesIterator();
73 }
74
75 private final class ClassesIterator extends CloseableIterator<Class<?>> {
76 private final Iterator<Class<?>> it = TestsToRun.this.locatedClasses.iterator();
77
78 private int iteratedCount;
79
80 @Override
81 protected boolean isClosed() {
82 return TestsToRun.this.isFinished();
83 }
84
85 @Override
86 protected boolean doHasNext() {
87 return it.hasNext();
88 }
89
90 @Override
91 protected Class<?> doNext() {
92 Class<?> nextTest = it.next();
93 TestsToRun.this.iteratedCount = max(++iteratedCount, TestsToRun.this.iteratedCount);
94 return nextTest;
95 }
96
97 @Override
98 protected void doRemove() {}
99
100 @Override
101 public void remove() {
102 throw new UnsupportedOperationException("unsupported remove");
103 }
104 }
105
106 public final void markTestSetFinished() {
107 finished = true;
108 }
109
110 public final boolean isFinished() {
111 return finished;
112 }
113
114 @Override
115 public String toString() {
116 StringBuilder sb = new StringBuilder("TestsToRun: [");
117 for (Class<?> clazz : this) {
118 sb.append(' ').append(clazz.getName());
119 }
120
121 sb.append(']');
122 return sb.toString();
123 }
124
125 public boolean containsAtLeast(int atLeast) {
126 return containsAtLeast(iterator(), atLeast);
127 }
128
129 private boolean containsAtLeast(Iterator<Class<?>> it, int atLeast) {
130 for (int i = 0; i < atLeast; i++) {
131 if (!it.hasNext()) {
132 return false;
133 }
134
135 it.next();
136 }
137
138 return true;
139 }
140
141 public boolean containsExactly(int items) {
142 Iterator<Class<?>> it = iterator();
143 return containsAtLeast(it, items) && !it.hasNext();
144 }
145
146
147
148
149
150 public boolean allowEagerReading() {
151 return true;
152 }
153
154 public Class<?>[] getLocatedClasses() {
155 if (!allowEagerReading()) {
156 throw new IllegalStateException("Cannot eagerly read");
157 }
158 Collection<Class<?>> result = new ArrayList<>();
159 for (Class<?> clazz : this) {
160 result.add(clazz);
161 }
162 return result.toArray(new Class<?>[result.size()]);
163 }
164
165
166
167
168
169
170
171 public Class<?> getClassByName(String className) {
172 for (Class<?> clazz : this) {
173 if (clazz.getName().equals(className)) {
174 return clazz;
175 }
176 }
177 return null;
178 }
179
180
181
182
183
184 private Iterator<Class<?>> newWeakIterator() {
185 final Iterator<Class<?>> it = locatedClasses.subList(0, iteratedCount).iterator();
186 return new CloseableIterator<Class<?>>() {
187 @Override
188 protected boolean isClosed() {
189 return TestsToRun.this.isFinished();
190 }
191
192 @Override
193 protected boolean doHasNext() {
194 return it.hasNext();
195 }
196
197 @Override
198 protected Class<?> doNext() {
199 return it.next();
200 }
201
202 @Override
203 protected void doRemove() {}
204
205 @Override
206 public void remove() {
207 throw new UnsupportedOperationException("unsupported remove");
208 }
209 };
210 }
211 }