1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.test.escaping.suite

File ArchiveSuite.java

 
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
testParameterEscaping: got: <false>, expected: is <true>
 

Coverage histogram

../../../../../img/srcFileCovDistChart7.png
64% of files have more coverage

Code metrics

44
90
14
5
376
232
41
0.46
6.43
2.8
2.93

Classes

Class Line # Actions
ArchiveSuite 79 90 0% 41 43
0.709459570.9%
ArchiveSuite.ArchivePath 87 0 - 0 0
-1.0 -
ArchiveSuite.ArchivePathGetter 112 0 - 0 0
-1.0 -
ArchiveSuite.BeforeSuite 123 0 - 0 0
-1.0 -
ArchiveSuite.AfterSuite 134 0 - 0 0
-1.0 -
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package org.xwiki.test.escaping.suite;
21   
22    import java.io.IOException;
23    import java.io.InputStreamReader;
24    import java.io.Reader;
25    import java.lang.annotation.Documented;
26    import java.lang.annotation.ElementType;
27    import java.lang.annotation.Retention;
28    import java.lang.annotation.RetentionPolicy;
29    import java.lang.annotation.Target;
30    import java.lang.reflect.Method;
31    import java.lang.reflect.Modifier;
32    import java.util.ArrayList;
33    import java.util.Comparator;
34    import java.util.Enumeration;
35    import java.util.List;
36    import java.util.zip.ZipEntry;
37    import java.util.zip.ZipFile;
38   
39    import org.junit.After;
40    import org.junit.Before;
41    import org.junit.Test;
42    import org.junit.internal.runners.statements.RunAfters;
43    import org.junit.internal.runners.statements.RunBefores;
44    import org.junit.runner.Description;
45    import org.junit.runner.Runner;
46    import org.junit.runner.manipulation.Sorter;
47    import org.junit.runner.notification.RunNotifier;
48    import org.junit.runners.ParentRunner;
49    import org.junit.runners.model.FrameworkMethod;
50    import org.junit.runners.model.InitializationError;
51    import org.junit.runners.model.RunnerBuilder;
52    import org.junit.runners.model.Statement;
53    import org.junit.runners.model.TestClass;
54   
55   
56    /**
57    * JUnit4 test suite that generates tests based on files found in a Zip (i.e. also war/xar/jar) archive.
58    * <p>
59    * The path to the archive must be specified using &#064;{@link ArchivePath} or
60    * &#064;{@link ArchivePathGetter}.</p>
61    * <p>
62    * This test suite requires the test class to implement {@link FileTest}. It defines an initialization
63    * method to set up the test case for each file based on the file content.</p>
64    * <p>
65    * The test methods should be annotated with &#064;{@link Test} as usual. All custom JUnit4 annotations
66    * like &#064;{@link Before} and &#064;{@link After} and &#064;{@link Test} attributes are supported.</p>
67    * <p>
68    * The lifetime of each {@link FileTest} is as follows:
69    * <ul>
70    * <li>An instance of the file test class is created.</li>
71    * <li>The method {@link #initialize(String, Reader)} is called.</li>
72    * <li>The stream associated with the {@link Reader} that was used to initialize the test is closed.</li>
73    * <li>All methods marked with the &#064;{@link Test} annotation are called.</li>
74    * </ul></p>
75    *
76    * @version $Id: 97e26b705a18cc81dd8412ecf4928083efc89bb9 $
77    * @since 2.5M1
78    */
 
