HtmlUtils.java

1
package fr.sii.ogham.core.util;
2
3
import java.net.URI;
4
import java.net.URISyntaxException;
5
import java.nio.file.Path;
6
import java.nio.file.Paths;
7
import java.util.ArrayList;
8
import java.util.Iterator;
9
import java.util.List;
10
import java.util.regex.Matcher;
11
import java.util.regex.Pattern;
12
13
import org.jsoup.Jsoup;
14
import org.jsoup.nodes.Document;
15
import org.jsoup.nodes.Element;
16
import org.jsoup.select.Elements;
17
import org.slf4j.Logger;
18
import org.slf4j.LoggerFactory;
19
20
/**
21
 * Utility class for handling HTML content. It helps for repetitive tasks for
22
 * manipulating HTML.
23
 * 
24
 * @author Aurélien Baudet
25
 *
26
 */
27
public final class HtmlUtils {
28
	private static final Logger LOG = LoggerFactory.getLogger(HtmlUtils.class);
29
30
	private static final Pattern HTML_PATTERN = Pattern.compile("<html", Pattern.CASE_INSENSITIVE);
31
	private static final String CSS_LINKS_SELECTOR = "link[rel*=\"stylesheet\"], link[type=\"text/css\"], link[href$=\".css\"]";
32
	private static final String HREF_ATTR = "href";
33
	private static final String IMG_SELECTOR = "img";
34
	private static final String SRC_ATTR = "src";
35
	private static final Pattern URL_PATTERN = Pattern.compile("^https?://.+$", Pattern.CASE_INSENSITIVE);
36
	private static final Pattern URI_INVALID_CHARS = Pattern.compile("\\\\'");
37
	private static final String URI_ESCAPE = "''";
38
	private static final Pattern QUOTE_ENTITY = Pattern.compile("&quot;");
39
	private static final String CSS_URL_FUNC = "(?<start>url\\s*\\(\\s*)(?:'(?<singlequotedurl>\\S*?)'|\"(?<doublequotedurl>\\S*?)\"|(?<unquotedurl>(?:\\\\\\s|\\\\\\)|\\\\\\\"|\\\\\\'|\\S)*?))(?<end>\\s*\\))";
40
	/**
41
	 * Regular expression that matches CSS {@code url()} inclusions. It can be:
42
	 * <ul>
43
	 * <li>url(http://some-url)</li>
44
	 * <li>url("http://some-url")</li>
45
	 * <li>url('http://some-url')</li>
46
	 * </ul>
47
	 * 
48
	 * <p>
49
	 * It also handle escaping of quotes.
50
	 * 
51
	 * <p>
52
	 * The pattern provides the following named capturing groups:
53
	 * <ul>
54
	 * <li>{@code "start"}: matches the {@code url(} part</li>
55
	 * <li>{@code "end"}: matches the {@code );} part</li>
56
	 * <li>{@code "singlequotedurl"}: matches the url that is surrounded by
57
	 * {@literal '} character ({@literal '} is not included)</li>
58
	 * <li>{@code "doublequotedurl"}: matches the url that is surrounded by
59
	 * {@literal "} character ({@literal "} is not included)</li>
60
	 * <li>{@code "unquotedurl"}: matches the url that is not surrounded by a
61
	 * character</li>
62
	 * </ul>
63
	 */
64
	public static final Pattern CSS_URL_FUNC_PATTERN = Pattern.compile(CSS_URL_FUNC);
65
	/**
66
	 * Regular expression that matches CSS properties for image inclusions such
67
	 * as:
68
	 * <ul>
69
	 * <li>{@code background: <value>;}</li>
70
	 * <li>{@code background-image: <value>};</li>
71
	 * <li>{@code list-style: <value>};</li>
72
	 * <li>{@code list-style-image: <value>};</li>
73
	 * <li>{@code cursor: <value>};</li>
74
	 * </ul>
75
	 * 
76
	 * <p>
77
	 * The pattern provides the following named capturing groups:
78
	 * <ul>
79
	 * <li>{@code "property"}: matches the property part (property name, spaces
80
	 * and {@literal :})</li>
81
	 * <li>{@code "propertyname"}: matches the property name (such as
82
	 * {@code background})</li>
83
	 * <li>{@code "value"}: matches the property value (without final
84
	 * {@literal ;})</li>
85
	 * </ul>
86
	 */
87
	public static final Pattern CSS_IMAGE_PROPERTIES_PATTERN = Pattern.compile("(?<property>(?<propertyname>((background|list-style)(-image)?)|cursor)\\s*:)(?<value>[^;}>]+)",
88
			Pattern.MULTILINE | Pattern.DOTALL | Pattern.CASE_INSENSITIVE);
89
90
	/**
91
	 * Indicates if the provided content is HTML or not. It is considered HTML
92
	 * only if it is a whole document. Any partial HTML content won't be
93
	 * considered as HTML.
94
	 * 
95
	 * @param content
96
	 *            the content to test
97
	 * @return true if it is HTML, false otherwise
98
	 */
99
	public static boolean isHtml(String content) {
100 10 1. isHtml : replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → NO_COVERAGE
2. isHtml : replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED
3. isHtml : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED
4. isHtml : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED
5. isHtml : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → NO_COVERAGE
6. isHtml : replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → TIMED_OUT
7. isHtml : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → TIMED_OUT
8. isHtml : replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED
9. isHtml : replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED
10. isHtml : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED
		return HTML_PATTERN.matcher(content).find();
101
	}
102
103
	/**
104
	 * Finds all CSS file inclusions (looks for <code>link</code> tags for
105
	 * stylesheet files). Returns only the path or URL to the CSS file. If the
106
	 * several CSS inclusions have the same path, the path is present in the
107
	 * list only one time.
108
	 * 
109
	 * @param htmlContent
110
	 *            the html content that may contain external CSS files
111
	 * @return the list of found CSS inclusions (paths only) or empty if nothing
112
	 *         found
113
	 */
114
	public static List<String> getDistinctCssUrls(String htmlContent) {
115
		Document doc = Jsoup.parse(htmlContent);
116
		Elements els = doc.select(CSS_LINKS_SELECTOR);
117
		List<String> cssFiles = new ArrayList<>(els.size());
118
		for (Element e : els) {
119
			String path = e.attr(HREF_ATTR);
120 3 1. getDistinctCssUrls : negated conditional → NO_COVERAGE
2. getDistinctCssUrls : negated conditional → KILLED
3. getDistinctCssUrls : negated conditional → KILLED
			if (!cssFiles.contains(path)) {
121
				cssFiles.add(path);
122
			}
123
		}
124 4 1. getDistinctCssUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → NO_COVERAGE
2. getDistinctCssUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → TIMED_OUT
3. getDistinctCssUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → KILLED
4. getDistinctCssUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → KILLED
		return cssFiles;
125
	}
126
127
	/**
128
	 * Finds all image inclusions (looks for <code>img</code> tags). Returns
129
	 * only the path or URL to the image. If the several images have the same
130
	 * path, the path is present in the list only one time.
131
	 * 
132
	 * @param htmlContent
133
	 *            the html content that may contain image files
134
	 * @return the list of found images (paths only) or empty if nothing found
135
	 */
136
	public static List<String> getDistinctImageUrls(String htmlContent) {
137
		Document doc = Jsoup.parse(htmlContent);
138
		Elements els = doc.select(IMG_SELECTOR);
139
		List<String> images = new ArrayList<>(els.size());
140
		for (Element e : els) {
141
			String path = e.attr(SRC_ATTR);
142 3 1. getDistinctImageUrls : negated conditional → NO_COVERAGE
2. getDistinctImageUrls : negated conditional → KILLED
3. getDistinctImageUrls : negated conditional → KILLED
			if (!images.contains(path)) {
143
				images.add(path);
144
			}
145
		}
146 5 1. getDistinctImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → SURVIVED
2. getDistinctImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → NO_COVERAGE
3. getDistinctImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → TIMED_OUT
4. getDistinctImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → KILLED
5. getDistinctImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → KILLED
		return images;
147
	}
148
149
	/**
150
	 * Finds all image inclusions from CSS properties. Returns only the path or
151
	 * URL to the image. If the several images have the same path, the path is
152
	 * present in the list only one time.
153
	 * 
154
	 * <p>
155
	 * It looks for:
156
	 * <ul>
157
	 * <li><code>background</code></li>
158
	 * <li><code>background-image</code></li>
159
	 * <li><code>list-style</code></li>
160
	 * <li><code>list-style-image</code></li>
161
	 * <li><code>cursor</code></li>
162
	 * </ul>
163
	 * 
164
	 * @param htmlContent
165
	 *            the html content that may contain image files
166
	 * @return the list of found images (paths only) or empty if nothing found
167
	 */
168
	public static List<String> getDistinctCssImageUrls(String htmlContent) {
169
		List<String> urls = new ArrayList<>();
170
		Matcher m = CSS_IMAGE_PROPERTIES_PATTERN.matcher(QUOTE_ENTITY.matcher(htmlContent).replaceAll("'"));
171 5 1. getDistinctCssImageUrls : negated conditional → NO_COVERAGE
2. getDistinctCssImageUrls : negated conditional → TIMED_OUT
3. getDistinctCssImageUrls : negated conditional → KILLED
4. getDistinctCssImageUrls : negated conditional → KILLED
5. getDistinctCssImageUrls : negated conditional → KILLED
		while (m.find()) {
172
			String value = m.group("value");
173
			Matcher urlMatcher = CSS_URL_FUNC_PATTERN.matcher(value);
174 3 1. getDistinctCssImageUrls : negated conditional → NO_COVERAGE
2. getDistinctCssImageUrls : negated conditional → KILLED
3. getDistinctCssImageUrls : negated conditional → KILLED
			while (urlMatcher.find()) {
175
				String url = urlMatcher.group("unquotedurl");
176 3 1. getDistinctCssImageUrls : negated conditional → NO_COVERAGE
2. getDistinctCssImageUrls : negated conditional → KILLED
3. getDistinctCssImageUrls : negated conditional → KILLED
				if (url == null) {
177
					url = urlMatcher.group("singlequotedurl");
178
				}
179 3 1. getDistinctCssImageUrls : negated conditional → NO_COVERAGE
2. getDistinctCssImageUrls : negated conditional → KILLED
3. getDistinctCssImageUrls : negated conditional → KILLED
				if (url == null) {
180
					url = urlMatcher.group("doublequotedurl");
181
				}
182 3 1. getDistinctCssImageUrls : negated conditional → NO_COVERAGE
2. getDistinctCssImageUrls : negated conditional → KILLED
3. getDistinctCssImageUrls : negated conditional → KILLED
				if (!urls.contains(url)) {
183
					urls.add(url);
184
				}
185
			}
186
		}
187 5 1. getDistinctCssImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → SURVIVED
2. getDistinctCssImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → NO_COVERAGE
3. getDistinctCssImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → TIMED_OUT
4. getDistinctCssImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → KILLED
5. getDistinctCssImageUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → KILLED
		return urls;
188
	}
189
190
	/**
191
	 * Get the title of the HTML. If no <code>title</code> tag exists, then the
192
	 * title is null.
193
	 * 
194
	 * @param htmlContent
195
	 *            the HTML content that may contain a title
196
	 * @return the title of the HTML or null if none
197
	 */
198
	public static String getTitle(String htmlContent) {
199
		Document doc = Jsoup.parse(htmlContent);
200
		Elements titleNode = doc.select("head > title");
201 8 1. getTitle : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → NO_COVERAGE
2. getTitle : negated conditional → NO_COVERAGE
3. getTitle : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → TIMED_OUT
4. getTitle : negated conditional → TIMED_OUT
5. getTitle : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → KILLED
6. getTitle : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → KILLED
7. getTitle : negated conditional → KILLED
8. getTitle : negated conditional → KILLED
		return titleNode.isEmpty() ? null : doc.title();
202
	}
203
204
	/**
205
	 * The list of provided URLs are either relative or absolute. This method
206
	 * returns only the list of relative URLs.
207
	 * 
208
	 * <p>
209
	 * The URL is considered absolute if it starts with {@code "http://"} or
210
	 * {@code https://}.
211
	 * 
212
	 * 
213
	 * @param urls
214
	 *            the urls (relative or absolute)
215
	 * @return the relative urls only
216
	 */
217
	public static List<String> skipExternalUrls(List<String> urls) {
218 5 1. skipExternalUrls : negated conditional → NO_COVERAGE
2. skipExternalUrls : negated conditional → TIMED_OUT
3. skipExternalUrls : negated conditional → KILLED
4. skipExternalUrls : negated conditional → KILLED
5. skipExternalUrls : negated conditional → KILLED
		for (Iterator<String> it = urls.iterator(); it.hasNext();) {
219
			String url = it.next();
220 3 1. skipExternalUrls : negated conditional → NO_COVERAGE
2. skipExternalUrls : negated conditional → KILLED
3. skipExternalUrls : negated conditional → KILLED
			if (URL_PATTERN.matcher(url).matches()) {
221 3 1. skipExternalUrls : removed call to java/util/Iterator::remove → NO_COVERAGE
2. skipExternalUrls : removed call to java/util/Iterator::remove → KILLED
3. skipExternalUrls : removed call to java/util/Iterator::remove → KILLED
				it.remove();
222
			}
223
		}
224 5 1. skipExternalUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → NO_COVERAGE
2. skipExternalUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → SURVIVED
3. skipExternalUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → TIMED_OUT
4. skipExternalUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → KILLED
5. skipExternalUrls : replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → KILLED
		return urls;
225
	}
226
227
	/**
228
	 * Generate a relative URL/path:
229
	 * <ul>
230
	 * <li>If {@code other} parameter is absolute, then return
231
	 * {@code other}.</li>
232
	 * <li>If {@code other} parameter is relative, then it merges {@code other}
233
	 * into {@code base}. For example:
234
	 * <ul>
235
	 * <li>base="css/foo.css", other="bar.png" {@literal =>} returns "css/bar.png"</li>
236
	 * <li>base="css/foo.css", other="../images/bar.png" {@literal =>} returns
237
	 * "images/bar.png"</li>
238
	 * <li>base="http://some-url/css/foo.css", other="bar.png" {@literal =>} returns
239
	 * "http://some-url/css/bar.png"</li>
240
	 * <li>base="http://some-url/css/foo.css", other="../images/bar.png" {@literal =>}
241
	 * returns "http://some-url/images/bar.png"</li>
242
	 * </ul>
243
	 * </li>
244
	 * </ul>
245
	 * 
246
	 * <p>
247
	 * This method uses {@link #isRelativeUrl(String)} to determine if
248
	 * {@code other} is relative or absolute.
249
	 * 
250
	 * @param base
251
	 *            the base path/URL
252
	 * @param other
253
	 *            the path/URL to relativize
254
	 * @return the merge path/URL
255
	 */
256
	public static String relativize(String base, String other) {
257 3 1. relativize : negated conditional → NO_COVERAGE
2. relativize : negated conditional → KILLED
3. relativize : negated conditional → KILLED
		if (!isRelativeUrl(other)) {
258 2 1. relativize : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → NO_COVERAGE
2. relativize : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED
			return other;
259
		}
260
		Path basePath = Paths.get(base);
261 3 1. relativize : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → NO_COVERAGE
2. relativize : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED
3. relativize : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED
		return unescapeJavaUri(ResourceUtils.toResourcePath(basePath.resolveSibling(escapeForJavaUri(other)).normalize()));
262
	}
263
	
264
	/**
265
	 * Indicates if the URL is relative or not.
266
	 * 
267
	 * <p>
268
	 * Relative URLs may be:
269
	 * <ul>
270
	 * <li>{@code "relative/path"}</li>
271
	 * <li>{@code "./relative/path"}</li>
272
	 * <li>{@code "../relative/path"}</li>
273
	 * </ul>
274
	 * 
275
	 * <p>
276
	 * On the contrary, any URL that matches one of the following condition is
277
	 * absolute:
278
	 * <ul>
279
	 * <li>starts with a scheme or protocol (like {@code "http://"} or
280
	 * {@code "classpath:"}</li>
281
	 * <li>starts with a {@code "/"}</li>
282
	 * </ul>
283
	 * 
284
	 * @param url
285
	 *            the URL that may be relative or absolute
286
	 * @return true if relative
287
	 */
288
	public static boolean isRelativeUrl(String url) {
289
		try {
290 3 1. isRelativeUrl : negated conditional → NO_COVERAGE
2. isRelativeUrl : negated conditional → KILLED
3. isRelativeUrl : negated conditional → KILLED
			if (url.startsWith("/")) {
291 2 1. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → SURVIVED
2. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE
				return false;
292
			}
293
			URI u = new URI(escapeForJavaUri(url));
294 6 1. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → SURVIVED
2. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE
3. isRelativeUrl : negated conditional → NO_COVERAGE
4. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → KILLED
5. isRelativeUrl : negated conditional → KILLED
6. isRelativeUrl : negated conditional → KILLED
			return !u.isAbsolute();
295
		} catch (URISyntaxException e) {
296
			LOG.warn("Can't determine if '{}' url is relative or absolute => consider absolute", url);
297
			LOG.trace("", e);
298 1 1. isRelativeUrl : replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE
			return false;
299
		}
300
	}
301
302
	private static String escapeForJavaUri(String url) {
303 3 1. escapeForJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → NO_COVERAGE
2. escapeForJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → KILLED
3. escapeForJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → KILLED
		return URI_INVALID_CHARS.matcher(url).replaceAll(URI_ESCAPE);
304
	}
305
306
	@SuppressWarnings("java:S5361")
307
	private static String unescapeJavaUri(String url) {
308 3 1. unescapeJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → NO_COVERAGE
2. unescapeJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → KILLED
3. unescapeJavaUri : replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → KILLED
		return url.replaceAll(URI_ESCAPE, URI_INVALID_CHARS.pattern());
309
	}
310
	
311
	private HtmlUtils() {
312
		super();
313
	}
314
}

