Range.java

1
package com.renomad.minum.web;
2
3
import java.util.List;
4
import java.util.Objects;
5
import java.util.regex.Matcher;
6
import java.util.regex.Pattern;
7
8
final class Range {
9
10
    private static final Pattern rangeHeaderPattern = Pattern.compile("^bytes=(?<first>[0-9]{0,13})-(?<second>[0-9]{0,13})$");
11
    private final Long rangeFirstPart;
12
    private final Long rangeSecondPart;
13
    private final Long length;
14
    private final Long offset;
15
    private final boolean hasRangeHeader;
16
17
    public Range(Headers requestHeaders, long fullLength) {
18
        List<String> rangeHeaders = requestHeaders.valueByKey("range");
19 1 1. <init> : negated conditional → KILLED
        if (rangeHeaders == null) {
20
            hasRangeHeader = false;
21
            rangeFirstPart = null;
22
            rangeSecondPart = null;
23
            length = fullLength;
24
            offset = 0L;
25
        } else {
26
            hasRangeHeader = true;
27 2 1. <init> : negated conditional → KILLED
2. <init> : changed conditional boundary → KILLED
            if (rangeHeaders.size() > 1) {
28
                throw new InvalidRangeException("Error: Request contained more than one Range header");
29
            }
30
            // the "Range:" header provides a desired range, and can request multiple ranges.
31
            // this server does not currently handle multiple ranges, so if that is requested we
32
            // will ignore the range header and return a 200 with the entire contents.
33
            Matcher matcher = rangeHeaderPattern.matcher(rangeHeaders.getFirst());
34 1 1. <init> : negated conditional → KILLED
            if (matcher.matches()) {
35
                String firstPart = matcher.group("first");
36
                String secondPart = matcher.group("second");
37
38 1 1. <init> : negated conditional → KILLED
                if (!firstPart.isEmpty()) {
39
                    rangeFirstPart = Long.parseLong(firstPart);
40
                } else {
41
                    rangeFirstPart = null;
42
                }
43
44 1 1. <init> : negated conditional → KILLED
                if (!secondPart.isEmpty()) {
45
                    rangeSecondPart = Long.parseLong(secondPart);
46
                } else {
47
                    rangeSecondPart = null;
48
                }
49
50
                // options
51
                // 1: there's a first and second part
52
                // 2: only a second part
53
                // 3: only a first part
54
                // 4: (invalid) the first part is larger than the second part
55
                // 5: (invalid) either of the range values are invalid longs
56 2 1. <init> : negated conditional → KILLED
2. <init> : negated conditional → KILLED
                if (rangeFirstPart != null && rangeSecondPart != null) {
57 2 1. <init> : changed conditional boundary → SURVIVED
2. <init> : negated conditional → KILLED
                    if (rangeFirstPart > rangeSecondPart) {
58
                        throw new InvalidRangeException("Error: The value of the first part of the range was larger than the second.");
59
                    } else {
60 2 1. <init> : Replaced long subtraction with addition → TIMED_OUT
2. <init> : Replaced long addition with subtraction → KILLED
                        length = (rangeSecondPart - rangeFirstPart) + 1;
61
                        offset = rangeFirstPart;
62
                    }
63 1 1. <init> : negated conditional → KILLED
                } else if (rangeFirstPart != null) {
64
                    offset = rangeFirstPart;
65 1 1. <init> : Replaced long subtraction with addition → KILLED
                    length = fullLength - offset;
66 1 1. <init> : negated conditional → KILLED
                } else if (rangeSecondPart != null) {
67 1 1. <init> : Replaced long subtraction with addition → KILLED
                    offset = fullLength - rangeSecondPart;
68
                    length = rangeSecondPart;
69
                } else {
70
                    length = fullLength;
71
                    offset = 0L;
72
                }
73
74
            } else {
75
                rangeFirstPart = null;
76
                rangeSecondPart = null;
77
                length = fullLength;
78
                offset = 0L;
79
            }
80
        }
81
    }
82
83
    public Long getRangeFirstPart() {
84 1 1. getRangeFirstPart : replaced Long return value with 0L for com/renomad/minum/web/Range::getRangeFirstPart → KILLED
        return rangeFirstPart;
85
    }
86
87
    public Long getRangeSecondPart() {
88 1 1. getRangeSecondPart : replaced Long return value with 0L for com/renomad/minum/web/Range::getRangeSecondPart → KILLED
        return rangeSecondPart;
89
    }
90
91
    public Long getLength() {
92 1 1. getLength : replaced Long return value with 0L for com/renomad/minum/web/Range::getLength → KILLED
        return length;
93
    }
94
95
    public Long getOffset() {
96 1 1. getOffset : replaced Long return value with 0L for com/renomad/minum/web/Range::getOffset → KILLED
        return offset;
97
    }
98
99
    public boolean hasRangeHeader() {
100 2 1. hasRangeHeader : replaced boolean return with true for com/renomad/minum/web/Range::hasRangeHeader → KILLED
2. hasRangeHeader : replaced boolean return with false for com/renomad/minum/web/Range::hasRangeHeader → KILLED
        return hasRangeHeader;
101
    }
102
103
    @Override
104
    public boolean equals(Object o) {
105 2 1. equals : negated conditional → TIMED_OUT
2. equals : replaced boolean return with false for com/renomad/minum/web/Range::equals → KILLED
        if (this == o) return true;
106 3 1. equals : replaced boolean return with true for com/renomad/minum/web/Range::equals → TIMED_OUT
2. equals : negated conditional → TIMED_OUT
3. equals : negated conditional → KILLED
        if (o == null || getClass() != o.getClass()) return false;
107
        Range range = (Range) o;
108 6 1. equals : negated conditional → TIMED_OUT
2. equals : negated conditional → TIMED_OUT
3. equals : negated conditional → TIMED_OUT
4. equals : replaced boolean return with true for com/renomad/minum/web/Range::equals → TIMED_OUT
5. equals : negated conditional → TIMED_OUT
6. equals : negated conditional → TIMED_OUT
        return hasRangeHeader == range.hasRangeHeader && Objects.equals(rangeFirstPart, range.rangeFirstPart) && Objects.equals(rangeSecondPart, range.rangeSecondPart) && Objects.equals(length, range.length) && Objects.equals(offset, range.offset);
109
    }
110
111
    @Override
112
    public int hashCode() {
113 1 1. hashCode : replaced int return with 0 for com/renomad/minum/web/Range::hashCode → TIMED_OUT
        return Objects.hash(rangeFirstPart, rangeSecondPart, length, offset, hasRangeHeader);
114
    }
115
116
    @Override
117
    public String toString() {
118 1 1. toString : replaced return value with "" for com/renomad/minum/web/Range::toString → KILLED
        return "Range{" +
119
                "rangeFirstPart=" + rangeFirstPart +
120
                ", rangeSecondPart=" + rangeSecondPart +
121
                ", length=" + length +
122
                ", offset=" + offset +
123
                ", hasRangeHeader=" + hasRangeHeader +
124
                '}';
125
    }
126
}

Mutations

19

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_MultipleRangeHeaders(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

27

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_MultipleRangeHeaders(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_InvalidPattern_tooLongLeft(com.renomad.minum.web.RangeTests)
changed conditional boundary → KILLED

34

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_InvalidPattern_tooLongLeft(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

38

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_FirstLarger(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

44

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_FirstLarger(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

56

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_FirstLarger(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

2.2
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_FirstLarger(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

57

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_FirstLarger(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

2.2
Location : <init>
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

60

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader(com.renomad.minum.web.RangeTests)
Replaced long addition with subtraction → KILLED

2.2
Location : <init>
Killed by : none
Replaced long subtraction with addition → TIMED_OUT

63

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_MissingBothParts(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

65

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_MissingSecondPart(com.renomad.minum.web.RangeTests)
Replaced long subtraction with addition → KILLED

66

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_MissingBothParts(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

67

1.1
Location : <init>
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_MissingFirstPart(com.renomad.minum.web.RangeTests)
Replaced long subtraction with addition → KILLED

84

1.1
Location : getRangeFirstPart
Killed by : com.renomad.minum.web.RangeTests.test_InvalidPattern_tooLongLeft(com.renomad.minum.web.RangeTests)
replaced Long return value with 0L for com/renomad/minum/web/Range::getRangeFirstPart → KILLED

88

1.1
Location : getRangeSecondPart
Killed by : com.renomad.minum.web.RangeTests.test_InvalidPattern_tooLongLeft(com.renomad.minum.web.RangeTests)
replaced Long return value with 0L for com/renomad/minum/web/Range::getRangeSecondPart → KILLED

92

1.1
Location : getLength
Killed by : com.renomad.minum.web.RangeTests.test_InvalidPattern_tooLongLeft(com.renomad.minum.web.RangeTests)
replaced Long return value with 0L for com/renomad/minum/web/Range::getLength → KILLED

96

1.1
Location : getOffset
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader_EdgeCase_MissingFirstPart(com.renomad.minum.web.RangeTests)
replaced Long return value with 0L for com/renomad/minum/web/Range::getOffset → KILLED

100

1.1
Location : hasRangeHeader
Killed by : com.renomad.minum.web.RangeTests.test_NoRange(com.renomad.minum.web.RangeTests)
replaced boolean return with true for com/renomad/minum/web/Range::hasRangeHeader → KILLED

2.2
Location : hasRangeHeader
Killed by : com.renomad.minum.web.RangeTests.test_DetermineLengthFromRangeHeader(com.renomad.minum.web.RangeTests)
replaced boolean return with false for com/renomad/minum/web/Range::hasRangeHeader → KILLED

105

1.1
Location : equals
Killed by : com.renomad.minum.web.RangeTests.testEquals(com.renomad.minum.web.RangeTests)
replaced boolean return with false for com/renomad/minum/web/Range::equals → KILLED

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

106

1.1
Location : equals
Killed by : none
replaced boolean return with true for com/renomad/minum/web/Range::equals → TIMED_OUT

2.2
Location : equals
Killed by : com.renomad.minum.web.RangeTests.testEquals(com.renomad.minum.web.RangeTests)
negated conditional → KILLED

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

108

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

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

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

4.4
Location : equals
Killed by : none
replaced boolean return with true for com/renomad/minum/web/Range::equals → TIMED_OUT

5.5
Location : equals
Killed by : none
negated conditional → TIMED_OUT

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

113

1.1
Location : hashCode
Killed by : none
replaced int return with 0 for com/renomad/minum/web/Range::hashCode → TIMED_OUT

118

1.1
Location : toString
Killed by : com.renomad.minum.web.RangeTests.test_NoRange(com.renomad.minum.web.RangeTests)
replaced return value with "" for com/renomad/minum/web/Range::toString → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0