]> gitweb.michael.orlitzky.com - dead/htsn-import.git/blobdiff - src/TSN/Parse.hs
Make the game_info schedule_id optional and add a test case for it.
[dead/htsn-import.git] / src / TSN / Parse.hs
index 9fe51259ddb518b46a83338fe55792226af7bbae..d707f5fd9575a4d2945f0285204145e0b44b5117 100644 (file)
@@ -113,6 +113,30 @@ parse_message_int child xmltree =
 
 
 
+-- | Parse an optional 'Int' from a direct descendent of the
+--   (top-level) \<message\> element in an XmlTree. This is just like
+--   'parse_message_int', except we expect the element/value to be
+--   missing sometimes.
+--
+--   To handle the fact that the element/value is optional, we pattern
+--   match on the 'ParseError' that comes back in case of failure. If
+--   we didn't find anything, we turn that into a \"successful
+--   nothing\". But if we find a value and it can't be parsed, we let
+--   the error propagate, because that shouldn't happen. Of course, if
+--   the parse worked, that's nice too: we wrap the parsed value in a
+--   'Just' and return that wrapped in a 'Right'
+--
+parse_message_int_optional :: String
+                           -> XmlTree
+                           -> Either ParseError (Maybe Int)
+parse_message_int_optional child xmltree =
+  case (parse_message_int child xmltree) of
+    Left (ParseNotFound _)     -> Right Nothing
+    Left pm@(ParseMismatch {}) -> Left pm
+    Right whatever             -> Right (Just whatever)
+
+
+
 -- | Extract the \"XML_File_ID\" element from a document. If we fail
 --   to parse an XML_File_ID, we return an appropriate 'ParseError'
 --   wrapped in a 'Left' constructor. The reason should be one of two
@@ -135,53 +159,21 @@ parse_xmlfid = parse_message_int "XML_File_ID"
 
 -- | Extract the \<game_id\> element from within the top-level
 --   \<message\> of a document. These appear in the "TSN.XML.GameInfo"
---   documents. Unlike the \<schedule_id\> and \<XML_File_ID\>
---   elements, the \<game_id\> can be missing from GameInfo
---   documents. So even the 'Right' value of the 'Either' can be
---   \"missing\". There are two reasons that the parse might fail.
---
---     1. No such elements were found. This is expected sometimes, and
---        should be returned as a 'Right' 'Nothing'.
---
---     2. An element was found, but it could not be read into an
---        'Int'. This is NOT expected, and will be returned as a
---        'ParseError', wrapped in a 'Left'.
---
---   Most of implementation for this ('parse_message_int') is shared,
---   but to handle the fact that game_id is optional, we pattern match
---   on the 'ParseError' that comes back in case of failure. If we
---   didn't find any game_id elements, we turn that into a
---   \"successful nothing\". But if we find a game_id and it can't be
---   parsed, we let the error propagate, because that shouldn't
---   happen. Of course, if the parse worked, that's nice too: we wrap
---   the parsed value in a 'Just' and return that wrapped in a 'Right'
+--   documents. Unlike the \<XML_File_ID\> elements, the \<game_id\>
+--   can be missing from GameInfo documents, so for our implementation
+--   we use 'parse_message_int_optional' instead.
 --
 parse_game_id :: XmlTree -> Either ParseError (Maybe Int)
-parse_game_id xml =
-  case (parse_message_int "game_id" xml) of
-    Left (ParseNotFound _)     -> Right Nothing
-    Left pm@(ParseMismatch {}) -> Left pm
-    Right whatever             -> Right (Just whatever)
+parse_game_id = parse_message_int_optional "game_id"
 
 
 
 -- | Extract the \<schedule_id\> element from within the top-level
---   \<message\> of a document.  These appear in the
---   "TSN.XML.GameInfo" documents. If we fail to parse a schedule_id,
---   we return the reason wrapped in an appropriate 'ParseError'. The reason
---   should be one of two things:
---
---     1. No such elements were found.
---
---     2. An element was found, but it could not be read
---        into an Int.
---
---   Both of these are truly errors in the case of schedule_id. The
---   implementation for this ('parse_message_int') is shared among a
---   few functions.
+--   \<message\> of a document. Identical to 'parse_game_id' except
+--   for the element name.
 --
-parse_schedule_id :: XmlTree -> Either ParseError Int
-parse_schedule_id = parse_message_int "schedule_id"
+parse_schedule_id :: XmlTree -> Either ParseError (Maybe Int)
+parse_schedule_id = parse_message_int_optional "schedule_id"
 
 
 
@@ -262,6 +254,7 @@ parse_tests =
     "TSN.Parse tests"
     [ test_parse_game_id,
       test_parse_missing_game_id,
+      test_parse_missing_schedule_id,
       test_parse_schedule_id,
       test_parse_xmlfid ]
   where
@@ -312,3 +305,15 @@ test_parse_missing_game_id =
     let actual = parse_game_id xmltree
     let expected = Right Nothing
     actual @?= expected
+
+
+-- | The schedule_id element can be missing, so we test that too.
+--
+test_parse_missing_schedule_id :: TestTree
+test_parse_missing_schedule_id =
+  testCase "missing schedule_id is not an error" $ do
+    let path = "test/xml/gameinfo/recapxml-no-game-schedule-ids.xml"
+    xmltree <- unsafe_read_document path
+    let actual = parse_schedule_id xmltree
+    let expected = Right Nothing
+    actual @?= expected