Mutations

100

1.1
Location : isHtml
Killed by : oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest.withTitle(oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest)
replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED

2.2
Location : isHtml
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.unreadableCss(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED

3.3
Location : isHtml
Killed by : none
replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → TIMED_OUT

4.4
Location : isHtml
Killed by : none
replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → NO_COVERAGE

5.5
Location : isHtml
Killed by : none
replaced boolean return with false for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED

6.6
Location : isHtml
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED

7.7
Location : isHtml
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.notHtml(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → KILLED

8.8
Location : isHtml
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → SURVIVED

9.9
Location : isHtml
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → TIMED_OUT

10.10
Location : isHtml
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isHtml → NO_COVERAGE

120

1.1
Location : getDistinctCssUrls
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getDistinctCssUrls
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.unreadableCss(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
negated conditional → KILLED

3.3
Location : getDistinctCssUrls
Killed by : oghamcore.it.html.translator.InlineCssTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineCssTranslatorTest)
negated conditional → KILLED

124

1.1
Location : getDistinctCssUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → TIMED_OUT

2.2
Location : getDistinctCssUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → NO_COVERAGE

3.3
Location : getDistinctCssUrls
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.unreadableCss(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → KILLED

4.4
Location : getDistinctCssUrls
Killed by : oghamcore.it.html.translator.InlineCssTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineCssTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssUrls → KILLED

142

1.1
Location : getDistinctImageUrls
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getDistinctImageUrls
Killed by : oghamall.it.html.translator.JsoupInlineImageTranslatorTest.unreadableImage(oghamall.it.html.translator.JsoupInlineImageTranslatorTest)
negated conditional → KILLED

3.3
Location : getDistinctImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

146

1.1
Location : getDistinctImageUrls
Killed by : oghamall.it.html.translator.JsoupInlineImageTranslatorTest.unreadableImage(oghamall.it.html.translator.JsoupInlineImageTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → KILLED

2.2
Location : getDistinctImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → SURVIVED

3.3
Location : getDistinctImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → TIMED_OUT

4.4
Location : getDistinctImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineImageTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → KILLED

5.5
Location : getDistinctImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctImageUrls → NO_COVERAGE

171

1.1
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → TIMED_OUT

4.4
Location : getDistinctCssImageUrls
Killed by : oghamall.it.html.translator.JsoupInlineImageTranslatorTest.unreadableImage(oghamall.it.html.translator.JsoupInlineImageTranslatorTest)
negated conditional → KILLED

5.5
Location : getDistinctCssImageUrls
Killed by : oghamjavamail.it.UnreadableAttachmentTest.attachmentUnreadable(oghamjavamail.it.UnreadableAttachmentTest)
negated conditional → KILLED

174

1.1
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.backgroudImagesShouldBeInlined(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

2.2
Location : getDistinctCssImageUrls
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → NO_COVERAGE

176

1.1
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getDistinctCssImageUrls
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.backgroudImagesShouldBeInlined(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

179

1.1
Location : getDistinctCssImageUrls
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

2.2
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.backgroudImagesShouldBeInlined(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → NO_COVERAGE

182

1.1
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.backgroudImagesShouldBeInlined(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

2.2
Location : getDistinctCssImageUrls
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : none
negated conditional → NO_COVERAGE

187

1.1
Location : getDistinctCssImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → SURVIVED

2.2
Location : getDistinctCssImageUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.backgroudImagesShouldBeInlined(oghamcore.it.html.translator.InlineImageTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → KILLED

3.3
Location : getDistinctCssImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → TIMED_OUT

4.4
Location : getDistinctCssImageUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → NO_COVERAGE

5.5
Location : getDistinctCssImageUrls
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::getDistinctCssImageUrls → KILLED

201

1.1
Location : getTitle
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → TIMED_OUT

2.2
Location : getTitle
Killed by : oghamall.it.email.EmailExtractSubjectTest.noSubjectInContentsWithoutDefaultSubjectShouldSendWithoutSubject(oghamall.it.email.EmailExtractSubjectTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → KILLED

3.3
Location : getTitle
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → NO_COVERAGE

4.4
Location : getTitle
Killed by : oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest.withTitle(oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::getTitle → KILLED

5.5
Location : getTitle
Killed by : none
negated conditional → NO_COVERAGE

6.6
Location : getTitle
Killed by : none
negated conditional → TIMED_OUT

7.7
Location : getTitle
Killed by : oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest.withTitle(oghamcore.ut.email.subject.provider.HtmlTitleSubjectProviderTest)
negated conditional → KILLED

8.8
Location : getTitle
Killed by : oghamall.it.email.EmailExtractSubjectTest.noSubjectInContentsWithoutDefaultSubjectShouldSendWithoutSubject(oghamall.it.email.EmailExtractSubjectTest)
negated conditional → KILLED

218

1.1
Location : skipExternalUrls
Killed by : oghamjavamail.it.UnreadableAttachmentTest.attachmentUnreadable(oghamjavamail.it.UnreadableAttachmentTest)
negated conditional → KILLED

2.2
Location : skipExternalUrls
Killed by : none
negated conditional → TIMED_OUT

3.3
Location : skipExternalUrls
Killed by : oghamall.it.html.translator.JsoupInlineImageTranslatorTest.skipExternalImages(oghamall.it.html.translator.JsoupInlineImageTranslatorTest)
negated conditional → KILLED

4.4
Location : skipExternalUrls
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : skipExternalUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.absoluteUrlsShouldBeAutomaticallySkipped(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

220

1.1
Location : skipExternalUrls
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.unreadableCss(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
negated conditional → KILLED

2.2
Location : skipExternalUrls
Killed by : none
negated conditional → NO_COVERAGE

3.3
Location : skipExternalUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineImageTranslatorTest)
negated conditional → KILLED

221

1.1
Location : skipExternalUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.absoluteUrlsShouldBeAutomaticallySkipped(oghamcore.it.html.translator.InlineImageTranslatorTest)
removed call to java/util/Iterator::remove → KILLED

2.2
Location : skipExternalUrls
Killed by : oghamall.it.html.translator.JsoupInlineImageTranslatorTest.skipExternalImages(oghamall.it.html.translator.JsoupInlineImageTranslatorTest)
removed call to java/util/Iterator::remove → KILLED

3.3
Location : skipExternalUrls
Killed by : none
removed call to java/util/Iterator::remove → NO_COVERAGE

224

1.1
Location : skipExternalUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → NO_COVERAGE

2.2
Location : skipExternalUrls
Killed by : oghamall.it.html.translator.JsoupInlineCssTranslatorTest.unreadableCss(oghamall.it.html.translator.JsoupInlineCssTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → KILLED

3.3
Location : skipExternalUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → TIMED_OUT

4.4
Location : skipExternalUrls
Killed by : oghamcore.it.html.translator.InlineImageTranslatorTest.oghamAttributesShoulBeRemoved(oghamcore.it.html.translator.InlineImageTranslatorTest)
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → KILLED

5.5
Location : skipExternalUrls
Killed by : none
replaced return value with Collections.emptyList for fr/sii/ogham/core/util/HtmlUtils::skipExternalUrls → SURVIVED

257

1.1
Location : relativize
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : relativize
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
negated conditional → KILLED

3.3
Location : relativize
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

258

1.1
Location : relativize
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED

2.2
Location : relativize
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → NO_COVERAGE

261

1.1
Location : relativize
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → NO_COVERAGE

2.2
Location : relativize
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED

3.3
Location : relativize
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::relativize → KILLED

290

1.1
Location : isRelativeUrl
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

2.2
Location : isRelativeUrl
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
negated conditional → KILLED

3.3
Location : isRelativeUrl
Killed by : none
negated conditional → NO_COVERAGE

291

1.1
Location : isRelativeUrl
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → SURVIVED

2.2
Location : isRelativeUrl
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE

294

1.1
Location : isRelativeUrl
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → SURVIVED

2.2
Location : isRelativeUrl
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE

3.3
Location : isRelativeUrl
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → KILLED

4.4
Location : isRelativeUrl
Killed by : none
negated conditional → NO_COVERAGE

5.5
Location : isRelativeUrl
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
negated conditional → KILLED

6.6
Location : isRelativeUrl
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
negated conditional → KILLED

298

1.1
Location : isRelativeUrl
Killed by : none
replaced boolean return with true for fr/sii/ogham/core/util/HtmlUtils::isRelativeUrl → NO_COVERAGE

303

1.1
Location : escapeForJavaUri
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → KILLED

2.2
Location : escapeForJavaUri
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → KILLED

3.3
Location : escapeForJavaUri
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::escapeForJavaUri → NO_COVERAGE

308

1.1
Location : unescapeJavaUri
Killed by : none
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → NO_COVERAGE

2.2
Location : unescapeJavaUri
Killed by : oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest.updateRelativeUrls(oghamcore.ut.html.inliner.impl.JsoupCssInlinerTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → KILLED

3.3
Location : unescapeJavaUri
Killed by : oghamall.it.email.EmailResourceInliningTest.inlineResources(oghamall.it.email.EmailResourceInliningTest)
replaced return value with "" for fr/sii/ogham/core/util/HtmlUtils::unescapeJavaUri → KILLED

Active mutators

Tests examined


Report generated by PIT OGHAM