AbstractDecimalFormatter.java

1
/*
2
 * Copyright 2004 the original author or authors.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package com.ancientprogramming.fixedformat4j.format.impl;
17
18
import com.ancientprogramming.fixedformat4j.format.FormatInstructions;
19
import org.apache.commons.lang3.StringUtils;
20
import org.slf4j.Logger;
21
import org.slf4j.LoggerFactory;
22
23
import java.math.BigDecimal;
24
import java.math.RoundingMode;
25
import java.text.DecimalFormat;
26
27
/**
28
 * Base class for formatting decimal data
29
 *
30
 * @author Jacob von Eyben - <a href="https://eybenconsult.com">https://eybenconsult.com</a>
31
 * @since 1.0.0
32
 */
33
public abstract class AbstractDecimalFormatter<T extends Number> extends AbstractNumberFormatter<T> {
34
35
  private static final Logger LOG = LoggerFactory.getLogger(AbstractDecimalFormatter.class);
36
37
  /** {@inheritDoc} */
38
  public String asString(T obj, FormatInstructions instructions) {
39
    BigDecimal roundedValue = null;
40
    int decimals = instructions.getFixedFormatDecimalData().getDecimals();
41 1 1. asString : negated conditional → KILLED
    if (obj != null) {
42 1 1. asString : negated conditional → KILLED
      BigDecimal value = obj instanceof BigDecimal ? (BigDecimal)obj : BigDecimal.valueOf(obj.doubleValue());
43
44
      RoundingMode roundingMode = instructions.getFixedFormatDecimalData().getRoundingMode();
45
46
      roundedValue = value.setScale(decimals, roundingMode);
47
48
      if (LOG.isDebugEnabled()) {
49
        LOG.debug("Value before rounding = '{}', value after rounding = '{}', decimals = {}, rounding mode = {}", value, roundedValue, decimals, roundingMode);
50
      }
51
    }
52
       
53
    DecimalFormat formatter = new DecimalFormat();
54 1 1. asString : removed call to java/text/DecimalFormat::setDecimalSeparatorAlwaysShown → KILLED
    formatter.setDecimalSeparatorAlwaysShown(true);
55 1 1. asString : removed call to java/text/DecimalFormat::setMaximumFractionDigits → KILLED
    formatter.setMaximumFractionDigits(decimals);
56
57
    char decimalSeparator = formatter.getDecimalFormatSymbols().getDecimalSeparator();
58
    char groupingSeparator = formatter.getDecimalFormatSymbols().getGroupingSeparator();
59
    String zeroString = String.format("0%c0", decimalSeparator);
60
61 1 1. asString : negated conditional → KILLED
    String rawString = roundedValue != null ? formatter.format(roundedValue) : zeroString;
62
    if (LOG.isDebugEnabled()) {
63
      LOG.debug("rawString: {} - G[{}] D[{}]", rawString, groupingSeparator, decimalSeparator);
64
    }
65
    rawString = rawString.replaceAll("\\" + groupingSeparator, "");
66
    boolean useDecimalDelimiter = instructions.getFixedFormatDecimalData().isUseDecimalDelimiter();
67
68
    String beforeDelimiter = rawString.substring(0, rawString.indexOf(decimalSeparator));
69 1 1. asString : Replaced integer addition with subtraction → KILLED
    String afterDelimiter = rawString.substring(rawString.indexOf(decimalSeparator)+1, rawString.length());
70
    if (LOG.isDebugEnabled()) {
71
      LOG.debug("beforeDelimiter[{}], afterDelimiter[{}]", beforeDelimiter, afterDelimiter);
72
    }
73
74
    //trim decimals
75
    afterDelimiter = StringUtils.substring(afterDelimiter, 0, decimals);
76
    afterDelimiter = StringUtils.rightPad(afterDelimiter, decimals, '0');
77
78 1 1. asString : negated conditional → KILLED
    String delimiter = useDecimalDelimiter ? String.valueOf(instructions.getFixedFormatDecimalData().getDecimalDelimiter()) : "";
79
    String result = beforeDelimiter + delimiter + afterDelimiter;
80
    if (LOG.isDebugEnabled()) {
81
      LOG.debug("result[{}]", result);
82
    }
83 1 1. asString : replaced return value with "" for com/ancientprogramming/fixedformat4j/format/impl/AbstractDecimalFormatter::asString → KILLED
    return result;
84
  }
85
 
86
  protected String getStringToConvert(String string, FormatInstructions instructions) {
87
    String toConvert = string;
88
    boolean useDecimalDelimiter = instructions.getFixedFormatDecimalData().isUseDecimalDelimiter();
89 1 1. getStringToConvert : negated conditional → KILLED
    if (useDecimalDelimiter) {
90
      char delimiter = instructions.getFixedFormatDecimalData().getDecimalDelimiter();
91
      toConvert = toConvert.replace(String.valueOf(delimiter), ""); //
92
    }
93
    boolean applyNegativeSign = false;
94
    final Character negativeSignChar = instructions.getFixedFormatNumberData().getNegativeSign();
95 2 1. getStringToConvert : negated conditional → KILLED
2. getStringToConvert : negated conditional → KILLED
    if (negativeSignChar != null && toConvert.startsWith(negativeSignChar.toString())) {
96
      toConvert = toConvert.replaceFirst(negativeSignChar.toString(), "");
97
      applyNegativeSign = true;
98
    }
99
100
    int decimals = instructions.getFixedFormatDecimalData().getDecimals();
101
    final boolean theZeroString = toConvert.matches("^[0]+$");
102
    //only change the string to convert if data contains decimals AND is not the zero string
103 3 1. getStringToConvert : changed conditional boundary → SURVIVED
2. getStringToConvert : negated conditional → KILLED
3. getStringToConvert : negated conditional → KILLED
    if (decimals > 0 && !theZeroString) {
104
      //ensuring the string to convert is at least as long as the decimals length
105
      toConvert = StringUtils.leftPad(toConvert, decimals, "0");
106 1 1. getStringToConvert : Replaced integer subtraction with addition → KILLED
      String beforeDelimiter = toConvert.substring(0, toConvert.length()-decimals);
107 1 1. getStringToConvert : Replaced integer subtraction with addition → KILLED
      String afterDelimiter = toConvert.substring(toConvert.length()-decimals);
108
      toConvert = beforeDelimiter + '.' + afterDelimiter;
109
    }
110 1 1. getStringToConvert : negated conditional → KILLED
    if (applyNegativeSign) {
111
      toConvert = "-".concat(toConvert);
112
    }
113 1 1. getStringToConvert : replaced return value with "" for com/ancientprogramming/fixedformat4j/format/impl/AbstractDecimalFormatter::getStringToConvert → KILLED
    return toConvert;
114
  }
115
}

