From d704da7e4e1428ae4ae828e3e726c75d493914c1 Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 16:33:48 +0300 Subject: [PATCH 1/6] Add Fb2Reader --- HomeLibProt.Common/Fb2Reader.fs | 275 +++++++++++++++++++ HomeLibProt.Common/HomeLibProt.Common.fsproj | 1 + 2 files changed, 276 insertions(+) create mode 100644 HomeLibProt.Common/Fb2Reader.fs diff --git a/HomeLibProt.Common/Fb2Reader.fs b/HomeLibProt.Common/Fb2Reader.fs new file mode 100644 index 0000000..fd6628d --- /dev/null +++ b/HomeLibProt.Common/Fb2Reader.fs @@ -0,0 +1,275 @@ +module HomeLibProt.Common.Fb2Reader + +open System +open System.IO +open System.Xml +open System.Xml.XPath + +type Fb2Attributes = + { Annotation: string option + Coverpage: string option } + +type AuthorName = + { First: string + Middle: string + Last: string } + +type Series = { Name: string; Number: string } + +type Fb2Info = + { Authors: AuthorName array + Genres: string array + Title: string + Language: string + Keywords: string array + Series: Series array } + +let private authorsXpath = "/fb:FictionBook/fb:description/fb:title-info/fb:author" + +let private genresXpath = "/fb:FictionBook/fb:description/fb:title-info/fb:genre" + +let private titleXpath = + "/fb:FictionBook/fb:description/fb:title-info/fb:book-title" + +let private langXpath = "/fb:FictionBook/fb:description/fb:title-info/fb:lang" + +let private keywordsXpath = + "/fb:FictionBook/fb:description/fb:title-info/fb:keywords" + +let private seriesXpath = "/fb:FictionBook/fb:description/fb:title-info/fb:sequence" + +let private annotationXpath = + "/fb:FictionBook/fb:description/fb:title-info/fb:annotation" + +let private coverpageLinkXpath = + "/fb:FictionBook/fb:description/fb:title-info/fb:coverpage/fb:image" + +let private makeKeywords (keywords: string) : string array = + keywords.Split(',', StringSplitOptions.RemoveEmptyEntries ||| StringSplitOptions.TrimEntries) + +let private tryToRemoveNamespace (value: string option) : string option = + match value with + | Some v -> + v.Replace(" xmlns=\"http://www.gribuser.ru/xml/fictionbook/2.0\"", String.Empty) + |> Some + | None -> None + +let private tryToReplaceIdSing (id: string option) : string option = + match id with + | Some i -> i.Replace("#", String.Empty) |> Some + | None -> None + +let private tryToGetCoverpageXpath (id: string option) : string option = + match id with + | Some i -> Some $"/fb:FictionBook/fb:binary[@id='{i}']" + | None -> None + +let private tryToSelectValue (navigator: XPathNavigator option) : string option = + match navigator with + | Some n -> Some n.Value + | None -> None + +let private tryToSelectInnerXml (navigator: XPathNavigator option) : string option = + match navigator with + | Some n -> Some n.InnerXml + | None -> None + +let private tryToSelectSingleNode + (navigator: XPathNavigator) + (namespaceManager: XmlNamespaceManager) + (xpath: string) + : XPathNavigator option = + match navigator.SelectSingleNode(xpath, namespaceManager) with + | null -> None + | xPathNavigator -> Some xPathNavigator + +let private tryToGetValue (navigator: XPathNavigator option) : string = + match navigator with + | Some n -> n.Value + | None -> String.Empty + +let private tryToSelect + (navigator: XPathNavigator) + (namespaceManager: XmlNamespaceManager) + (xpath: string) + : XPathNodeIterator option = + match navigator.Select(xpath, namespaceManager) with + | null -> None + | iterator -> Some iterator + +let private tryToSelectAttributeNode + (xpath: string) + (namespaceManager: XmlNamespaceManager) + (navigator: XPathNavigator option) + : XPathNavigator option = + match navigator with + | Some n -> xpath |> tryToSelectSingleNode n namespaceManager + | None -> None + +let private tryToSelectSeries + (namespaceManager: XmlNamespaceManager) + (iterator: XPathNodeIterator option) + : Series seq option = + match iterator with + | Some i -> + seq { + while i.MoveNext() do + let name = + tryToSelectAttributeNode "@name" namespaceManager (Some i.Current) + |> tryToSelectValue + |> Option.defaultValue String.Empty + + let number = + tryToSelectAttributeNode "@number" namespaceManager (Some i.Current) + |> tryToSelectValue + |> Option.defaultValue String.Empty + + yield { Name = name; Number = number } + } + |> Some + | None -> None + +let private tryToSelectKeywords (iterator: XPathNodeIterator option) : string seq option = + match iterator with + | Some i -> + seq { + while i.MoveNext() do + yield $"{i.Current}" + } + |> Some + | None -> None + +let private tryToSelectGenres (iterator: XPathNodeIterator option) : string seq option = + match iterator with + | Some i -> + seq { + while i.MoveNext() do + yield $"{i.Current}" + } + |> Some + | None -> None + +let private tryToSelectAuthors + (namespaceManager: XmlNamespaceManager) + (iterator: XPathNodeIterator option) + : AuthorName seq option = + match iterator with + | Some i -> + seq { + while i.MoveNext() do + let firstName = + "fb:first-name" + |> tryToSelectSingleNode i.Current namespaceManager + |> tryToGetValue + + let middleName = + "fb:middle-name" + |> tryToSelectSingleNode i.Current namespaceManager + |> tryToGetValue + + let lastName = + "fb:last-name" + |> tryToSelectSingleNode i.Current namespaceManager + |> tryToGetValue + + yield + { First = firstName + Middle = middleName + Last = lastName } + } + |> Some + | None -> None + +let private tryToGetCoverpageNode + (navigator: XPathNavigator) + (namespaceManager: XmlNamespaceManager) + (xpath: string option) + : XPathNavigator option = + match xpath with + | Some x -> x |> tryToSelectSingleNode navigator namespaceManager + | None -> None + +let private readFb2 (fb2: Stream) (action: XPathNavigator -> XmlNamespaceManager -> 'T) : 'T option = + try + let doc = new XPathDocument(fb2) + + let navigator = doc.CreateNavigator() + + let namespaceManager = new XmlNamespaceManager(navigator.NameTable) + namespaceManager.AddNamespace("fb", "http://www.gribuser.ru/xml/fictionbook/2.0") + namespaceManager.AddNamespace("l", "http://www.w3.org/1999/xlink") + + action navigator namespaceManager |> Some + with :? XmlException -> + None + +let getFb2Attributes (fb2: Stream) : Fb2Attributes option = + readFb2 fb2 (fun navigator namespaceManager -> + let annotation = + annotationXpath + |> tryToSelectSingleNode navigator namespaceManager + |> tryToSelectInnerXml + |> tryToRemoveNamespace + + let coverpage = + coverpageLinkXpath + |> tryToSelectSingleNode navigator namespaceManager + |> tryToSelectAttributeNode "@l:href" namespaceManager + |> tryToSelectValue + |> tryToReplaceIdSing + |> tryToGetCoverpageXpath + |> tryToGetCoverpageNode navigator namespaceManager + |> tryToSelectValue + + { Annotation = annotation + Coverpage = coverpage }) + +let getFb2Info (fb2: Stream) : Fb2Info option = + readFb2 fb2 (fun navigator namespaceManager -> + let authors = + authorsXpath + |> tryToSelect navigator namespaceManager + |> tryToSelectAuthors namespaceManager + |> Option.defaultValue Seq.empty + |> Seq.toArray + + let genres = + genresXpath + |> tryToSelect navigator namespaceManager + |> tryToSelectGenres + |> Option.defaultValue Seq.empty + |> Seq.toArray + + let title = + titleXpath |> tryToSelectSingleNode navigator namespaceManager |> tryToGetValue + + let language = + langXpath |> tryToSelectSingleNode navigator namespaceManager |> tryToGetValue + + let keywords = + keywordsXpath + |> tryToSelect navigator namespaceManager + |> tryToSelectKeywords + |> Option.defaultValue Seq.empty + |> Seq.collect makeKeywords + |> Seq.toArray + + let series = + seriesXpath + |> tryToSelect navigator namespaceManager + |> tryToSelectSeries namespaceManager + |> Option.defaultValue ( + seq { + yield + { Name = String.Empty + Number = String.Empty } + } + ) + |> Seq.toArray + + { Authors = authors + Genres = genres + Title = title + Language = language + Keywords = keywords + Series = series }) diff --git a/HomeLibProt.Common/HomeLibProt.Common.fsproj b/HomeLibProt.Common/HomeLibProt.Common.fsproj index cf8ecda..907ae9b 100644 --- a/HomeLibProt.Common/HomeLibProt.Common.fsproj +++ b/HomeLibProt.Common/HomeLibProt.Common.fsproj @@ -7,6 +7,7 @@ + From d446de84806689ecb6521570b83c7649e4f0bd91 Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 16:36:22 +0300 Subject: [PATCH 2/6] Add HomeLibProt.Common.Tests --- .../HomeLibProt.Common.Tests.fsproj | 34 +++++++++++++++++++ HomeLibProt.Common.Tests/Program.fs | 4 +++ HomeLibProt.sln | 14 ++++++++ 3 files changed, 52 insertions(+) create mode 100644 HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj create mode 100644 HomeLibProt.Common.Tests/Program.fs diff --git a/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj new file mode 100644 index 0000000..c362547 --- /dev/null +++ b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj @@ -0,0 +1,34 @@ + + + + net8.0 + + false + false + true + + + + + + + + + + + + + + + + + + + + + + Always + + + + diff --git a/HomeLibProt.Common.Tests/Program.fs b/HomeLibProt.Common.Tests/Program.fs new file mode 100644 index 0000000..176a7b6 --- /dev/null +++ b/HomeLibProt.Common.Tests/Program.fs @@ -0,0 +1,4 @@ +module Program = + + [] + let main _ = 0 diff --git a/HomeLibProt.sln b/HomeLibProt.sln index 47510a9..6df8d78 100644 --- a/HomeLibProt.sln +++ b/HomeLibProt.sln @@ -17,6 +17,8 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "HomeLibProt.CollectionManag EndProject Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "HomeLibProt.Common", "HomeLibProt.Common\HomeLibProt.Common.fsproj", "{E10E492A-144A-4DFA-A99C-583A92EA4CA6}" EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "HomeLibProt.Common.Tests", "HomeLibProt.Common.Tests\HomeLibProt.Common.Tests.fsproj", "{E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -111,6 +113,18 @@ Global {E10E492A-144A-4DFA-A99C-583A92EA4CA6}.Release|x64.Build.0 = Release|Any CPU {E10E492A-144A-4DFA-A99C-583A92EA4CA6}.Release|x86.ActiveCfg = Release|Any CPU {E10E492A-144A-4DFA-A99C-583A92EA4CA6}.Release|x86.Build.0 = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|x64.ActiveCfg = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|x64.Build.0 = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|x86.ActiveCfg = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Debug|x86.Build.0 = Debug|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|Any CPU.Build.0 = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|x64.ActiveCfg = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|x64.Build.0 = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|x86.ActiveCfg = Release|Any CPU + {E7C4DE15-A3C1-4DED-B569-10C14FEB3E99}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 36cba61bef4c458a8911644cddff44397d1fc006 Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 16:38:33 +0300 Subject: [PATCH 3/6] HomeLibProt.CollectionImporter.Tests should reference to HomeLibProt.Common.Tests --- .../HomeLibProt.CollectionImporter.Tests.fsproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj b/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj index 42a21e3..51589a2 100644 --- a/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj +++ b/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj @@ -30,7 +30,7 @@ - + From 8ef57f7d00e4dfb83a37931c3243687e6af63be8 Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 17:01:38 +0300 Subject: [PATCH 4/6] Move TestCaseUtils --- .../HomeLibProt.CollectionImporter.Tests.fsproj | 1 - HomeLibProt.CollectionImporter.Tests/TestCollectionValidator.fs | 2 +- HomeLibProt.CollectionImporter.Tests/TestInpxImporter.fs | 2 +- HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj | 1 + .../Utils/TestCaseUtils.fs | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) rename {HomeLibProt.CollectionImporter.Tests => HomeLibProt.Common.Tests}/Utils/TestCaseUtils.fs (74%) diff --git a/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj b/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj index 51589a2..7e367b8 100644 --- a/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj +++ b/HomeLibProt.CollectionImporter.Tests/HomeLibProt.CollectionImporter.Tests.fsproj @@ -9,7 +9,6 @@ - diff --git a/HomeLibProt.CollectionImporter.Tests/TestCollectionValidator.fs b/HomeLibProt.CollectionImporter.Tests/TestCollectionValidator.fs index 6beb994..536570b 100644 --- a/HomeLibProt.CollectionImporter.Tests/TestCollectionValidator.fs +++ b/HomeLibProt.CollectionImporter.Tests/TestCollectionValidator.fs @@ -5,7 +5,7 @@ open System open System.IO open HomeLibProt.CollectionImporter.CollectionValidator -open HomeLibProt.CollectionImporter.Tests.Utils +open HomeLibProt.Common.Tests.Utils open HomeLibProt.Domain.DataAccess open HomeLibProt.Domain.Tests.Utils diff --git a/HomeLibProt.CollectionImporter.Tests/TestInpxImporter.fs b/HomeLibProt.CollectionImporter.Tests/TestInpxImporter.fs index 778d5b9..23f3dbe 100644 --- a/HomeLibProt.CollectionImporter.Tests/TestInpxImporter.fs +++ b/HomeLibProt.CollectionImporter.Tests/TestInpxImporter.fs @@ -5,7 +5,7 @@ open System open System.IO open HomeLibProt.CollectionImporter.InpxImporter -open HomeLibProt.CollectionImporter.Tests.Utils +open HomeLibProt.Common.Tests.Utils open HomeLibProt.Domain.DataAccess open HomeLibProt.Domain.Tests.Entities open HomeLibProt.Domain.Tests.Utils diff --git a/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj index c362547..071f28a 100644 --- a/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj +++ b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj @@ -9,6 +9,7 @@ + diff --git a/HomeLibProt.CollectionImporter.Tests/Utils/TestCaseUtils.fs b/HomeLibProt.Common.Tests/Utils/TestCaseUtils.fs similarity index 74% rename from HomeLibProt.CollectionImporter.Tests/Utils/TestCaseUtils.fs rename to HomeLibProt.Common.Tests/Utils/TestCaseUtils.fs index 14903e4..d01f666 100644 --- a/HomeLibProt.CollectionImporter.Tests/Utils/TestCaseUtils.fs +++ b/HomeLibProt.Common.Tests/Utils/TestCaseUtils.fs @@ -1,4 +1,4 @@ -module HomeLibProt.CollectionImporter.Tests.Utils.TestCaseUtils +module HomeLibProt.Common.Tests.Utils.TestCaseUtils open System.IO open System.Reflection From 06336f011b552c4a588febbc194cc1e08bdf077a Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 17:05:29 +0300 Subject: [PATCH 5/6] Add Fb2Reader tests - getFb2Attributes --- .../HomeLibProt.Common.Tests.fsproj | 1 + .../GetAttributes/NoAttributes/Book.fb2 | 30 +++++++++++++++ .../GetAttributes/OnlyReference/Book.fb2 | 34 +++++++++++++++++ .../GetAttributes/Simple/Book.fb2 | 37 +++++++++++++++++++ HomeLibProt.Common.Tests/TestFb2Reader.fs | 34 +++++++++++++++++ 5 files changed, 136 insertions(+) create mode 100644 HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/NoAttributes/Book.fb2 create mode 100644 HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/OnlyReference/Book.fb2 create mode 100644 HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/Simple/Book.fb2 create mode 100644 HomeLibProt.Common.Tests/TestFb2Reader.fs diff --git a/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj index 071f28a..d13cb8c 100644 --- a/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj +++ b/HomeLibProt.Common.Tests/HomeLibProt.Common.Tests.fsproj @@ -10,6 +10,7 @@ + diff --git a/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/NoAttributes/Book.fb2 b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/NoAttributes/Book.fb2 new file mode 100644 index 0000000..552fd54 --- /dev/null +++ b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/NoAttributes/Book.fb2 @@ -0,0 +1,30 @@ + + + + +genre1 +genre2 + +Aa +Bb +Cc + + +Dd +Ee +Ff + +Title 1 +en + + +Keyword1, Keyword2 +Keyword3 + + + +
+

Body

+
+ +
\ No newline at end of file diff --git a/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/OnlyReference/Book.fb2 b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/OnlyReference/Book.fb2 new file mode 100644 index 0000000..fad189a --- /dev/null +++ b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/OnlyReference/Book.fb2 @@ -0,0 +1,34 @@ + + + + +genre1 +genre2 + +Aa +Bb +Cc + + +Dd +Ee +Ff + +Title 1 + + + +en + + +Keyword1, Keyword2 +Keyword3 + + + +
+

Body

+
+ +Base64 +
\ No newline at end of file diff --git a/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/Simple/Book.fb2 b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/Simple/Book.fb2 new file mode 100644 index 0000000..a7018d2 --- /dev/null +++ b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetAttributes/Simple/Book.fb2 @@ -0,0 +1,37 @@ + + + + +genre1 +genre2 + +Aa +Bb +Cc + + +Dd +Ee +Ff + +Title 1 + +

Annotation

+
+ + + +en + + +Keyword1, Keyword2 +Keyword3 +
+
+ +
+

Body

+
+ +Base64 +
\ No newline at end of file diff --git a/HomeLibProt.Common.Tests/TestFb2Reader.fs b/HomeLibProt.Common.Tests/TestFb2Reader.fs new file mode 100644 index 0000000..b305f68 --- /dev/null +++ b/HomeLibProt.Common.Tests/TestFb2Reader.fs @@ -0,0 +1,34 @@ +module HomeLibProt.Common.Tests.TestFb2Reader + +open NUnit.Framework +open System.IO + +open HomeLibProt.Common.Fb2Reader +open HomeLibProt.Common.Tests.Utils + +let getBookPath (testCaseName: string) = + Path.Combine(TestCaseUtils.getTestCasesBasePath "TestFb2Reader", testCaseName, "Book.fb2") + +let getFb2AttributesTestCases = + [| TestCaseData( + "GetAttributes/Simple", + Some + { Annotation = Some "

Annotation

" + Coverpage = Some "Base64" } + ) + TestCaseData( + "GetAttributes/OnlyReference", + Some + { Annotation = None + Coverpage = Some "Base64" } + ) + TestCaseData("GetAttributes/NoAttributes", Some { Annotation = None; Coverpage = None }) |] + +[] +[] +let TestGetFb2Attributes (testCaseName: string, expected: Fb2Attributes option) = + use fb2 = getBookPath testCaseName |> File.OpenRead + + let actual = getFb2Attributes fb2 + + Assert.That(actual, Is.EqualTo expected) From 8e407e6fdd05e6e80c8bcdbede02b671459bb768 Mon Sep 17 00:00:00 2001 From: dazering Date: Fri, 19 Jun 2026 17:19:06 +0300 Subject: [PATCH 6/6] Add Fb2Reader tests - getFb2Info --- .../GetFb2Info/NoAttributes/Book.fb2 | 19 ++++++++++ .../TestFb2Reader/GetFb2Info/Simple/Book.fb2 | 37 +++++++++++++++++++ HomeLibProt.Common.Tests/TestFb2Reader.fs | 37 +++++++++++++++++++ 3 files changed, 93 insertions(+) create mode 100644 HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/NoAttributes/Book.fb2 create mode 100644 HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/Simple/Book.fb2 diff --git a/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/NoAttributes/Book.fb2 b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/NoAttributes/Book.fb2 new file mode 100644 index 0000000..fb7acc8 --- /dev/null +++ b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/NoAttributes/Book.fb2 @@ -0,0 +1,19 @@ + + + + + +

Annotation

+
+ + + +
+
+ +
+

Body

+
+ +Base64 +
\ No newline at end of file diff --git a/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/Simple/Book.fb2 b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/Simple/Book.fb2 new file mode 100644 index 0000000..a7018d2 --- /dev/null +++ b/HomeLibProt.Common.Tests/TestCases/TestFb2Reader/GetFb2Info/Simple/Book.fb2 @@ -0,0 +1,37 @@ + + + + +genre1 +genre2 + +Aa +Bb +Cc + + +Dd +Ee +Ff + +Title 1 + +

Annotation

+
+ + + +en + + +Keyword1, Keyword2 +Keyword3 +
+
+ +
+

Body

+
+ +Base64 +
\ No newline at end of file diff --git a/HomeLibProt.Common.Tests/TestFb2Reader.fs b/HomeLibProt.Common.Tests/TestFb2Reader.fs index b305f68..9c87ff2 100644 --- a/HomeLibProt.Common.Tests/TestFb2Reader.fs +++ b/HomeLibProt.Common.Tests/TestFb2Reader.fs @@ -24,6 +24,34 @@ let getFb2AttributesTestCases = ) TestCaseData("GetAttributes/NoAttributes", Some { Annotation = None; Coverpage = None }) |] +let getFb2InfoTestCases = + [| TestCaseData( + "GetFb2Info/Simple", + Some + { Authors = + [| { First = "Aa" + Middle = "Bb" + Last = "Cc" } + { First = "Dd" + Middle = "Ee" + Last = "Ff" } |] + Genres = [| "genre1"; "genre2" |] + Title = "Title 1" + Language = "en" + Keywords = [| "Keyword1"; "Keyword2"; "Keyword3" |] + Series = [| { Name = "Series 1"; Number = "1" }; { Name = "Series 2"; Number = "1" } |] } + ) + TestCaseData( + "GetFb2Info/NoAttributes", + Some + { Authors = [||] + Genres = [||] + Title = "" + Language = "" + Keywords = [||] + Series = [||] } + ) |] + [] [] let TestGetFb2Attributes (testCaseName: string, expected: Fb2Attributes option) = @@ -32,3 +60,12 @@ let TestGetFb2Attributes (testCaseName: string, expected: Fb2Attributes option) let actual = getFb2Attributes fb2 Assert.That(actual, Is.EqualTo expected) + +[] +[] +let TestGetFb2Info (testCaseName: string, expected: Fb2Info option) = + use fb2 = getBookPath testCaseName |> File.OpenRead + + let actual = getFb2Info fb2 + + Assert.That(actual, Is.EqualTo expected)