Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

pureconfig / pureconfig / 1633

1 Oct 2018 - 0:06 coverage decreased (-1.8%) to 87.347%
1633

Pull #415

travis-ci

9181eb84f9c35729a3bad740fb7f9d93?size=18&default=identiconweb-flow
Fix deprecation warning
Pull Request #415: Apply the same automatic type conversions HOCON allows at the cursor level

65 of 75 new or added lines in 7 files covered. (86.67%)

25 existing lines in 3 files now uncovered.

787 of 901 relevant lines covered (87.35%)

1.74 hits per line

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

75.0
/core/src/main/scala/pureconfig/error/FailureReason.scala
1
package pureconfig.error
2

3
import scala.annotation.tailrec
4
import scala.collection.mutable
5

6
import com.typesafe.config.{ ConfigRenderOptions, ConfigValue, ConfigValueType }
7

8
/**
9
 * A representation of a reason why a value failed to be converted.
10
 */
11
trait FailureReason {
12

13
  /**
14
   * A human-readable description of the failure.
15
   */
16
  def description: String
17
}
18

19
/**
20
 * A general reason given for the failure of a value to be converted to a desired type.
21
 *
22
 * @param value the value that was requested to be converted
23
 * @param toType the target type that the value was requested to be converted to
24
 * @param because the reason why the conversion was not possible
25
 */
26
final case class CannotConvert(value: String, toType: String, because: String) extends FailureReason {
UNCOV
27
  def description = s"Cannot convert '$value' to $toType: $because."
!
28
}
29

30
/**
31
 * A failure reason given when there is a collision of keys with different semantics. This error is raised when a key
32
 * that should be used to disambiguate a coproduct is mapped to a field in a product.
33
 *
34
 * @param key the colliding key
35
 * @param existingValue the value of the key
36
 */
37
final case class CollidingKeys(key: String, existingValue: ConfigValue) extends FailureReason {
38
  def description = s"Key with value '{$existingValue.render(ConfigRenderOptions.concise)}' collides with a key necessary to disambiguate a coproduct."
!
39
}
40

41
/**
42
 * A failure reason given when a key is missing from a `ConfigObject` or `ConfigList`.
43
 *
44
 * @param key the key that is missing
45
 * @param candidates a set of candidate keys that might correspond to the
46
 *                   desired key in case of a misconfigured ProductHint
47
 */
48
final case class KeyNotFound(key: String, candidates: Set[String] = Set()) extends FailureReason {
49
  def description = {
50
    if (candidates.nonEmpty) {
2×
51
      val descLines = mutable.ListBuffer[String]()
2×
52
      descLines += s"Key not found: '$key'. You might have a misconfigured ProductHint, since the following similar keys were found:"
2×
53
      candidates.foreach { candidate =>
2×
54
        descLines += s" - '$candidate'"
2×
55
      }
56
      descLines.mkString("\n")
2×
57
    } else {
58
      s"Key not found: '$key'."
2×
59
    }
60
  }
61
}
62

63
object KeyNotFound {
64
  @tailrec
65
  private[this] def isSubsequence(s1: String, s2: String): Boolean = {
66
    if (s1.isEmpty)
2×
67
      true
2×
68
    else if (s2.isEmpty)
2×
69
      false
2×
70
    else if (s1.head == s2.head)
2×
71
      isSubsequence(s1.tail, s2.tail)
2×
72
    else
73
      isSubsequence(s1, s2.tail)
2×
74
  }
75

76
  def forKeys(fieldName: String, keys: Iterable[String]): KeyNotFound = {
77
    val lcField = fieldName.toLowerCase.filter(c => c.isDigit || c.isLetter)
2×
78
    val objectKeys = keys.map(f => (f, f.toLowerCase))
2×
79
    val candidateKeys = objectKeys.filter(k => isSubsequence(lcField, k._2)).map(_._1).toSet
2×
80
    KeyNotFound(fieldName, candidateKeys)
2×
81
  }
82
}
83

84
/**
85
 * A failure reason given when an unknown key is found in a `ConfigObject`. The failure is raised when a key of a
86
 * `ConfigObject` is not mapped into a field of a given type and the `allowUnknownKeys` property of the `ProductHint`
87
 * for the type in question is `false`.
88
 *
89
 * @param key the unknown key
90
 */
91
final case class UnknownKey(key: String) extends FailureReason {
92
  def description = s"Unknown key."
!
93
}
94

95
/**
96
 * A failure reason given when a `ConfigValue` has the wrong type.
97
 *
98
 * @param foundType the `ConfigValueType` that was found
99
 * @param expectedTypes the `ConfigValueType`s that were expected
100
 */
101
final case class WrongType(foundType: ConfigValueType, expectedTypes: Set[ConfigValueType]) extends FailureReason {
102
  def description = s"""Expected type ${expectedTypes.mkString(" or ")}. Found $foundType instead."""
2×
103
}
104

105
/**
106
 * A failure reason given when an exception is thrown during a conversion.
107
 *
108
 * @param throwable the `Throwable` that was raised
109
 */
110
final case class ExceptionThrown(throwable: Throwable) extends FailureReason {
111
  def description = s"${throwable.getMessage}."
!
112
}
113

114
/**
115
 * A failure reason given when an unexpected empty string is found.
116
 *
117
 * @param typ the type that was attempted to be converted to from an empty string
118
 */
119
final case class EmptyStringFound(typ: String) extends FailureReason {
120
  def description = s"Empty string found when trying to convert to $typ."
!
121
}
122

123
/**
124
 * A failure reason given when an unexpected non-empty object is found. The failure happens when using
125
 * `EnumCoproductHint` to write a config.
126
 *
127
 * @param typ the type for which a non-empty object was attempted to be written
128
 */
129
final case class NonEmptyObjectFound(typ: String) extends FailureReason {
130
  def description = s"Non-empty object found when using EnumCoproductHint to write a $typ."
!
131
}
132

133
/**
134
 * A failure reason given when a list of an unexpected size is found when attempting to read into an `HList`.
135
 *
136
 * @param expected the expected number of elements
137
 * @param found the number of elements found
138
 */
139
final case class WrongSizeList(expected: Int, found: Int) extends FailureReason {
140
  def description = s"List of wrong size found. Expected $expected elements. Found $found elements instead."
2×
141
}
142

143
/**
144
 * A failure reason given when a string is not of the expected size.
145
 *
146
 * @param expected the expected number of characters
147
 * @param found the number of characters found
148
 */
149
final case class WrongSizeString(expected: Int, found: Int) extends FailureReason {
150
  def description = s"String of wrong size found. Expected $expected characters. Found $found characters instead."
!
151
}
152

153
/**
154
 * A failure reason given when a valid choice for a coproduct cannot be found.
155
 *
156
 * @param value the ConfigValue that was unable to be mapped to a coproduct choice
157
 */
158
final case class NoValidCoproductChoiceFound(value: ConfigValue) extends FailureReason {
159
  def description = s"No valid coproduct choice found for '${value.render(ConfigRenderOptions.concise())}'."
2×
160
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2021 Coveralls, LLC