1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package org.htmlunit.archunit;
16
17 import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.methods;
18 import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
19
20 import java.util.HashSet;
21 import java.util.Set;
22 import java.util.stream.Collectors;
23
24 import org.htmlunit.BrowserVersion;
25 import org.htmlunit.junit.annotation.AnnotationUtils;
26 import org.junit.Assert;
27 import org.junit.Test;
28 import org.junit.runner.RunWith;
29
30 import com.tngtech.archunit.core.domain.JavaClasses;
31 import com.tngtech.archunit.core.domain.JavaMethod;
32 import com.tngtech.archunit.junit.AnalyzeClasses;
33 import com.tngtech.archunit.junit.ArchTest;
34 import com.tngtech.archunit.junit.ArchUnitRunner;
35 import com.tngtech.archunit.lang.ArchCondition;
36 import com.tngtech.archunit.lang.ArchRule;
37 import com.tngtech.archunit.lang.ConditionEvents;
38 import com.tngtech.archunit.lang.SimpleConditionEvent;
39
40
41
42
43
44
45 @RunWith(ArchUnitRunner.class)
46 @AnalyzeClasses(packages = "org.htmlunit")
47 public class Architecture2Test {
48
49
50
51
52
53 @ArchTest
54 public static void allPropertyTestShouldTestTheSameObjects(final JavaClasses classes) {
55 compare(classes, "ElementPropertiesTest", "ElementOwnPropertiesTest");
56 compare(classes, "ElementPropertiesTest", "ElementOwnPropertySymbolsTest");
57 }
58
59
60
61
62
63 @ArchTest
64 public static void allElementTestShouldTestTheSameObjects(final JavaClasses classes) {
65 compare(classes, "ElementChildNodesTest", "ElementClosesItselfTest");
66 compare(classes, "ElementChildNodesTest", "ElementCreationTest");
67 compare(classes, "ElementChildNodesTest", "ElementDefaultStyleDisplayTest");
68 compare(classes, "ElementChildNodesTest", "ElementOuterHtmlTest");
69 }
70
71
72
73
74
75 @ArchTest
76 public static void allHostTestShouldTestTheSameObjects(final JavaClasses classes) {
77 compare(classes, "HostClassNameTest", "HostTypeOfTest");
78 compare(classes, "HostClassNameTest", "DedicatedWorkerGlobalScopeClassNameTest");
79 compare(classes, "HostClassNameTest", "DedicatedWorkerGlobalScopeTypeOfTest");
80 }
81
82 private static void compare(final JavaClasses classes, final String oneName, final String anotherName) {
83 final Set<String> oneTests =
84 classes.get("org.htmlunit.general." + oneName).getAllMethods().stream()
85 .filter(m -> m.tryGetAnnotationOfType("org.junit.Test").isPresent())
86 .map(m -> m.getName())
87 .collect(Collectors.toSet());
88
89 final Set<String> anotherTests =
90 classes.get("org.htmlunit.general." + anotherName).getAllMethods().stream()
91 .filter(m -> m.tryGetAnnotationOfType("org.junit.Test").isPresent())
92 .map(m -> m.getName())
93 .collect(Collectors.toSet());
94
95 final Set<String> tmp = new HashSet<>(anotherTests);
96 tmp.removeAll(oneTests);
97 oneTests.removeAll(anotherTests);
98
99 if (tmp.size() + oneTests.size() > 0) {
100 if (tmp.size() == 0) {
101 Assert.fail("The " + oneTests.size() + " method(s) "
102 + oneTests.stream().sorted().collect(Collectors.toList())
103 + " are available in " + oneName + " but missing in " + anotherName + ".");
104 }
105 else if (oneTests.size() == 0) {
106 anotherTests.removeAll(oneTests);
107 Assert.fail("The " + tmp.size() + " method(s) "
108 + tmp.stream().sorted().collect(Collectors.toList())
109 + " are available in " + anotherName + " but missing in " + oneName + ".");
110 }
111
112 Assert.fail("The " + tmp.size() + " method(s) "
113 + tmp.stream().sorted().collect(Collectors.toList())
114 + " are available in " + anotherName + " but missing in " + oneName
115 + " and the " + oneTests.size() + " method(s) "
116 + oneTests.stream().sorted().collect(Collectors.toList())
117 + " are available in " + oneName + " but missing in " + anotherName + ".");
118 }
119 }
120
121
122
123
124 @ArchTest
125 public static final ArchRule isChrome = noClasses()
126 .that()
127 .doNotHaveFullyQualifiedName("org.htmlunit.BrowserVersion")
128 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration")
129 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$Chrome")
130 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdge")
131 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdgeAndFirefox")
132 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdgeNotIterable")
133 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.dom.Document")
134 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.DateTimeFormat")
135 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.NumberFormat")
136
137 .should().callMethod(BrowserVersion.class, "isChrome", new Class[] {});
138
139
140
141
142 @ArchTest
143 public static final ArchRule isEdge = noClasses()
144 .that()
145 .doNotHaveFullyQualifiedName("org.htmlunit.BrowserVersion")
146 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration")
147 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$Edge")
148 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$Chrome")
149 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdge")
150 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdgeAndFirefox")
151 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdgeNotIterable")
152 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.dom.Document")
153 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.DateTimeFormat")
154 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.NumberFormat")
155
156 .should().callMethod(BrowserVersion.class, "isEdge", new Class[] {});
157
158
159
160
161 @ArchTest
162 public static final ArchRule isFirefox = noClasses()
163 .that()
164 .doNotHaveFullyQualifiedName("org.htmlunit.BrowserVersion")
165 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration")
166 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.worker.DedicatedWorkerGlobalScope")
167
168 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$FF")
169 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$FFNotIterable")
170 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$FFESR")
171 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$FFLatest")
172 .and().doNotHaveFullyQualifiedName("org.htmlunit.css.BrowserConfiguration$ChromeAndEdgeAndFirefox")
173
174 .and().doNotHaveFullyQualifiedName("org.htmlunit.general.huge.ElementClosesElementTest")
175 .should().callMethod(BrowserVersion.class, "isFirefox", new Class[] {});
176
177
178
179
180 @ArchTest
181 public static final ArchRule isFirefoxESR = noClasses()
182 .that()
183 .doNotHaveFullyQualifiedName("org.htmlunit.BrowserVersion")
184 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.configuration.AbstractJavaScriptConfiguration")
185 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.worker.DedicatedWorkerGlobalScope")
186
187 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.DateTimeFormat")
188 .and().doNotHaveFullyQualifiedName("org.htmlunit.javascript.host.intl.NumberFormat")
189 .should().callMethod(BrowserVersion.class, "isFirefoxESR", new Class[] {});
190
191
192
193
194
195 @ArchTest
196 public static final ArchRule hamcrest = noClasses()
197 .should().dependOnClassesThat().resideInAPackage("org.hamcrest..");
198
199 private static final ArchCondition<JavaMethod> haveConsistentTestAnnotations =
200 new ArchCondition<JavaMethod>("have consistent HtmlUnit test annotations") {
201 @Override
202 public void check(final JavaMethod method, final ConditionEvents events) {
203 try {
204 AnnotationUtils.assertAlerts(method.reflect());
205 }
206 catch (final AssertionError e) {
207 events.add(SimpleConditionEvent.violated(method, e.getMessage()));
208 }
209 }
210 };
211
212
213
214
215 @ArchTest
216 public static final ArchRule consistentTestAnnotations = methods()
217 .that().areAnnotatedWith(Test.class)
218 .and().areNotDeclaredIn("org.htmlunit.junit.annotation.AnnotationUtilsTest")
219 .should(haveConsistentTestAnnotations);
220 }