• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ljacqu / wordeval / 14890732001

07 May 2025 06:33PM UTC coverage: 60.614% (-0.8%) from 61.437%
14890732001

push

github

ljacqu
Fix line processor tests not to depend on the dictionary files

392 of 702 branches covered (55.84%)

0 of 2 new or added lines in 1 file covered. (0.0%)

26 existing lines in 5 files now uncovered.

968 of 1597 relevant lines covered (60.61%)

3.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

87.18
/src/main/java/ch/jalu/wordeval/dictionary/hunspell/HunspellUnmuncherService.java
1
package ch.jalu.wordeval.dictionary.hunspell;
2

3
import ch.jalu.wordeval.dictionary.hunspell.lineprocessor.RootAndAffixes;
4
import com.google.common.base.Preconditions;
5
import org.springframework.stereotype.Service;
6

7
import java.util.List;
8
import java.util.function.Function;
9
import java.util.stream.Stream;
10

11
/**
12
 * Service to "unmunch" words (i.e. expand) based on Hunspell affix rules.
13
 */
14
@Service
15
public class HunspellUnmuncherService {
3✔
16

17
  /**
18
   * Processes the given word and expands it based on the specified affix rules.
19
   *
20
   * @param rootAndAffixes the word and affix flags to apply
21
   * @param affixDefinition the dictionary's affix definitions
22
   * @return all words isolated and expanded
23
   */
24
  public Stream<String> unmunch(RootAndAffixes rootAndAffixes, HunspellAffixes affixDefinition) {
25
    String root = rootAndAffixes.root();
3✔
26
    List<String> affixFlags = affixDefinition.getFlagType().split(rootAndAffixes.affixFlags());
6✔
27

28
    // Slashes can be escaped with a backslash apparently (nl.dic), but this currently goes beyond the desired scope,
29
    // since a word with a slash won't be interesting to wordeval anyway. So it's the job of a line processor to skip
30
    // these words before they're passed to this class.
31
    Preconditions.checkArgument(root.indexOf('\\') < 0, rootAndAffixes);
8!
32

33
    if (affixDefinition.getForbiddenWordClass() != null
5✔
34
        && affixFlags.contains(affixDefinition.getForbiddenWordClass())) {
3✔
35
      return Stream.empty();
2✔
36
    }
37

38
    boolean includeRoot = affixDefinition.getNeedAffixFlag() == null
5✔
39
        || !affixFlags.contains(affixDefinition.getNeedAffixFlag());
7!
40
    if (includeRoot) {
2✔
41
      return Stream.concat(Stream.of(root), streamThroughAllAffixes(root, affixFlags, affixDefinition));
9✔
42
    }
43
    return streamThroughAllAffixes(root, affixFlags, affixDefinition);
6✔
44
  }
45

46
  private Stream<String> streamThroughAllAffixes(String baseWord, List<String> affixFlags,
47
                                                 HunspellAffixes affixDefinition) {
48
    return affixFlags.stream()
6✔
49
        .flatMap(affixFlag -> affixDefinition.streamThroughMatchingRules(baseWord, affixFlag))
11✔
50
        .flatMap(affixRule -> {
1✔
51
          String wordWithAffix = affixRule.applyRule(baseWord);
4✔
52
          if (wordWithAffix == null) {
2✔
53
            return Stream.empty();
2✔
54
          }
55

56
          boolean hasContinuationClasses = !affixRule.getContinuationClasses().isEmpty();
8✔
57
          boolean isCrossProductPrefix = affixRule.getType() == AffixType.PFX && affixRule.isCrossProduct();
11!
58
          if (hasContinuationClasses && isCrossProductPrefix) {
4!
UNCOV
59
            return Stream.of(
×
UNCOV
60
                    Stream.of(wordWithAffix),
×
UNCOV
61
                    streamThroughAllAffixes(wordWithAffix, affixRule.getContinuationClasses(), affixDefinition),
×
UNCOV
62
                    addSuffixes(wordWithAffix, affixFlags, affixDefinition))
×
UNCOV
63
                .flatMap(Function.identity());
×
64
          } else if (hasContinuationClasses) {
2✔
65
            return Stream.concat(
3✔
66
                    Stream.of(wordWithAffix),
4✔
67
                    streamThroughAllAffixes(wordWithAffix, affixRule.getContinuationClasses(), affixDefinition));
3✔
68
          } else if (isCrossProductPrefix) {
2✔
69
            return Stream.concat(
3✔
70
                    Stream.of(wordWithAffix),
4✔
71
                    addSuffixes(wordWithAffix, affixFlags, affixDefinition));
1✔
72
          } else {
73
            return Stream.of(wordWithAffix);
3✔
74
          }
75
        });
76
  }
77

78
  private static Stream<String> addSuffixes(String word,
79
                                            List<String> affixFlags,
80
                                            HunspellAffixes affixDefinition) {
81
    return affixFlags.stream()
5✔
82
        .flatMap(affixFlag -> affixDefinition.getAffixRulesByFlag().get(affixFlag).stream())
9✔
83
        .filter(rule -> rule.getType() == AffixType.SFX && rule.isCrossProduct() && rule.matches(word))
18✔
84
        .map(rule -> rule.applyRule(word));
5✔
85
  }
86
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc