Skip to content

Commit

Permalink
Fixed tests, added test coverage and some more refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
basiliskus committed Dec 20, 2024
1 parent d34f1ba commit 38556b6
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 115 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@ public HL7Segment getSegment(String name) throws HL7MessageException {

public String getValue(String path) throws HL7MessageException {
HL7Path hl7Path = HL7Parser.parsePath(path);
List<String> fields = getSegment(hl7Path.segmentName()).fields();
char[] segmentDelimiters = this.encoding.getOrderedDelimiters();
return HL7Parser.parseFieldValue(hl7Path, fields, segmentDelimiters);
return HL7Parser.parseMessageFieldValue(hl7Path, this);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,16 @@ public static HL7Message parseMessage(String content) {
return new HL7Message(segments, HL7Encoding.fromEncodingField(encodingCharactersField));
}

public static String parseFieldValue(HL7Path hl7Path, List<String> fields, char[] delimiters) {
public static String parseMessageFieldValue(HL7Path hl7Path, HL7Message message)
throws HL7MessageException {
if (hl7Path == null || hl7Path.indices().length == 0) {
return "";
}

int[] indices = hl7Path.indices();
List<String> fields = message.getSegment(hl7Path.segmentName()).fields();
char[] delimiters = message.getEncoding().getOrderedDelimiters();

if (fields == null || fields.isEmpty() || indices[0] > fields.size()) {
return "";
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package gov.hhs.cdc.trustedintermediary.rse2e.hl7

import spock.lang.Specification

class HL7EncodingTest extends Specification {

def "defaultEncoding should use expected default characters"() {
when:
def encodingChars = HL7Encoding.defaultEncoding()

then:
encodingChars.getFieldDelimiter() == '|' as char
encodingChars.getComponentDelimiter() == '^' as char
encodingChars.getRepetitionDelimiter() == '~' as char
encodingChars.getEscapeCharacter() == '\\' as char
encodingChars.getSubcomponentDelimiter() == '&' as char
}

def "fromEncodingField should use custom encoding characters when provided"() {
given:
def customEncodingChars = "@#+_"

when:
def encodingChars = HL7Encoding.fromEncodingField(customEncodingChars)

then:
encodingChars.getFieldDelimiter() == '|' as char
encodingChars.getComponentDelimiter() == '@' as char
encodingChars.getRepetitionDelimiter() == '#' as char
encodingChars.getEscapeCharacter() == '+' as char
encodingChars.getSubcomponentDelimiter() == '_' as char
}

def "fromEncodingField should use default characters when encoding characters passed is blank or null"() {
when:
def blankEncodingChars = HL7Encoding.fromEncodingField("")

then:
blankEncodingChars.getFieldDelimiter() == '|' as char
blankEncodingChars.getComponentDelimiter() == '^' as char
blankEncodingChars.getRepetitionDelimiter() == '~' as char
blankEncodingChars.getEscapeCharacter() == '\\' as char
blankEncodingChars.getSubcomponentDelimiter() == '&' as char

when:
def nullEncodingChars = HL7Encoding.fromEncodingField(null)

then:
nullEncodingChars.getFieldDelimiter() == '|' as char
nullEncodingChars.getComponentDelimiter() == '^' as char
nullEncodingChars.getRepetitionDelimiter() == '~' as char
nullEncodingChars.getEscapeCharacter() == '\\' as char
nullEncodingChars.getSubcomponentDelimiter() == '&' as char
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -253,16 +253,16 @@ PID|1||11102779^^^CR^MR||SMITH^BB SARAH^^^^^L"""
result == msh3
}

def "getLiteralOrFieldValue returns null when there's an exception getting the value"() {
def "getLiteralOrFieldValue throws exception when using invalid operand"() {
given:
def operand = "invalidField"
def inputMessage = Mock(HL7Message)

when:
def result = evaluator.getLiteralOrFieldValue(hl7Message, inputMessage, operand)
evaluator.getLiteralOrFieldValue(hl7Message, inputMessage, operand)

then:
result == null
thrown(HL7ParserException)
}

def "getFieldValue returns specified field value"() {
Expand All @@ -278,16 +278,16 @@ PID|1||11102779^^^CR^MR||SMITH^BB SARAH^^^^^L"""
result == msh3
}

def "getFieldValue returns null for non numeric field index"() {
def "getFieldValue throws exception for non numeric field index"() {
given:
def fieldName = "MSH-three"
def inputMessage = Mock(HL7Message)

when:
def result = evaluator.getFieldValue(hl7Message, inputMessage, fieldName)
evaluator.getFieldValue(hl7Message, inputMessage, fieldName)

then:
result == null
thrown(HL7ParserException)
}

def "getFieldValue throws exception for empty field name"() {
Expand All @@ -299,8 +299,7 @@ PID|1||11102779^^^CR^MR||SMITH^BB SARAH^^^^^L"""
evaluator.getFieldValue(hl7Message, inputMessage, fieldName)

then:
def e = thrown(HL7ParserException)
e.getMessage().contains("Invalid field name format")
thrown(HL7ParserException)
}

def "getMessageBySource should return input message when source is input"() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,6 @@ OBX|2|NM|||3122||||||F|||202402221854-0500||"""

def "getValue returns the expected value given the segment name and indices"() {
expect:
message.getValue("PID", 3) == message.getValue("PID-3")
message.getValue("PID", 3, 0) == message.getValue("PID-3.0")
message.getValue("PID", 40, 4, 1) == message.getValue("PID-40.4.1")
message.getValue("NK1", 33, 4, 1, 1) == message.getValue("NK1-33.4.1.1")
message.getValue("PID-3") == "1300974^^^Baptist East^MR"
message.getValue("PID-3.0") == ""
message.getValue("PID-3.1") == "1300974"
Expand All @@ -105,14 +101,15 @@ OBX|2|NM|||3122||||||F|||202402221854-0500||"""

def "getValue should throws an exception when the segment is not found"() {
when:
message.getValue("ZZZ", 1)
message.getValue("ZZZ-1")

then:
thrown(HL7MessageException)
}

// TODO: move to HL7EncodingTest
def "getEscapeCharacter should return the escape character"() {
expect:
message.getEscapeCharacter() == '\\' as char
message.getEncoding().getEscapeCharacter() == '\\' as char
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import spock.lang.Specification

class HL7ParserTest extends Specification {

def "parse should handle basic HL7 message"() {
def "parseMessage should handle basic HL7 message"() {
given:
def content = """MSH|^~\\&|sending_app|sending_facility
PID|||12345||Doe^John||19800101|M"""
Expand All @@ -26,7 +26,7 @@ PID|||12345||Doe^John||19800101|M"""
segments[1].fields().get(4) == "Doe^John"
}

def "parse should handle empty lines in message"() {
def "parseMessage should handle empty lines in message"() {
given:
def content = """MSH|^~\\&|sending_app
Expand All @@ -39,7 +39,7 @@ PID|||12345"""
result.getSegments().size() == 2
}

def "parse should preserve empty fields"() {
def "parseMessage should preserve empty fields"() {
given:
def content = "MSH|^~\\&|sending_app||sending_facility"

Expand All @@ -50,8 +50,11 @@ PID|||12345"""
result.getSegments().get(0).fields().get(3) == ""
}

def "parseFieldValue should handle different field levels"() {
def "parseMessageFieldValue should handle different field levels"() {
given:
def message = HL7Parser.parseMessage("""delimiters
"""
)
def fields = [
"value1",
"component1^component2",
Expand All @@ -61,138 +64,61 @@ PID|||12345"""
def delimiters = ['|', '^', '~', '&'] as char[]

when:
def result = HL7Parser.parseFieldValue(fields, delimiters, indices as int[])
def hl7Path = HL7Parser.parsePath(path)
def result = HL7Parser.parseMessageFieldValue(hl7Path, fields, delimiters)

then:
result == expectedValue

where:
scenario | indices | expectedValue
scenario | path | expectedValue
"simple field" | [1] | "value1"
"component" | [2, 2] | "component2"
"repetition" | [3, 1, 2] | "rep2"
"subcomponent" | [4, 2, 2, 2] | "sub2"
"invalid index" | [5] | ""
}

def "parseFieldValue returns an empty string when inputs are null"() {
def "parseMessageFieldValue returns an empty string when inputs are null"() {
when:
def result = HL7Parser.parseFieldValue(null, [] as char[], 1)
def result = HL7Parser.parseMessageFieldValue(null, null)

then:
result == ""
}

def "getEncodingCharacterMap should use defaults when no encoding characters provided"() {
when:
def encodingChars = HL7Parser.getEncodingCharacterMap(null)

then:
encodingChars["field"] == '|' as char
encodingChars["component"] == '^' as char
encodingChars["repetition"] == '~' as char
encodingChars["escape"] == '\\' as char
encodingChars["subcomponent"] == '&' as char
}

def "getEncodingCharacterMap should use default character when one is missing"() {
given:
def customEncodingChars = "_"

when:
def encodingChars = HL7Parser.getEncodingCharacterMap(customEncodingChars)

then:
encodingChars["field"] == '|' as char
encodingChars["component"] == '_' as char
encodingChars["repetition"] == '~' as char
encodingChars["escape"] == '\\' as char
encodingChars["subcomponent"] == '&' as char
}

def "getEncodingCharacterMap should use custom encoding characters when provided"() {
given:
def customEncodingChars = "@#+_"

when:
def result = HL7Parser.getEncodingCharacterMap(customEncodingChars)

then:
result["field"] == '|' as char
result["component"] == '@' as char
result["repetition"] == '#' as char
result["escape"] == '+' as char
result["subcomponent"] == '_' as char
}

def "parseFieldValue returns an empty string if a null list of fields is given"() {
def "parseMessageFieldValue returns an empty string if an empty message is given"() {
given:
def nullList = null
def delimiters = ['|']
def hl7Path = HL7Parser.parsePath("MSH-3")
def message = HL7Parser.parseMessage("")

when:
def out = HL7Parser.parseFieldValue(nullList, delimiters as char[])
def out = HL7Parser.parseMessageFieldValue(hl7Path, message)

then:
out == ""
}

def "parseFieldValue returns an empty string if an empty list of fields is given"() {
def "parseMessageFieldValue returns an empty string if an empty hl7 path is given"() {
given:
def emptyList = []
def delimiters = ['|']
def hl7Path = HL7Parser.parsePath("")

when:
def out = HL7Parser.parseFieldValue(emptyList, delimiters as char[])
def out = HL7Parser.parseMessageFieldValue(hl7Path, _ as HL7Message)

then:
out == ""
}

def "parseFieldValue returns an empty string if the indices are pointing outside the expected range"() {
def "parseMessageFieldValue returns an empty string if the indices in hl7 path are pointing outside the expected range"() {
given:
def emptyList = [
"MSH|fakeValues",
"OBR|fakeValues"
]
def delimiters = ['|']
def message = HL7Parser.parseMessage("MSH|fakeValues\nOBR|fakeValues")
def hl7Path = HL7Parser.parsePath("MSH-3")

when:
def out = HL7Parser.parseFieldValue(emptyList, delimiters as char[], 10, 20)
def out = HL7Parser.parseMessageFieldValue(hl7Path, message)

then:
out == ""
}

def "getEncodingCharacterMap uses default definitions when encoding characters are not available"() {
when:
def out = HL7Parser.getEncodingCharacterMap("tes")

then:
out.size() > 0
}

def "getEncodingCharacterMap uses default definitions if the encoding characters are blank"() {
when:
def out = HL7Parser.getEncodingCharacterMap(" ")

then:
out.size() > 0
}

def "getEncodingCharacterMap uses default definitions if the encoding characters are whitespace"() {
when:
def out = HL7Parser.getEncodingCharacterMap("")

then:
out.size() > 0
}

def "getEncodingCharacterMap uses default definitions if the encoding characters are null"() {
when:
def out = HL7Parser.getEncodingCharacterMap(null)

then:
out.size() > 0
}
}

0 comments on commit 38556b6

Please sign in to comment.