Utils.java

1
package com.github.dakusui.symfonion.utils;
2
3
import com.github.dakusui.symfonion.compat.exceptions.SymfonionException;
4
import com.github.valid8j.pcond.forms.Printables;
5
6
import java.io.*;
7
import java.util.Optional;
8
import java.util.concurrent.atomic.AtomicReference;
9
import java.util.function.BiFunction;
10
import java.util.function.Predicate;
11
import java.util.stream.Collector;
12
13
import static com.github.dakusui.symfonion.compat.exceptions.CompatExceptionThrower.*;
14
import static com.github.valid8j.classic.Requires.require;
15
import static com.github.valid8j.classic.Requires.requireNonNull;
16
import static com.github.valid8j.pcond.forms.Predicates.isNotNull;
17
import static java.nio.charset.StandardCharsets.UTF_8;
18
19
20
public enum Utils {
21
  ;
22
23
  /**
24
   * Count occurrences of a given character {@code ch} in a string {@code s}.
25
   *
26
   * @param ch A character to count its occurrences.
27
   * @param s  A string in which the number of {@code ch} should be counted.
28
   * @return The number of occurrences of {@code ch} in string {@code s}.
29
   */
30
  public static int count(char ch, String s) {
31
    int ret = 0;
32 3 1. count : negated conditional → TIMED_OUT
2. count : Replaced integer addition with subtraction → TIMED_OUT
3. count : changed conditional boundary → KILLED
    for (int i = s.indexOf(ch); i >= 0; i = s.indexOf(ch, i + 1)) {
33 1 1. count : Changed increment from 1 to -1 → KILLED
      ret++;
34
    }
35 1 1. count : replaced int return with 0 for com/github/dakusui/symfonion/utils/Utils::count → KILLED
    return ret;
36
  }
37
38
  public static String loadResource(String resourceName) throws SymfonionException {
39
    StringBuffer b = new StringBuffer(4096);
40
    try {
41
      InputStream is = new BufferedInputStream(require(ClassLoader.getSystemResourceAsStream(resourceName),
42
                                                       resourceIsNotNull(resourceName)));
43 1 1. loadResource : removed call to com/github/dakusui/symfonion/utils/Utils::loadFromInputStream → KILLED
      loadFromInputStream(b, is);
44
    } catch (IOException e) {
45
      throw loadResourceException(resourceName, e);
46
    }
47 1 1. loadResource : replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::loadResource → KILLED
    return b.toString();
48
  }
49
50
  public static String loadFile(String fileName) throws SymfonionException {
51
    StringBuffer b = new StringBuffer(4096);
52
    File         f = new File(fileName);
53
    try (InputStream is = new BufferedInputStream(new FileInputStream(f))) {
54 1 1. loadFile : removed call to com/github/dakusui/symfonion/utils/Utils::loadFromInputStream → KILLED
      loadFromInputStream(b, is);
55
    } catch (FileNotFoundException e) {
56
      throw fileNotFoundException(f, e);
57
    } catch (IOException e) {
58
      throw loadFileException(e);
59
    }
60 1 1. loadFile : replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::loadFile → KILLED
    return b.toString();
61
  }
62
63
  private static void loadFromInputStream(StringBuffer b, InputStream is) throws IOException {
64
    Reader r = new InputStreamReader(is, UTF_8);
65
    int    c;
66 1 1. loadFromInputStream : negated conditional → TIMED_OUT
    while ((c = r.read()) != -1) {
67
      b.append((char) c);
68
    }
69
  }
70
71
  record NoteLength(Fraction noteLength, double gateRatio) {
72
    NoteLength(Fraction noteLength, String articulation) {
73
      this(requireNonNull(noteLength),
74
           switch (articulation) {
75
             case "'" -> 0.5;
76
             case "^" -> 0.25;
77
             case "~" -> 1 / 0.8;
78
             default -> 1.0;
79
           });
80
    }
81
  }
82
83
  public static byte[] getIntBytes(int input) {
84
    byte[] ret = new byte[3];
85
86 2 1. getIntBytes : Replaced bitwise AND with OR → KILLED
2. getIntBytes : Replaced Shift Right with Shift Left → KILLED
    ret[0] = (byte) (input >> 16 & 0xff);
87 2 1. getIntBytes : Replaced bitwise AND with OR → KILLED
2. getIntBytes : Replaced Shift Right with Shift Left → KILLED
    ret[1] = (byte) (input >> 8 & 0xff);
88 1 1. getIntBytes : Replaced bitwise AND with OR → KILLED
    ret[2] = (byte) (input & 0xff);
89
90 1 1. getIntBytes : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::getIntBytes → KILLED
    return ret;
91
  }
92
93
  /**
94
   * This method was copied from <a href="https://stackoverflow.com/questions/22694884/filter-java-stream-to-1-and-only-1-element/22695424#22695424">stackoverflow.com</a> and renamed.
95
   *
96
   * @param <E> Type of the element to be collected.
97
   * @return A collector
98
   */
99
  public static <E> Collector<E, ?, Optional<E>> onlyElement() {
100 1 1. onlyElement : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::onlyElement → NO_COVERAGE
    return onlyElement((e1, e2) -> {
101
      throw new IllegalArgumentException("Multiple values are found in the stream: <" + e1 + "> and <" + e2 + ">");
102
    });
103
  }
104
105
106
  public static <E> Collector<E, AtomicReference<E>, Optional<E>> onlyElement(BiFunction<E, E, ? extends RuntimeException> multipleElements) {
107 1 1. onlyElement : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::onlyElement → KILLED
    return Collector.of(
108
        AtomicReference::new,
109
        (ref, e) -> {
110 1 1. lambda$onlyElement$1 : negated conditional → KILLED
          if (!ref.compareAndSet(null, e)) {
111
            throw multipleElements.apply(ref.get(), e);
112
          }
113
        },
114
        (ref1, ref2) -> {
115 1 1. lambda$onlyElement$2 : negated conditional → NO_COVERAGE
          if (ref1.get() == null) {
116 1 1. lambda$onlyElement$2 : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$2 → NO_COVERAGE
            return ref2;
117 1 1. lambda$onlyElement$2 : negated conditional → NO_COVERAGE
          } else if (ref2.get() != null) {
118
            throw multipleElements.apply(ref1.get(), ref2.get());
119
          } else {
120 1 1. lambda$onlyElement$2 : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$2 → NO_COVERAGE
            return ref1;
121
          }
122
        },
123 1 1. lambda$onlyElement$3 : replaced return value with Optional.empty for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$3 → KILLED
        ref -> Optional.ofNullable(ref.get()),
124
        Collector.Characteristics.UNORDERED);
125
  }
126
127
  private static Predicate<InputStream> resourceIsNotNull(String resourceName) {
128 2 1. lambda$resourceIsNotNull$4 : replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::lambda$resourceIsNotNull$4 → SURVIVED
2. resourceIsNotNull : replaced return value with null for com/github/dakusui/symfonion/utils/Utils::resourceIsNotNull → KILLED
    return Printables.predicate(() -> "isNotNull[resourceLoadedFrom[" + resourceName + "]]", isNotNull());
129
  }
130
131
}