79    Test failure here public class ArchiveSuite extends ParentRunner<Runner>
80    {
81    /**
82    * Path to the archive. Is overridden by &#064;{@link ArchivePathGetter}.
83    */
84    @Target(ElementType.TYPE)
85    @Retention(RetentionPolicy.RUNTIME)
86    @Documented
 
87    public @interface ArchivePath
88    {
89    /**
90    * Path to the archive.
91    */
92    String value();
93    }
94   
95    /**
96    * Marks the method that should be used to retrieve the path to the archive to use. Overrides
97    * &#064;{@link ArchivePath}.
98    * <p>
99    * The getter method should be a public static method returning String and not taking any arguments.
100    * Only one method should have this annotation. Example:
101    * <pre>
102    * &#064;ArchivePathMethod
103    * public static String getPath() {
104    * ...
105    * }
106    * </pre>
107    * </p>
108    */
109    @Target(ElementType.METHOD)
110    @Retention(RetentionPolicy.RUNTIME)
111    @Documented
 
112    public @interface ArchivePathGetter
113    {
114    // no attributes
115    }
116   
117    /**
118    * Marks a method that should be called before the archive is read.
119    */
120    @Target(ElementType.METHOD)
121    @Retention(RetentionPolicy.RUNTIME)
122    @Documented
 
123    public @interface BeforeSuite
124    {
125    // no attributes
126    }
127   
128    /**
129    * Marks a method that should be called after all tests finished.
130    */
131    @Target(ElementType.METHOD)
132    @Retention(RetentionPolicy.RUNTIME)
133    @Documented
 
134    public @interface AfterSuite
135    {
136    // no attributes
137    }
138   
139    /** List of test runners build, one for each matching file found in the archive. */
140    private final List<Runner> runners;
141   
142    /** Path to the archive. */
143    private final String archivePath;
144   
145   
146    /**
147    * Create new ArchiveSuite.
148    *
149    * @param klass the annotated test class
150    * @param builder default junit builder
151    * @throws InitializationError on errors
152    */
 
153  2 toggle public ArchiveSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError
154    {
155  2 super(klass);
156  2 validateTestClass();
157  2 this.archivePath = getArchiveFromAnnotation();
158  2 this.runners = createRunners(this.archivePath);
159    }
160   
 
161  2 toggle @Override
162    protected List<Runner> getChildren()
163    {
164  2 return this.runners;
165    }
166   
 
167  2844 toggle @Override
168    protected Description describeChild(Runner child)
169    {
170  2844 return child.getDescription();
171    }
172   
 
173  948 toggle @Override
174    protected void runChild(Runner child, RunNotifier notifier)
175    {
176  948 Test failure here child.run(notifier);
177    }
178   
 
179  6 toggle @Override
180    protected String getName()
181    {
182  6 String fileName = this.archivePath;
183  6 int idx = this.archivePath.lastIndexOf("/");
184  6 if (idx >= 0 && idx < this.archivePath.length() - 2) {
185  6 fileName = this.archivePath.substring(idx + 1);
186    }
187  6 return getClass().getSimpleName() + "(" + fileName + ")\n";
188    }
189   
 
190  0 toggle @Override
191    public void sort(Sorter sorter)
192    {
193  0 super.sort(new Sorter(new Comparator<Description>() {
 
194  0 toggle @Override
195    public int compare(Description o1, Description o2) {
196  0 return o1.getDisplayName().compareTo(o2.getDisplayName());
197    }
198    }));
199    }
200   
201    /**
202    * Read the archive and build a list of runners for its content.
203    *
204    * @param archivePath path to the archive to use
205    * @return a list of test runners
206    * @throws InitializationError on errors
207    */
 
208  2 toggle private List<Runner> createRunners(String archivePath) throws InitializationError
209    {
210  2 List<Runner> list = new ArrayList<Runner>();
211  2 try {
212  2 final ZipFile archive = new ZipFile(archivePath);
213  2 Enumeration< ? extends ZipEntry> entries = archive.entries();
214  3804 while (entries.hasMoreElements()) {
215  3802 ZipEntry entry = entries.nextElement();
216  3802 if (entry.isDirectory()) {
217  95 continue;
218    }
219  3707 Reader reader = new InputStreamReader(archive.getInputStream(entry));
220  3707 addTest(list, entry.getName(), reader);
221    }
222  2 archive.close();
223    } catch (IOException exception) {
224  0 throw new InitializationError(exception);
225    }
226  2 return list;
227    }
228   
229    /**
230    * Create and initialize an instance of the test class for given file.
231    *
232    * @param name file name to use
233    * @param reader the reader associated with the file data
234    * @throws InitializationError on errors
235    */
 
236  3707 toggle private void addTest(List<Runner> list, String name, Reader reader) throws InitializationError
237    {
238  3707 try {
239  3707 Object result = getTestClass().getOnlyConstructor().newInstance();
240  3707 if (result instanceof FileTest) {
241  3707 FileTest test = (FileTest) result;
242  3707 if (test.initialize(name, reader)) {
243  948 list.add(new FileTestRunner(test));
244    }
245  3707 return;
246    }
247    } catch (Exception exception) {
248    // should not happen, since the test class was validated before
249  0 throw new InitializationError(exception);
250    }
251  0 throw new InitializationError("Failed to initialize the test for \"" + name + "\"");
252    }
253   
254    /**
255    * Validate that the test class implements {@link FileTest} and has the expected default constructor.
256    *
257    * @throws InitializationError
258    */
 
259  2 toggle private void validateTestClass() throws InitializationError
260    {
261  2 TestClass test = getTestClass();
262  2 List<Throwable> errors= new ArrayList<Throwable>();
263  2 if (!FileTest.class.isAssignableFrom(test.getJavaClass())) {
264  0 errors.add(new Exception("The test class " + test.getName() + " should implement FileTest"));
265    }
266  2 if (test.getOnlyConstructor().getParameterTypes().length != 0) {
267  0 errors.add(new Exception("Constructor of " + test.getName() + " should have no parameters"));
268    }
269  2 validatePublicVoidNoArgMethods(Test.class, false, errors);
270  2 if (errors.size() != 0) {
271  0 throw new InitializationError(errors);
272    }
273    }
274   
275    /**
276    * Retrieve the path to the archive form annotations. Throws an exception if no annotations can
277    * be found, when the annotation is used incorrectly or the path is invalid.
278    *
279    * @return path to the archive to use
280    * @throws InitializationError when an error occurs
281    */
 
282  2 toggle private String getArchiveFromAnnotation() throws InitializationError
283    {
284  2 String path = null;
285   
286    // try class annotation first
287  2 ArchivePath classAnnotation = getTestClass().getJavaClass().getAnnotation(ArchivePath.class);
288  2 if (classAnnotation != null) {
289  0 path = classAnnotation.value();
290    }
291   
292    // override by getter method, if present
293  2 List<FrameworkMethod> getters = getTestClass().getAnnotatedMethods(ArchivePathGetter.class);
294  2 if (getters.size() > 1) {
295  0 throw new InitializationError("Only one method should be annotated with @ArchivePathGetter. "
296    + "The test case \"" + getTestClass().getName() + "\" has " + getters.size() + " annotated methods.");
297    }
298  2 if (classAnnotation == null && getters.size() == 0) {
299  0 throw new InitializationError("No archive path annotations found. The test case \""
300    + getTestClass().getName() + "\" should be annotated with @ArchivePath or @ArchivePathGetter");
301    }
302  2 if (getters.size() == 1) {
303  2 path = invokeGetter(getters.get(0).getMethod());
304    }
305   
306    // validate the path
307  2 if (path == null) {
308  0 throw new InitializationError("Archive path is null.");
309    }
310  2 return path;
311    }
312   
 
313  2 toggle @Override
314    protected Statement withBeforeClasses(Statement statement)
315    {
316  2 Statement result = super.withBeforeClasses(statement);
317  2 List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(BeforeSuite.class);
318  2 if (methods.isEmpty()) {
319  0 return result;
320    }
321  2 return new RunBefores(result, methods, null);
322    }
323   
 
324  2 toggle @Override
325    protected Statement withAfterClasses(Statement statement)
326    {
327  2 Statement result = super.withAfterClasses(statement);
328  2 List<FrameworkMethod> methods = getTestClass().getAnnotatedMethods(AfterSuite.class);
329  2 if (methods.isEmpty()) {
330  0 return result;
331    }
332  2 return new RunAfters(result, methods, null);
333    }
334   
335    /**
336    * Check that the archive getter method has the expected type and invoke it.
337    *
338    * @param getter the getter method to use
339    * @return the resulting archive path
340    * @throws InitializationError on errors
341    */
 
342  2 toggle private String invokeGetter(Method getter) throws InitializationError
343    {
344  2 List<Throwable> errors = new ArrayList<Throwable>();
345  2 Class<?> getterClass = getter.getDeclaringClass();
346  2 String getterName = getterClass.getName() + "." + getter.getName();
347  2 if (!Modifier.isPublic(getterClass.getModifiers())) {
348  0 errors.add(new Exception("The class " + getterClass.getName() + " should be public."));
349    }
350  2 if (!Modifier.isPublic(getter.getModifiers())) {
351  0 errors.add(new Exception("The method " + getterName + " should be public."));
352    }
353  2 if (!Modifier.isStatic(getter.getModifiers())) {
354  0 errors.add(new Exception("The method " + getterName + " should be static."));
355    }
356  2 if (!getter.getReturnType().equals(String.class)) {
357  0 errors.add(new Exception("The method " + getterName + " should return String."));
358    }
359  2 if (getter.getParameterTypes().length != 0) {
360  0 errors.add(new Exception("The method " + getterName + " should have no parameters."));
361    }
362  2 if (errors.size() != 0) {
363  0 throw new InitializationError(errors);
364    }
365  2 try {
366  2 Object result = getter.invoke(null);
367  2 if (result instanceof String) {
368  2 return (String) result;
369    }
370    } catch (Exception exception) {
371  0 throw new InitializationError(exception);
372    }
373  0 return null;
374    }
375    }
376