Mutations

41

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
negated conditional → KILLED

42

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
negated conditional → KILLED

54

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestBooleanNumberDecimalFormatting.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestBooleanNumberDecimalFormatting]/[test-template:formatsAndParsesBigDecimalWithDecimalData(int, boolean, char, java.math.RoundingMode, int, com.ancientprogramming.fixedformat4j.annotation.Align, char, java.math.BigDecimal, java.lang.String)]/[test-template-invocation:#4]
removed call to java/text/DecimalFormat::setDecimalSeparatorAlwaysShown → KILLED

55

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
removed call to java/text/DecimalFormat::setMaximumFractionDigits → KILLED

61

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
negated conditional → KILLED

69

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
Replaced integer addition with subtraction → KILLED

78

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
negated conditional → KILLED

83

1.1
Location : asString
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestDoubleFormatter]/[method:testFormatDoubleWith4DecimalsKeepAllDecimals()]
replaced return value with "" for com/ancientprogramming/fixedformat4j/format/impl/AbstractDecimalFormatter::asString → KILLED

89

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestFloatFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestFloatFormatter]/[method:testParse()]
negated conditional → KILLED

95

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
negated conditional → KILLED

2.2
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestBigDecimalFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestBigDecimalFormatter]/[method:testParse()]
negated conditional → KILLED

103

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
negated conditional → KILLED

2.2
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
negated conditional → KILLED

3.3
Location : getStringToConvert
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

106

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
Replaced integer subtraction with addition → KILLED

107

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
Replaced integer subtraction with addition → KILLED

110

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
negated conditional → KILLED

113

1.1
Location : getStringToConvert
Killed by : com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter.[engine:junit-jupiter]/[class:com.ancientprogramming.fixedformat4j.format.impl.TestByTypeFormatter]/[method:testDispatchesToDoubleFormatter()]
replaced return value with "" for com/ancientprogramming/fixedformat4j/format/impl/AbstractDecimalFormatter::getStringToConvert → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.1