CredentialScanUnitSource.java

1
package org.egothor.methodatlas.command;
2
3
import java.io.IOException;
4
import java.io.UncheckedIOException;
5
import java.nio.charset.StandardCharsets;
6
import java.nio.file.FileSystems;
7
import java.nio.file.Files;
8
import java.nio.file.Path;
9
import java.nio.file.PathMatcher;
10
import java.util.ArrayList;
11
import java.util.List;
12
import java.util.logging.Level;
13
import java.util.logging.Logger;
14
import java.util.stream.Stream;
15
import org.egothor.methodatlas.api.CredentialScanUnit;
16
17
/**
18
 * Selects files to scan for credentials by mask and reads each into a
19
 * {@link CredentialScanUnit}. The default mask is the test-file suffix list; an
20
 * optional glob override widens the scan to arbitrary source.
21
 *
22
 * @since 4.1.0
23
 */
24
public final class CredentialScanUnitSource {
25
26
    private static final Logger LOG = Logger.getLogger(CredentialScanUnitSource.class.getName());
27
28
    private final List<String> suffixes;
29
    private final PathMatcher globMatcher;
30
31
    /**
32
     * Creates a source.
33
     *
34
     * @param suffixes test-file suffixes used when no glob override is given; never {@code null}
35
     * @param glob     optional glob (e.g. {@code "**}{@code /*.java"}); {@code null} uses {@code suffixes}
36
     */
37
    public CredentialScanUnitSource(List<String> suffixes, String glob) {
38
        this.suffixes = List.copyOf(suffixes);
39 2 1. <init> : removed conditional - replaced equality check with true → KILLED
2. <init> : removed conditional - replaced equality check with false → KILLED
        this.globMatcher = glob == null ? null
40
                : FileSystems.getDefault().getPathMatcher("glob:" + glob);
41
    }
42
43
    /**
44
     * Walks {@code roots} and returns one unit per matching, readable file, in
45
     * deterministic sorted order.
46
     *
47
     * @param roots scan roots; never {@code null}
48
     * @return scan units; never {@code null}
49
     */
50
    public List<CredentialScanUnit> collect(List<Path> roots) {
51
        List<CredentialScanUnit> units = new ArrayList<>();
52
        for (Path root : roots) {
53
            try (Stream<Path> walk = Files.walk(root)) {
54 2 1. lambda$collect$0 : replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::lambda$collect$0 → SURVIVED
2. lambda$collect$0 : replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::lambda$collect$0 → KILLED
                walk.filter(Files::isRegularFile)
55
                    .filter(this::matches)
56
                    .sorted()
57 2 1. collect : removed call to java/util/stream/Stream::forEach → KILLED
2. lambda$collect$1 : removed call to org/egothor/methodatlas/command/CredentialScanUnitSource::readInto → KILLED
                    .forEach(p -> readInto(p, units));
58
            } catch (IOException e) {
59
                throw new UncheckedIOException("Failed to walk " + root, e);
60
            }
61
        }
62 1 1. collect : replaced return value with Collections.emptyList for org/egothor/methodatlas/command/CredentialScanUnitSource::collect → KILLED
        return units;
63
    }
64
65
    private boolean matches(Path p) {
66 2 1. matches : removed conditional - replaced equality check with true → KILLED
2. matches : removed conditional - replaced equality check with false → KILLED
        if (globMatcher != null) {
67 2 1. matches : replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → SURVIVED
2. matches : replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED
            return globMatcher.matches(p);
68
        }
69
        String name = p.getFileName().toString();
70 2 1. matches : replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED
2. matches : replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED
        return suffixes.stream().anyMatch(name::endsWith);
71
    }
72
73
    private void readInto(Path p, List<CredentialScanUnit> units) {
74
        try {
75
            String source = Files.readString(p, StandardCharsets.UTF_8);
76
            units.add(new CredentialScanUnit(p.toAbsolutePath(), null, source, languageOf(p)));
77
        } catch (IOException e) {
78
            // Non-fatal: skip unreadable / binary files.
79
            LOG.log(Level.FINE, e, () -> "Skipping unreadable file: " + p);
80
        }
81
    }
82
83
    /**
84
     * Derives a short language identifier from a file's extension.
85
     *
86
     * @param p the file path; never {@code null}
87
     * @return the lowercase extension (without the dot), or {@code null} when the
88
     *         path has no file name or no extension
89
     */
90
    /* default */ static String languageOf(Path p) {
91
        Path fileName = p.getFileName();
92 2 1. languageOf : removed conditional - replaced equality check with false → SURVIVED
2. languageOf : removed conditional - replaced equality check with true → KILLED
        if (fileName == null) {
93 1 1. languageOf : replaced return value with "" for org/egothor/methodatlas/command/CredentialScanUnitSource::languageOf → NO_COVERAGE
            return null;
94
        }
95
        String name = fileName.toString();
96
        int dot = name.lastIndexOf('.');
97 5 1. languageOf : removed conditional - replaced comparison check with true → SURVIVED
2. languageOf : changed conditional boundary → SURVIVED
3. languageOf : removed conditional - replaced comparison check with false → KILLED
4. languageOf : replaced return value with "" for org/egothor/methodatlas/command/CredentialScanUnitSource::languageOf → KILLED
5. languageOf : Replaced integer addition with subtraction → KILLED
        return dot >= 0 ? name.substring(dot + 1) : null;
98
    }
99
}

Mutations

39

1.1
Location : <init>
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : <init>
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

54

1.1
Location : lambda$collect$0
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::lambda$collect$0 → KILLED

2.2
Location : lambda$collect$0
Killed by : none
replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::lambda$collect$0 → SURVIVED
Covering tests

57

1.1
Location : collect
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
removed call to java/util/stream/Stream::forEach → KILLED

2.2
Location : lambda$collect$1
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
removed call to org/egothor/methodatlas/command/CredentialScanUnitSource::readInto → KILLED

62

1.1
Location : collect
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
replaced return value with Collections.emptyList for org/egothor/methodatlas/command/CredentialScanUnitSource::collect → KILLED

66

1.1
Location : matches
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : matches
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
removed conditional - replaced equality check with false → KILLED

67

1.1
Location : matches
Killed by : none
replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → SURVIVED
Covering tests

2.2
Location : matches
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:globOverrideWidensScope(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED

70

1.1
Location : matches
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
replaced boolean return with false for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED

2.2
Location : matches
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
replaced boolean return with true for org/egothor/methodatlas/command/CredentialScanUnitSource::matches → KILLED

92

1.1
Location : languageOf
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
removed conditional - replaced equality check with true → KILLED

2.2
Location : languageOf
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

93

1.1
Location : languageOf
Killed by : none
replaced return value with "" for org/egothor/methodatlas/command/CredentialScanUnitSource::languageOf → NO_COVERAGE

97

1.1
Location : languageOf
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
removed conditional - replaced comparison check with false → KILLED

2.2
Location : languageOf
Killed by : none
removed conditional - replaced comparison check with true → SURVIVED
Covering tests

3.3
Location : languageOf
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
replaced return value with "" for org/egothor/methodatlas/command/CredentialScanUnitSource::languageOf → KILLED

4.4
Location : languageOf
Killed by : none
changed conditional boundary → SURVIVED Covering tests

5.5
Location : languageOf
Killed by : org.egothor.methodatlas.command.CredentialScanUnitSourceTest.[engine:junit-jupiter]/[class:org.egothor.methodatlas.command.CredentialScanUnitSourceTest]/[method:selectsFilesMatchingSuffixes(java.nio.file.Path)]
Replaced integer addition with subtraction → KILLED

Active mutators

Tests examined


Report generated by PIT 1.22.1