I'm trying to avoid strings being passed around as a valid value. The ability to make a mistake is too high for my taste and the solution that I've come up with is to use an Enum. This provides the benefit of intellisense when trying to use the values. Similar to typing sheet1.Visible = which gives the valid options a worksheet property with its type declared As SimpleSpanBracing allows the valid values be chosen. Now when I need to use something or to Get or Let a value I use the converter to ensure that I'm not going to mistakenly mix up casing, ends only or midspan, and accidentally get a false positive/negative.
Is there anything that I'm missing or haven't guarded against?
Enumeration with valid options. notSet is an option because I don't want to assume the default value. I'd prefer to see what's causing the issue and how it came about.
Public Enum SimpleSpanBracing
notSet
endsonly
midspan
thirdspan
End Enum
SpanBracingConverter Class that does the actual converting. I'm not concerned with getting a value that hasn't been set, but setting it to an invalid issues will cause an error to be raised, avoiding a false positive/negative mentioned above.
Private Const spanEnd As String = "ENDS ONLY"
Private Const spanMid As String = "MIDSPAN"
Private Const spanThird As String = "1/3 SPAN"
Private Const INVALID_INPUT As Long = 5
Public Function ToString(ByVal value As SimpleSpanBracing) As String
If value = endsonly Then
ToString = spanEnd
ElseIf value = midspan Then
ToString = spanMid
ElseIf value = thirdspan Then
ToString = spanThird
Else
Err.Raise INVALID_INPUT, "SpanBracingConverter.ToString()", "Invalid input supplied"
End If
End Function
Public Function ToEnum(ByVal value As String) As SimpleSpanBracing
value = UCase$(value)
If value = spanEnd Then
ToEnum = endsonly
ElseIf value = spanMid Then
ToEnum = midspan
ElseIf value = spanThird Then
ToEnum = thirdspan
Else
Err.Raise INVALID_INPUT, "SpanBracingConverter.ToEnum()", "Invalid input supplied"
End If
End Function
Public Function ValidateString(ByVal value As String) As String
ValidateString = ToString(ToEnum(value))
End Function
What follows are the unit tests I've created with Rubberduck to test this converter.
'@TestMethod
Public Sub ValidInputs()
On Error GoTo TestFail
'Arrange:
Dim sut As SpanBracingConverter
Set sut = New SpanBracingConverter
'Act:
Dim lowerEnd As SimpleSpanBracing
lowerEnd = sut.ToEnum("ends only")
Dim upperEnd As SimpleSpanBracing
upperEnd = sut.ToEnum("ENDS ONLY")
Dim lowerMid As SimpleSpanBracing
lowerMid = sut.ToEnum("midspan")
Dim upperMid As SimpleSpanBracing
upperMid = sut.ToEnum("MIDSPAN")
Dim lowerThird As SimpleSpanBracing
lowerThird = sut.ToEnum("1/3 span")
Dim upperThird As SimpleSpanBracing
upperThird = sut.ToEnum("1/3 SPAN")
Dim endInput As String
endInput = sut.ToString(endsonly)
Dim midInput As String
midInput = sut.ToString(midspan)
Dim thirdInput As String
thirdInput = sut.ToString(thirdspan)
'Assert:
Assert.areequal SimpleSpanBracing.endsonly, lowerEnd
Assert.areequal SimpleSpanBracing.endsonly, upperEnd
Assert.areequal SimpleSpanBracing.midspan, lowerMid
Assert.areequal SimpleSpanBracing.midspan, upperMid
Assert.areequal SimpleSpanBracing.thirdspan, lowerThird
Assert.areequal SimpleSpanBracing.thirdspan, upperThird
Assert.areequal "ENDS ONLY", endInput
Assert.areequal "MIDSPAN", midInput
Assert.areequal "1/3 SPAN", thirdInput
TestExit:
Exit Sub
TestFail:
Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
End Sub
'@TestMethod
Public Sub InvalidStringInput()
Const ExpectedError As Long = 5
On Error GoTo TestFail
'Arrange:
'Act:
With New SpanBracingConverter
.ToEnum "fail"
End With
Assert:
Assert.Fail "Expected error was not raised."
TestExit:
Exit Sub
TestFail:
If Err.Number = ExpectedError Then
Resume TestExit
Else
Resume Assert
End If
End Sub
'@TestMethod
Public Sub UnsetEnumValue()
Const ExpectedError As Long = 5
On Error GoTo TestFail
'Arrange:
'Act:
With New SpanBracingConverter
.ToString SimpleSpanBracing.notSet
End With
TestExit:
Exit Sub
TestFail:
If Err.Number = ExpectedError Then
Resume TestExit
Else
Assert.Fail "Expected error was not raised."
End If
End Sub
'@TestMethod
Public Sub LargestAssignedEnumValue()
Const ExpectedError As Long = 5
On Error GoTo TestFail
'Arrange:
'Act:
With New SpanBracingConverter
.ToString 4
End With
Assert:
Assert.Fail "Expected error was not raised."
TestExit:
Exit Sub
TestFail:
If Err.Number = ExpectedError Then
Resume TestExit
Else
Assert.Fail "Expected error was not raised."
End If
End Sub
'@TestMethod
Public Sub InputMatchesOutputCaseInsensitive()
On Error GoTo TestFail
'Arrange:
'Act:
'Assert:
With New SpanBracingConverter
Assert.areequal "ENDS ONLY", .ValidateString("ENDS ONLY")
Assert.areequal "ENDS ONLY", .ValidateString("ends only")
Assert.areequal "MIDSPAN", .ValidateString("MIDSPAN")
Assert.areequal "MIDSPAN", .ValidateString("midspan")
Assert.areequal "1/3 SPAN", .ValidateString("1/3 SPAN")
Assert.areequal "1/3 SPAN", .ValidateString("1/3 span")
End With
TestExit:
Exit Sub
TestFail:
Assert.Fail "Test raised an error: #" & Err.Number & " - " & Err.Description
End Sub
Edit: My followup question, Part 2 continues my work on the converter class.