FunctionalJavaFXRunner.java
001 /*
002  * Copyright 2008-2016 the original author or authors.
003  *
004  * Licensed under the Apache License, Version 2.0 (the "License");
005  * you may not use this file except in compliance with the License.
006  * You may obtain a copy of the License at
007  *
008  *     http://www.apache.org/licenses/LICENSE-2.0
009  *
010  * Unless required by applicable law or agreed to in writing, software
011  * distributed under the License is distributed on an "AS IS" BASIS,
012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013  * See the License for the specific language governing permissions and
014  * limitations under the License.
015  */
016 package griffon.javafx.test;
017 
018 import org.junit.internal.runners.statements.Fail;
019 import org.junit.runner.notification.Failure;
020 import org.junit.runner.notification.RunListener;
021 import org.junit.runner.notification.RunNotifier;
022 import org.junit.runners.BlockJUnit4ClassRunner;
023 import org.junit.runners.model.FrameworkMethod;
024 import org.junit.runners.model.InitializationError;
025 import org.junit.runners.model.Statement;
026 
027 import javax.annotation.Nonnull;
028 import java.lang.reflect.Field;
029 import java.util.ArrayList;
030 import java.util.Collections;
031 import java.util.Comparator;
032 import java.util.List;
033 
034 import static java.util.Collections.unmodifiableList;
035 import static org.junit.runner.Description.createTestDescription;
036 
037 /**
038  @author Andres Almiray
039  @since 2.6.0
040  */
041 public class FunctionalJavaFXRunner extends BlockJUnit4ClassRunner {
042     private GriffonTestFXClassRule testFXClassRule;
043 
044     public FunctionalJavaFXRunner(@Nonnull Class<?> klassthrows InitializationError {
045         super(klass);
046     }
047 
048     private static class FailureListener extends RunListener {
049         private final GriffonTestFXClassRule testfx;
050 
051         private FailureListener(GriffonTestFXClassRule testfx) {
052             this.testfx = testfx;
053         }
054 
055         @Override
056         public void testFailure(Failure failurethrows Exception {
057             testfx.setFailures(true);
058         }
059     }
060 
061     @Override
062     protected List<FrameworkMethod> computeTestMethods() {
063         List<FrameworkMethod> methods = new ArrayList<>(super.computeTestMethods());
064         Collections.sort(methods, new Comparator<FrameworkMethod>() {
065             @Override
066             public int compare(FrameworkMethod a, FrameworkMethod b) {
067                 return a.getName().compareTo(b.getName());
068             }
069         });
070         return unmodifiableList(methods);
071     }
072 
073     @Override
074     protected void runChild(FrameworkMethod method, RunNotifier notifier) {
075         try {
076             resolveTestFXClassRule(method);
077             notifier.addFirstListener(new FailureListener(testFXClassRule));
078         catch (Exception e) {
079             notifier.fireTestFailure(new Failure(createTestDescription(method.getDeclaringClass(), method.getName()), e));
080         }
081         super.runChild(method, notifier);
082     }
083 
084     @Override
085     protected Statement withBefores(FrameworkMethod method, Object target, Statement statement) {
086         try {
087             resolveTestFXClassRule(method);
088             testFXClassRule.injectMembers(target);
089         catch (Exception e) {
090             return new Fail(e);
091         }
092         return super.withBefores(method, target, statement);
093     }
094 
095     @Override
096     protected boolean isIgnored(FrameworkMethod child) {
097         if (super.isIgnored(child)) {
098             return true;
099         }
100 
101         try {
102             resolveTestFXClassRule(child);
103             return testFXClassRule.hasFailures();
104         catch (Exception e) {
105             return true;
106         }
107     }
108 
109     private void resolveTestFXClassRule(FrameworkMethod childthrows NoSuchFieldException, IllegalAccessException {
110         if (testFXClassRule == null) {
111             for (Field field : child.getDeclaringClass().getFields()) {
112                 if (GriffonTestFXClassRule.class.isAssignableFrom(field.getType())) {
113                     testFXClassRule = (GriffonTestFXClassRulefield.get(null);
114                     return;
115                 }
116             }
117             throw new IllegalStateException("Class " + child.getDeclaringClass().getName() " does not define a field of type " + GriffonTestFXClassRule.class.getName());
118         }
119     }
120 }