|
1
|
|
/******************************************************************************* |
|
2
|
|
* Copyright (C) 2026, Leo Galambos |
|
3
|
|
* All rights reserved. |
|
4
|
|
* |
|
5
|
|
* Redistribution and use in source and binary forms, with or without |
|
6
|
|
* modification, are permitted provided that the following conditions are met: |
|
7
|
|
* |
|
8
|
|
* 1. Redistributions of source code must retain the above copyright notice, |
|
9
|
|
* this list of conditions and the following disclaimer. |
|
10
|
|
* |
|
11
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice, |
|
12
|
|
* this list of conditions and the following disclaimer in the documentation |
|
13
|
|
* and/or other materials provided with the distribution. |
|
14
|
|
* |
|
15
|
|
* 3. Neither the name of the copyright holder nor the names of its contributors |
|
16
|
|
* may be used to endorse or promote products derived from this software |
|
17
|
|
* without specific prior written permission. |
|
18
|
|
* |
|
19
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
20
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
21
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
22
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
|
23
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
24
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
25
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
26
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
27
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
28
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
29
|
|
* POSSIBILITY OF SUCH DAMAGE. |
|
30
|
|
******************************************************************************/ |
|
31
|
|
package org.egothor.stemmer; |
|
32
|
|
|
|
33
|
|
import java.io.BufferedReader; |
|
34
|
|
import java.io.IOException; |
|
35
|
|
import java.io.InputStream; |
|
36
|
|
import java.io.InputStreamReader; |
|
37
|
|
import java.net.URL; |
|
38
|
|
import java.nio.charset.StandardCharsets; |
|
39
|
|
import java.util.ArrayList; |
|
40
|
|
import java.util.Collections; |
|
41
|
|
import java.util.Enumeration; |
|
42
|
|
import java.util.LinkedHashMap; |
|
43
|
|
import java.util.List; |
|
44
|
|
import java.util.Map; |
|
45
|
|
import java.util.Objects; |
|
46
|
|
import java.util.Properties; |
|
47
|
|
|
|
48
|
|
/** |
|
49
|
|
* Immutable deterministic registry of models discovered from classpath indexes. |
|
50
|
|
* |
|
51
|
|
* <p>Discovery enumerates every {@value #INDEX_RESOURCE} visible to the selected |
|
52
|
|
* class loader, validates the referenced descriptors, sorts them by stable model |
|
53
|
|
* identifier, and rejects duplicate identifiers. Selection never depends on |
|
54
|
|
* classpath order. Registry creation validates metadata and resource presence; |
|
55
|
|
* {@link StemmerPatchTrieLoader} verifies resource bytes when loading a model.</p> |
|
56
|
|
* |
|
57
|
|
* <p>Registry creation is not globally cached. Applications should normally |
|
58
|
|
* discover once for a class-loader scope and retain the immutable result.</p> |
|
59
|
|
*/ |
|
60
|
|
@SuppressWarnings({ "PMD.UseProperClassLoader", "PMD.ControlStatementBraces" }) |
|
61
|
|
public final class StemmerModelRegistry { |
|
62
|
|
/** Fixed classpath index name used by every model artifact. */ |
|
63
|
|
public static final String INDEX_RESOURCE = "META-INF/radixor/models.index"; |
|
64
|
|
private static final String FORMAT = "radixor-dictionary-tsv-gzip"; |
|
65
|
|
private static final int FORMAT_VERSION = 1; |
|
66
|
|
private final Map<String, StemmerModelDescriptor> descriptors; |
|
67
|
|
|
|
68
|
|
/** Creates an immutable registry from already validated descriptors. */ |
|
69
|
|
private StemmerModelRegistry(final Map<String, StemmerModelDescriptor> descriptors) { |
|
70
|
|
this.descriptors = Collections.unmodifiableMap(new LinkedHashMap<>(descriptors)); |
|
71
|
|
} |
|
72
|
|
|
|
73
|
|
/** |
|
74
|
|
* Discovers models through the current thread context class loader. |
|
75
|
|
* |
|
76
|
|
* <p>If the context loader is {@code null}, the defining class loader of this |
|
77
|
|
* registry is used.</p> |
|
78
|
|
* |
|
79
|
|
* @return immutable registry in stable model-ID order |
|
80
|
|
* @throws IOException if index or descriptor resources cannot be enumerated or read |
|
81
|
|
* @throws DuplicateStemmerModelException if two descriptors declare one model ID |
|
82
|
|
* @throws StemmerModelIntegrityException if an index, descriptor, or declared resource is invalid |
|
83
|
|
* @throws UnsupportedStemmerModelFormatException if a descriptor uses an unsupported format |
|
84
|
|
*/ |
|
85
|
|
public static StemmerModelRegistry fromContextClassLoader() throws IOException { |
|
86
|
|
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); |
|
87
|
2
1. fromContextClassLoader : negated conditional → SURVIVED
2. fromContextClassLoader : replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::fromContextClassLoader → KILLED
|
return fromClassLoader(classLoader == null ? StemmerModelRegistry.class.getClassLoader() : classLoader); |
|
88
|
|
} |
|
89
|
|
|
|
90
|
|
/** |
|
91
|
|
* Discovers and validates every indexed descriptor visible to an explicit class loader. |
|
92
|
|
* |
|
93
|
|
* @param classLoader class loader whose indexed model resources are visible |
|
94
|
|
* @return immutable registry in stable model-ID order |
|
95
|
|
* @throws NullPointerException if {@code classLoader} is {@code null} |
|
96
|
|
* @throws IOException if index or descriptor resources cannot be enumerated or read |
|
97
|
|
* @throws DuplicateStemmerModelException if two descriptors declare one model ID |
|
98
|
|
* @throws StemmerModelIntegrityException if an index, descriptor, or declared resource is invalid |
|
99
|
|
* @throws UnsupportedStemmerModelFormatException if a descriptor uses an unsupported format |
|
100
|
|
*/ |
|
101
|
|
public static StemmerModelRegistry fromClassLoader(final ClassLoader classLoader) throws IOException { |
|
102
|
|
Objects.requireNonNull(classLoader, "classLoader"); |
|
103
|
|
final List<URL> indexes = Collections.list(classLoader.getResources(INDEX_RESOURCE)); |
|
104
|
2
1. fromClassLoader : removed call to java/util/List::sort → SURVIVED
2. lambda$fromClassLoader$0 : replaced int return with 0 for org/egothor/stemmer/StemmerModelRegistry::lambda$fromClassLoader$0 → SURVIVED
|
indexes.sort((left, right) -> left.toExternalForm().compareTo(right.toExternalForm())); |
|
105
|
|
final List<StemmerModelDescriptor> discovered = new ArrayList<>(); |
|
106
|
|
for (URL index : indexes) { |
|
107
|
1
1. fromClassLoader : removed call to org/egothor/stemmer/StemmerModelRegistry::readIndex → KILLED
|
readIndex(index, classLoader, discovered); |
|
108
|
|
} |
|
109
|
1
1. fromClassLoader : removed call to java/util/Collections::sort → SURVIVED
|
Collections.sort(discovered); |
|
110
|
|
final Map<String, StemmerModelDescriptor> byId = new LinkedHashMap<>(); |
|
111
|
|
for (StemmerModelDescriptor descriptor : discovered) { |
|
112
|
|
final StemmerModelDescriptor previous = byId.putIfAbsent(descriptor.id(), descriptor); |
|
113
|
1
1. fromClassLoader : negated conditional → KILLED
|
if (previous != null) { |
|
114
|
|
throw new DuplicateStemmerModelException("Duplicate model ID '" + descriptor.id() + "' at " |
|
115
|
|
+ previous.source() + " and " + descriptor.source() + "."); |
|
116
|
|
} |
|
117
|
|
} |
|
118
|
1
1. fromClassLoader : replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::fromClassLoader → KILLED
|
return new StemmerModelRegistry(byId); |
|
119
|
|
} |
|
120
|
|
|
|
121
|
|
/** Returns all descriptors in stable model-identifier order. */ |
|
122
|
1
1. models : replaced return value with Collections.emptyList for org/egothor/stemmer/StemmerModelRegistry::models → SURVIVED
|
public List<StemmerModelDescriptor> models() { return List.copyOf(this.descriptors.values()); } |
|
123
|
|
|
|
124
|
|
/** |
|
125
|
|
* Returns the model with an exact stable identifier. |
|
126
|
|
* |
|
127
|
|
* @param modelId exact stable model identifier |
|
128
|
|
* @return matching descriptor |
|
129
|
|
* @throws NullPointerException if {@code modelId} is {@code null} |
|
130
|
|
* @throws StemmerModelNotFoundException if the selected class loader exposes no matching descriptor |
|
131
|
|
*/ |
|
132
|
|
public StemmerModelDescriptor require(final String modelId) { |
|
133
|
|
Objects.requireNonNull(modelId, "modelId"); |
|
134
|
|
final StemmerModelDescriptor descriptor = this.descriptors.get(modelId); |
|
135
|
1
1. require : negated conditional → KILLED
|
if (descriptor == null) { |
|
136
|
|
throw new StemmerModelNotFoundException("No model '" + modelId + "' is available. Add org.egothor:radixor-model-" |
|
137
|
|
+ modelId + ":<version> to the runtime classpath."); |
|
138
|
|
} |
|
139
|
1
1. require : replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::require → KILLED
|
return descriptor; |
|
140
|
|
} |
|
141
|
|
|
|
142
|
|
/** |
|
143
|
|
* Returns all models for a language in stable model-identifier order. |
|
144
|
|
* |
|
145
|
|
* @param language language to filter |
|
146
|
|
* @return immutable list, possibly empty |
|
147
|
|
* @throws NullPointerException if {@code language} is {@code null} |
|
148
|
|
*/ |
|
149
|
|
public List<StemmerModelDescriptor> findByLanguage(final StemmerPatchTrieLoader.Language language) { |
|
150
|
|
Objects.requireNonNull(language, "language"); |
|
151
|
3
1. findByLanguage : replaced return value with Collections.emptyList for org/egothor/stemmer/StemmerModelRegistry::findByLanguage → KILLED
2. lambda$findByLanguage$1 : negated conditional → KILLED
3. lambda$findByLanguage$1 : replaced boolean return with true for org/egothor/stemmer/StemmerModelRegistry::lambda$findByLanguage$1 → KILLED
|
return this.descriptors.values().stream().filter(value -> value.language() == language).toList(); |
|
152
|
|
} |
|
153
|
|
|
|
154
|
|
/** |
|
155
|
|
* Resolves the language's documented default model without classpath-order fallback. |
|
156
|
|
* |
|
157
|
|
* @param language language whose {@link StemmerPatchTrieLoader.Language#defaultModelId()} is required |
|
158
|
|
* @return exact default-model descriptor |
|
159
|
|
* @throws NullPointerException if {@code language} is {@code null} |
|
160
|
|
* @throws StemmerModelNotFoundException if the default model is not visible |
|
161
|
|
* @throws StemmerModelIntegrityException if the default descriptor declares another language |
|
162
|
|
*/ |
|
163
|
|
public StemmerModelDescriptor requireDefault(final StemmerPatchTrieLoader.Language language) { |
|
164
|
|
Objects.requireNonNull(language, "language"); |
|
165
|
|
final StemmerModelDescriptor descriptor = this.descriptors.get(language.defaultModelId()); |
|
166
|
1
1. requireDefault : negated conditional → KILLED
|
if (descriptor == null) { |
|
167
|
|
throw new StemmerModelNotFoundException("No default model '" + language.defaultModelId() |
|
168
|
|
+ "' is available for language " + language + ". Add org.egothor:radixor-model-" |
|
169
|
|
+ language.defaultModelId() + ":<version> to the runtime classpath."); |
|
170
|
|
} |
|
171
|
1
1. requireDefault : negated conditional → KILLED
|
if (descriptor.language() != language) { |
|
172
|
|
throw new StemmerModelIntegrityException("Default model '" + descriptor.id() + "' declares language " |
|
173
|
|
+ descriptor.language() + " instead of " + language + "."); |
|
174
|
|
} |
|
175
|
1
1. requireDefault : replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::requireDefault → KILLED
|
return descriptor; |
|
176
|
|
} |
|
177
|
|
|
|
178
|
|
/** Reads one deterministic index and appends its descriptors. */ |
|
179
|
|
private static void readIndex(final URL index, final ClassLoader classLoader, |
|
180
|
|
final List<StemmerModelDescriptor> descriptors) throws IOException { |
|
181
|
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(index.openStream(), StandardCharsets.UTF_8))) { |
|
182
|
|
String line; |
|
183
|
|
int lineNumber = 0; |
|
184
|
1
1. readIndex : negated conditional → KILLED
|
while ((line = reader.readLine()) != null) { |
|
185
|
1
1. readIndex : Changed increment from 1 to -1 → SURVIVED
|
lineNumber++; |
|
186
|
|
final String path = line.trim(); |
|
187
|
2
1. readIndex : negated conditional → KILLED
2. readIndex : negated conditional → KILLED
|
if (path.isEmpty() || path.startsWith("#")) continue; |
|
188
|
1
1. readIndex : negated conditional → KILLED
|
if (!path.matches("META-INF/radixor/models/[a-z0-9-]+\\.properties")) { |
|
189
|
|
throw new StemmerModelIntegrityException("Malformed model index entry at " + index + ":" + lineNumber + ": " + path); |
|
190
|
|
} |
|
191
|
|
final Enumeration<URL> resources = classLoader.getResources(path); |
|
192
|
1
1. readIndex : negated conditional → KILLED
|
if (!resources.hasMoreElements()) throw new StemmerModelIntegrityException("Indexed descriptor is missing: " + path + " from " + index); |
|
193
|
1
1. readIndex : negated conditional → KILLED
|
while (resources.hasMoreElements()) descriptors.add(readDescriptor(resources.nextElement(), classLoader)); |
|
194
|
|
} |
|
195
|
|
} |
|
196
|
|
} |
|
197
|
|
|
|
198
|
|
/** Parses and validates one immutable descriptor. */ |
|
199
|
|
private static StemmerModelDescriptor readDescriptor(final URL source, final ClassLoader classLoader) throws IOException { |
|
200
|
|
final Properties properties = new Properties(); |
|
201
|
1
1. readDescriptor : removed call to java/util/Properties::load → KILLED
|
try (InputStream input = source.openStream()) { properties.load(input); } |
|
202
|
|
final String id = required(properties, "model.id", source); |
|
203
|
1
1. readDescriptor : negated conditional → KILLED
|
if (!id.matches("[a-z]{2}(?:-[a-z]{2})?-[a-z0-9]+(?:-[a-z0-9]+)*")) throw new StemmerModelIntegrityException("Invalid model.id '" + id + "' at " + source); |
|
204
|
|
final String format = required(properties, "model.format", source); |
|
205
|
|
final int version; |
|
206
|
|
try { version = Integer.parseInt(required(properties, "model.formatVersion", source)); } |
|
207
|
|
catch (NumberFormatException exception) { throw new StemmerModelIntegrityException("Invalid model.formatVersion at " + source, exception); } |
|
208
|
2
1. readDescriptor : negated conditional → KILLED
2. readDescriptor : negated conditional → KILLED
|
if (!FORMAT.equals(format) || version != FORMAT_VERSION) throw new UnsupportedStemmerModelFormatException("Unsupported model format " + format + " version " + version + " at " + source + "."); |
|
209
|
|
final StemmerPatchTrieLoader.Language language; |
|
210
|
|
try { language = StemmerPatchTrieLoader.Language.valueOf(required(properties, "model.language", source)); } |
|
211
|
|
catch (IllegalArgumentException exception) { throw new StemmerModelIntegrityException("Invalid model.language at " + source, exception); } |
|
212
|
|
final String resource = required(properties, "model.resource", source); |
|
213
|
1
1. readDescriptor : negated conditional → KILLED
|
if (!resource.equals("org/egothor/stemmer/models/" + id + "/stemmer.gz")) throw new StemmerModelIntegrityException("Invalid model.resource for '" + id + "' at " + source); |
|
214
|
1
1. readDescriptor : negated conditional → KILLED
|
if (classLoader.getResource(resource) == null) throw new StemmerModelIntegrityException("Model resource is missing: " + resource + " declared at " + source); |
|
215
|
|
final String checksum = required(properties, "model.sha256", source); |
|
216
|
1
1. readDescriptor : negated conditional → KILLED
|
if (!checksum.matches("[0-9a-f]{64}")) throw new StemmerModelIntegrityException("Invalid model.sha256 at " + source); |
|
217
|
1
1. readDescriptor : replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::readDescriptor → KILLED
|
return new StemmerModelDescriptor(id, required(properties, "model.version", source), language, |
|
218
|
|
required(properties, "model.displayName", source), resource, |
|
219
|
|
Boolean.parseBoolean(required(properties, "model.default", source)), format, version, checksum, source, classLoader); |
|
220
|
|
} |
|
221
|
|
|
|
222
|
|
/** Returns a required nonblank property. */ |
|
223
|
|
private static String required(final Properties properties, final String key, final URL source) { |
|
224
|
|
final String value = properties.getProperty(key); |
|
225
|
2
1. required : negated conditional → KILLED
2. required : negated conditional → KILLED
|
if (value == null || value.isBlank()) throw new StemmerModelIntegrityException("Required property '" + key + "' is missing at " + source); |
|
226
|
1
1. required : replaced return value with "" for org/egothor/stemmer/StemmerModelRegistry::required → KILLED
|
return value.trim(); |
|
227
|
|
} |
|
228
|
|
} |
| | Mutations |
| 87 |
|
1.1 Location : fromContextClassLoader Killed by : none negated conditional → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:loadsDefaultPolishModel()]
- org.egothor.stemmer.benchmark.quality.LanguageUniverseTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.quality.LanguageUniverseTest]/[method:productionResourcesReconcile()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:rejectsInvalidExplicitModelIds()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldRepeatSmallDictionaryCorpusToTimingMinimum()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldKeepTokenAndExpectedRootArraysAligned()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldCreateChangedTokenTimingCorpus()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsExplicitModelId()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldReuseCachedCorpusInstances()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsDefaultPolishModel()]
2.2 Location : fromContextClassLoader Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::fromContextClassLoader → KILLED
|
| 104 |
|
1.1 Location : fromClassLoader Killed by : none removed call to java/util/List::sort → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:loadsDefaultPolishModel()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:reportsMissingModelFromIsolatedClassLoader()]
- org.egothor.stemmer.benchmark.quality.LanguageUniverseTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.quality.LanguageUniverseTest]/[method:productionResourcesReconcile()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversThroughExplicitClassLoader()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:rejectsInvalidExplicitModelIds()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldRepeatSmallDictionaryCorpusToTimingMinimum()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldKeepTokenAndExpectedRootArraysAligned()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldCreateChangedTokenTimingCorpus()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsExplicitModelId()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldReuseCachedCorpusInstances()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsDefaultPolishModel()]
2.2 Location : lambda$fromClassLoader$0 Killed by : none replaced int return with 0 for org/egothor/stemmer/StemmerModelRegistry::lambda$fromClassLoader$0 → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:loadsDefaultPolishModel()]
- org.egothor.stemmer.benchmark.quality.LanguageUniverseTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.quality.LanguageUniverseTest]/[method:productionResourcesReconcile()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversThroughExplicitClassLoader()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:rejectsInvalidExplicitModelIds()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldRepeatSmallDictionaryCorpusToTimingMinimum()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldKeepTokenAndExpectedRootArraysAligned()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldCreateChangedTokenTimingCorpus()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsExplicitModelId()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldReuseCachedCorpusInstances()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsDefaultPolishModel()]
|
| 107 |
|
1.1 Location : fromClassLoader Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] removed call to org/egothor/stemmer/StemmerModelRegistry::readIndex → KILLED
|
| 109 |
|
1.1 Location : fromClassLoader Killed by : none removed call to java/util/Collections::sort → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:loadsDefaultPolishModel()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:reportsMissingModelFromIsolatedClassLoader()]
- org.egothor.stemmer.benchmark.quality.LanguageUniverseTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.quality.LanguageUniverseTest]/[method:productionResourcesReconcile()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversThroughExplicitClassLoader()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:rejectsInvalidExplicitModelIds()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldRepeatSmallDictionaryCorpusToTimingMinimum()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldKeepTokenAndExpectedRootArraysAligned()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldCreateChangedTokenTimingCorpus()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsExplicitModelId()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldReuseCachedCorpusInstances()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsDefaultPolishModel()]
|
| 113 |
|
1.1 Location : fromClassLoader Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 118 |
|
1.1 Location : fromClassLoader Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::fromClassLoader → KILLED
|
| 122 |
|
1.1 Location : models Killed by : none replaced return value with Collections.emptyList for org/egothor/stemmer/StemmerModelRegistry::models → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversAndFiltersModels()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversThroughExplicitClassLoader()]
|
| 135 |
|
1.1 Location : require Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 139 |
|
1.1 Location : require Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::require → KILLED
|
| 151 |
|
1.1 Location : findByLanguage Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] replaced return value with Collections.emptyList for org/egothor/stemmer/StemmerModelRegistry::findByLanguage → KILLED
2.2 Location : lambda$findByLanguage$1 Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
3.3 Location : lambda$findByLanguage$1 Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] replaced boolean return with true for org/egothor/stemmer/StemmerModelRegistry::lambda$findByLanguage$1 → KILLED
|
| 166 |
|
1.1 Location : requireDefault Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
|
| 171 |
|
1.1 Location : requireDefault Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
|
| 175 |
|
1.1 Location : requireDefault Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::requireDefault → KILLED
|
| 184 |
|
1.1 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
|
| 185 |
|
1.1 Location : readIndex Killed by : none Changed increment from 1 to -1 → SURVIVED
Covering tests
Covered by tests:
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()]
- org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:loadsDefaultPolishModel()]
- org.egothor.stemmer.benchmark.quality.LanguageUniverseTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.quality.LanguageUniverseTest]/[method:productionResourcesReconcile()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:discoversThroughExplicitClassLoader()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:rejectsInvalidExplicitModelIds()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldRepeatSmallDictionaryCorpusToTimingMinimum()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldKeepTokenAndExpectedRootArraysAligned()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldCreateChangedTokenTimingCorpus()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsExplicitModelId()]
- org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.benchmark.LanguageBenchmarkCorpusTest]/[method:shouldReuseCachedCorpusInstances()]
- org.egothor.stemmer.StemmerModelDocumentationExamplesTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelDocumentationExamplesTest]/[method:loadsDefaultPolishModel()]
|
| 187 |
|
1.1 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
2.2 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
|
| 188 |
|
1.1 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 192 |
|
1.1 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 193 |
|
1.1 Location : readIndex Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:discoversModelsDeterministically()] negated conditional → KILLED
|
| 201 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] removed call to java/util/Properties::load → KILLED
|
| 203 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 208 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
2.2 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 213 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 214 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 216 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 217 |
|
1.1 Location : readDescriptor Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] replaced return value with null for org/egothor/stemmer/StemmerModelRegistry::readDescriptor → KILLED
|
| 225 |
|
1.1 Location : required Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
2.2 Location : required Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] negated conditional → KILLED
|
| 226 |
|
1.1 Location : required Killed by : org.egothor.stemmer.StemmerModelRegistryTest.[engine:junit-jupiter]/[class:org.egothor.stemmer.StemmerModelRegistryTest]/[method:rejectsMissingModel()] replaced return value with "" for org/egothor/stemmer/StemmerModelRegistry::required → KILLED
|