Mutations

32

1.1
Location : count
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.song.GrooveTest]/[method:test_B04()]
changed conditional boundary → KILLED

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

3.3
Location : count
Killed by : none
Replaced integer addition with subtraction → TIMED_OUT

33

1.1
Location : count
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.song.GrooveTest]/[method:test_A04()]
Changed increment from 1 to -1 → KILLED

35

1.1
Location : count
Killed by : com.github.dakusui.symfonion.tests.song.GrooveTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.song.GrooveTest]/[method:test_B04()]
replaced int return with 0 for com/github/dakusui/symfonion/utils/Utils::count → KILLED

43

1.1
Location : loadResource
Killed by : com.github.dakusui.symfonion.tests.InvalidJsonErrorTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.InvalidJsonErrorTest]/[method:invalid_array()]
removed call to com/github/dakusui/symfonion/utils/Utils::loadFromInputStream → KILLED

47

1.1
Location : loadResource
Killed by : com.github.dakusui.symfonion.tests.InvalidJsonErrorTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.InvalidJsonErrorTest]/[method:invalid_array()]
replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::loadResource → KILLED

54

1.1
Location : loadFile
Killed by : com.github.dakusui.symfonion.tests.InvalidJsonErrorTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.InvalidJsonErrorTest]/[method:invalid_array()]
removed call to com/github/dakusui/symfonion/utils/Utils::loadFromInputStream → KILLED

60

1.1
Location : loadFile
Killed by : com.github.dakusui.symfonion.tests.InvalidJsonErrorTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.InvalidJsonErrorTest]/[method:invalid_array()]
replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::loadFile → KILLED

66

1.1
Location : loadFromInputStream
Killed by : none
negated conditional → TIMED_OUT

86

1.1
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
Replaced bitwise AND with OR → KILLED

2.2
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
Replaced Shift Right with Shift Left → KILLED

87

1.1
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
Replaced bitwise AND with OR → KILLED

2.2
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
Replaced Shift Right with Shift Left → KILLED

88

1.1
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
Replaced bitwise AND with OR → KILLED

90

1.1
Location : getIntBytes
Killed by : com.github.dakusui.symfonion.tests.core.UtilsTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.core.UtilsTest]/[method:test_intToByteArray()]
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::getIntBytes → KILLED

100

1.1
Location : onlyElement
Killed by : none
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::onlyElement → NO_COVERAGE

107

1.1
Location : onlyElement
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest]/[method:whenPatchBay_thenOutputLooksOk()]
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::onlyElement → KILLED

110

1.1
Location : lambda$onlyElement$1
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest]/[method:whenPatchBay_thenOutputLooksOk()]
negated conditional → KILLED

115

1.1
Location : lambda$onlyElement$2
Killed by : none
negated conditional → NO_COVERAGE

116

1.1
Location : lambda$onlyElement$2
Killed by : none
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$2 → NO_COVERAGE

117

1.1
Location : lambda$onlyElement$2
Killed by : none
negated conditional → NO_COVERAGE

120

1.1
Location : lambda$onlyElement$2
Killed by : none
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$2 → NO_COVERAGE

123

1.1
Location : lambda$onlyElement$3
Killed by : com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.cli.subcommands.PatchBayTest]/[method:whenPatchBay_thenOutputLooksOk()]
replaced return value with Optional.empty for com/github/dakusui/symfonion/utils/Utils::lambda$onlyElement$3 → KILLED

128

1.1
Location : lambda$resourceIsNotNull$4
Killed by : none
replaced return value with "" for com/github/dakusui/symfonion/utils/Utils::lambda$resourceIsNotNull$4 → SURVIVED
Covering tests

2.2
Location : resourceIsNotNull
Killed by : com.github.dakusui.symfonion.tests.MalformedTest.[engine:junit-jupiter]/[class:com.github.dakusui.symfonion.tests.MalformedTest]/[method:givenMalformed_emptyFile()]
replaced return value with null for com/github/dakusui/symfonion/utils/Utils::resourceIsNotNull → KILLED

Active mutators

Tests examined


Report generated by PIT 1.19.1