diff --git a/Source/VersOne.Epub.Test/Comparers/EpubMetadataComparer.cs b/Source/VersOne.Epub.Test/Comparers/EpubMetadataComparer.cs new file mode 100644 index 0000000..482eb86 --- /dev/null +++ b/Source/VersOne.Epub.Test/Comparers/EpubMetadataComparer.cs @@ -0,0 +1,194 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Comparers +{ + internal static class EpubMetadataComparer + { + public static void CompareEpubMetadatas(EpubMetadata? expected, EpubMetadata? actual) + { + if (expected == null) + { + Assert.Null(actual); + } + else + { + Assert.NotNull(actual); + CollectionComparer.CompareCollections(expected.Titles, actual.Titles, CompareEpubMetadataTitles); + CollectionComparer.CompareCollections(expected.Creators, actual.Creators, CompareEpubMetadataCreators); + CollectionComparer.CompareCollections(expected.Subjects, actual.Subjects, CompareEpubMetadataSubjects); + CollectionComparer.CompareCollections(expected.Descriptions, actual.Descriptions, CompareEpubMetadataDescriptions); + CollectionComparer.CompareCollections(expected.Publishers, actual.Publishers, CompareEpubMetadataPublishers); + CollectionComparer.CompareCollections(expected.Contributors, actual.Contributors, CompareEpubMetadataContributors); + CollectionComparer.CompareCollections(expected.Dates, actual.Dates, CompareEpubMetadataDates); + CollectionComparer.CompareCollections(expected.Types, actual.Types, CompareEpubMetadataTypes); + CollectionComparer.CompareCollections(expected.Formats, actual.Formats, CompareEpubMetadataFormats); + CollectionComparer.CompareCollections(expected.Identifiers, actual.Identifiers, CompareEpubMetadataIdentifiers); + CollectionComparer.CompareCollections(expected.Sources, actual.Sources, CompareEpubMetadataSources); + CollectionComparer.CompareCollections(expected.Languages, actual.Languages, CompareEpubMetadataLanguages); + CollectionComparer.CompareCollections(expected.Relations, actual.Relations, CompareEpubMetadataRelations); + CollectionComparer.CompareCollections(expected.Coverages, actual.Coverages, CompareEpubMetadataCoverages); + CollectionComparer.CompareCollections(expected.Rights, actual.Rights, CompareEpubMetadataRights); + CompareEpubMetadataLinkLists(expected.Links, actual.Links); + CollectionComparer.CompareCollections(expected.MetaItems, actual.MetaItems, CompareEpubMetadataMetas); + } + } + + public static void CompareEpubMetadataTitles(EpubMetadataTitle expected, EpubMetadataTitle actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Title, actual.Title); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataCreators(EpubMetadataCreator expected, EpubMetadataCreator actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Creator, actual.Creator); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.FileAs, actual.FileAs); + Assert.Equal(expected.Role, actual.Role); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataSubjects(EpubMetadataSubject expected, EpubMetadataSubject actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Subject, actual.Subject); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataDescriptions(EpubMetadataDescription expected, EpubMetadataDescription actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Description, actual.Description); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataPublishers(EpubMetadataPublisher expected, EpubMetadataPublisher actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Publisher, actual.Publisher); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataContributors(EpubMetadataContributor expected, EpubMetadataContributor actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Contributor, actual.Contributor); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.FileAs, actual.FileAs); + Assert.Equal(expected.Role, actual.Role); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataDates(EpubMetadataDate expected, EpubMetadataDate actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Date, actual.Date); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.Event, actual.Event); + } + + public static void CompareEpubMetadataTypes(EpubMetadataType expected, EpubMetadataType actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Type, actual.Type); + Assert.Equal(expected.Id, actual.Id); + } + + public static void CompareEpubMetadataFormats(EpubMetadataFormat expected, EpubMetadataFormat actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Format, actual.Format); + Assert.Equal(expected.Id, actual.Id); + } + + public static void CompareEpubMetadataIdentifiers(EpubMetadataIdentifier expected, EpubMetadataIdentifier actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Identifier, actual.Identifier); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.Scheme, actual.Scheme); + } + + public static void CompareEpubMetadataSources(EpubMetadataSource expected, EpubMetadataSource actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Source, actual.Source); + Assert.Equal(expected.Id, actual.Id); + } + + public static void CompareEpubMetadataLanguages(EpubMetadataLanguage expected, EpubMetadataLanguage actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Language, actual.Language); + Assert.Equal(expected.Id, actual.Id); + } + + public static void CompareEpubMetadataRelations(EpubMetadataRelation expected, EpubMetadataRelation actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Relation, actual.Relation); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataCoverages(EpubMetadataCoverage expected, EpubMetadataCoverage actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Coverage, actual.Coverage); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataRights(EpubMetadataRights expected, EpubMetadataRights actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Rights, actual.Rights); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + + public static void CompareEpubMetadataLinkLists(List expected, List actual) + { + CollectionComparer.CompareCollections(expected, actual, CompareEpubMetadataLinks); + } + + public static void CompareEpubMetadataLinks(EpubMetadataLink expected, EpubMetadataLink actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Href, actual.Href); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.MediaType, actual.MediaType); + Assert.Equal(expected.Properties, actual.Properties); + Assert.Equal(expected.Refines, actual.Refines); + Assert.Equal(expected.Relationships, actual.Relationships); + } + + public static void CompareEpubMetadataMetas(EpubMetadataMeta expected, EpubMetadataMeta actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Name, actual.Name); + Assert.Equal(expected.Content, actual.Content); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.Refines, actual.Refines); + Assert.Equal(expected.Property, actual.Property); + Assert.Equal(expected.Scheme, actual.Scheme); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Comparers/EpubPackageComparer.cs b/Source/VersOne.Epub.Test/Comparers/EpubPackageComparer.cs index 80433da..d820f8f 100644 --- a/Source/VersOne.Epub.Test/Comparers/EpubPackageComparer.cs +++ b/Source/VersOne.Epub.Test/Comparers/EpubPackageComparer.cs @@ -7,93 +7,23 @@ internal static class EpubPackageComparer public static void CompareEpubPackages(EpubPackage expected, EpubPackage actual) { Assert.NotNull(actual); + Assert.Equal(expected.UniqueIdentifier, actual.UniqueIdentifier); Assert.Equal(expected.EpubVersion, actual.EpubVersion); - CompareEpubMetadatas(expected.Metadata, actual.Metadata); + EpubMetadataComparer.CompareEpubMetadatas(expected.Metadata, actual.Metadata); CompareEpubManifests(expected.Manifest, actual.Manifest); CompareEpubSpines(expected.Spine, actual.Spine); CompareEpubGuides(expected.Guide, actual.Guide); - } - - public static void CompareEpubMetadatas(EpubMetadata expected, EpubMetadata actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Titles, actual.Titles); - CollectionComparer.CompareCollections(expected.Creators, actual.Creators, CompareEpubMetadataCreators); - Assert.Equal(expected.Subjects, actual.Subjects); - Assert.Equal(expected.Description, actual.Description); - Assert.Equal(expected.Publishers, actual.Publishers); - CollectionComparer.CompareCollections(expected.Contributors, actual.Contributors, CompareEpubMetadataContributors); - CollectionComparer.CompareCollections(expected.Dates, actual.Dates, CompareEpubMetadataDates); - Assert.Equal(expected.Types, actual.Types); - Assert.Equal(expected.Formats, actual.Formats); - CollectionComparer.CompareCollections(expected.Identifiers, actual.Identifiers, CompareEpubMetadataIdentifiers); - Assert.Equal(expected.Sources, actual.Sources); - Assert.Equal(expected.Languages, actual.Languages); - Assert.Equal(expected.Relations, actual.Relations); - Assert.Equal(expected.Coverages, actual.Coverages); - Assert.Equal(expected.Rights, actual.Rights); - CollectionComparer.CompareCollections(expected.Links, actual.Links, CompareEpubMetadataLinks); - CollectionComparer.CompareCollections(expected.MetaItems, actual.MetaItems, CompareEpubMetadataMetas); - } - - public static void CompareEpubMetadataCreators(EpubMetadataCreator expected, EpubMetadataCreator actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Id, actual.Id); - Assert.Equal(expected.Creator, actual.Creator); - Assert.Equal(expected.FileAs, actual.FileAs); - Assert.Equal(expected.Role, actual.Role); - } - - public static void CompareEpubMetadataContributors(EpubMetadataContributor expected, EpubMetadataContributor actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Id, actual.Id); - Assert.Equal(expected.Contributor, actual.Contributor); - Assert.Equal(expected.FileAs, actual.FileAs); - Assert.Equal(expected.Role, actual.Role); - } - - public static void CompareEpubMetadataDates(EpubMetadataDate expected, EpubMetadataDate actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Date, actual.Date); - Assert.Equal(expected.Event, actual.Event); - } - - public static void CompareEpubMetadataIdentifiers(EpubMetadataIdentifier expected, EpubMetadataIdentifier actual) - { - Assert.NotNull(actual); + CompareEpubCollectionLists(expected.Collections, actual.Collections); Assert.Equal(expected.Id, actual.Id); - Assert.Equal(expected.Scheme, actual.Scheme); - Assert.Equal(expected.Identifier, actual.Identifier); - } - - public static void CompareEpubMetadataLinks(EpubMetadataLink expected, EpubMetadataLink actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Id, actual.Id); - Assert.Equal(expected.Href, actual.Href); - Assert.Equal(expected.MediaType, actual.MediaType); - Assert.Equal(expected.Properties, actual.Properties); - Assert.Equal(expected.Refines, actual.Refines); - Assert.Equal(expected.Relationships, actual.Relationships); - } - - public static void CompareEpubMetadataMetas(EpubMetadataMeta expected, EpubMetadataMeta actual) - { - Assert.NotNull(actual); - Assert.Equal(expected.Name, actual.Name); - Assert.Equal(expected.Content, actual.Content); - Assert.Equal(expected.Id, actual.Id); - Assert.Equal(expected.Refines, actual.Refines); - Assert.Equal(expected.Property, actual.Property); - Assert.Equal(expected.Scheme, actual.Scheme); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Prefix, actual.Prefix); + Assert.Equal(expected.Language, actual.Language); } public static void CompareEpubManifests(EpubManifest expected, EpubManifest actual) { Assert.NotNull(actual); + Assert.Equal(expected.Id, actual.Id); CollectionComparer.CompareCollections(expected.Items, actual.Items, CompareEpubManifestItems); } @@ -154,5 +84,22 @@ public static void CompareEpubGuideReferences(EpubGuideReference expected, EpubG Assert.Equal(expected.Title, actual.Title); Assert.Equal(expected.Href, actual.Href); } + + public static void CompareEpubCollectionLists(List expected, List actual) + { + CollectionComparer.CompareCollections(expected, actual, CompareEpubCollections); + } + + public static void CompareEpubCollections(EpubCollection expected, EpubCollection actual) + { + Assert.NotNull(actual); + Assert.Equal(expected.Role, actual.Role); + EpubMetadataComparer.CompareEpubMetadatas(expected.Metadata, actual.Metadata); + CompareEpubCollectionLists(expected.NestedCollections, actual.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(expected.Links, actual.Links); + Assert.Equal(expected.Id, actual.Id); + Assert.Equal(expected.TextDirection, actual.TextDirection); + Assert.Equal(expected.Language, actual.Language); + } } } diff --git a/Source/VersOne.Epub.Test/Integration/CustomSerialization/CustomTypes.cs b/Source/VersOne.Epub.Test/Integration/CustomSerialization/CustomTypes.cs index be2a82a..c017648 100644 --- a/Source/VersOne.Epub.Test/Integration/CustomSerialization/CustomTypes.cs +++ b/Source/VersOne.Epub.Test/Integration/CustomSerialization/CustomTypes.cs @@ -85,7 +85,13 @@ private static IEnumerable CreateTypes() ( optionalProperties: new() { - { nameof(EpubPackage.Guide), PropertyDefaultValue.NULL } + { nameof(EpubPackage.UniqueIdentifier), PropertyDefaultValue.NULL }, + { nameof(EpubPackage.Guide), PropertyDefaultValue.NULL }, + { nameof(EpubPackage.Collections), PropertyDefaultValue.EMPTY_ARRAY }, + { nameof(EpubPackage.Id), PropertyDefaultValue.NULL }, + { nameof(EpubPackage.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubPackage.Prefix), PropertyDefaultValue.NULL }, + { nameof(EpubPackage.Language), PropertyDefaultValue.NULL }, } ); yield return CreateType @@ -95,7 +101,7 @@ private static IEnumerable CreateTypes() { nameof(EpubMetadata.Titles), PropertyDefaultValue.EMPTY_ARRAY }, { nameof(EpubMetadata.Creators), PropertyDefaultValue.EMPTY_ARRAY }, { nameof(EpubMetadata.Subjects), PropertyDefaultValue.EMPTY_ARRAY }, - { nameof(EpubMetadata.Description), PropertyDefaultValue.NULL }, + { nameof(EpubMetadata.Descriptions), PropertyDefaultValue.EMPTY_ARRAY }, { nameof(EpubMetadata.Publishers), PropertyDefaultValue.EMPTY_ARRAY }, { nameof(EpubMetadata.Contributors), PropertyDefaultValue.EMPTY_ARRAY }, { nameof(EpubMetadata.Dates), PropertyDefaultValue.EMPTY_ARRAY }, @@ -111,13 +117,51 @@ private static IEnumerable CreateTypes() { nameof(EpubMetadata.MetaItems), PropertyDefaultValue.EMPTY_ARRAY } } ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataTitle.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataTitle.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataTitle.Language), PropertyDefaultValue.NULL } + } + ); yield return CreateType ( optionalProperties: new() { { nameof(EpubMetadataCreator.Id), PropertyDefaultValue.NULL }, { nameof(EpubMetadataCreator.FileAs), PropertyDefaultValue.NULL }, - { nameof(EpubMetadataCreator.Role), PropertyDefaultValue.NULL } + { nameof(EpubMetadataCreator.Role), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataCreator.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataCreator.Language), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataSubject.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataSubject.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataSubject.Language), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataDescription.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataDescription.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataDescription.Language), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataPublisher.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataPublisher.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataPublisher.Language), PropertyDefaultValue.NULL } } ); yield return CreateType @@ -126,16 +170,33 @@ private static IEnumerable CreateTypes() { { nameof(EpubMetadataContributor.Id), PropertyDefaultValue.NULL }, { nameof(EpubMetadataContributor.FileAs), PropertyDefaultValue.NULL }, - { nameof(EpubMetadataContributor.Role), PropertyDefaultValue.NULL } + { nameof(EpubMetadataContributor.Role), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataContributor.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataContributor.Language), PropertyDefaultValue.NULL } } ); yield return CreateType ( optionalProperties: new() { + { nameof(EpubMetadataDate.Id), PropertyDefaultValue.NULL }, { nameof(EpubMetadataDate.Event), PropertyDefaultValue.NULL } } ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataType.Id), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataFormat.Id), PropertyDefaultValue.NULL } + } + ); yield return CreateType ( optionalProperties: new() @@ -144,6 +205,47 @@ private static IEnumerable CreateTypes() { nameof(EpubMetadataIdentifier.Scheme), PropertyDefaultValue.NULL } } ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataSource.Id), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataLanguage.Id), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataRelation.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataRelation.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataRelation.Language), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataCoverage.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataCoverage.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataCoverage.Language), PropertyDefaultValue.NULL } + } + ); + yield return CreateType + ( + optionalProperties: new() + { + { nameof(EpubMetadataRights.Id), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataRights.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataRights.Language), PropertyDefaultValue.NULL } + } + ); yield return CreateType ( optionalProperties: new() @@ -163,13 +265,16 @@ private static IEnumerable CreateTypes() { nameof(EpubMetadataMeta.Id), PropertyDefaultValue.NULL }, { nameof(EpubMetadataMeta.Refines), PropertyDefaultValue.NULL }, { nameof(EpubMetadataMeta.Property), PropertyDefaultValue.NULL }, - { nameof(EpubMetadataMeta.Scheme), PropertyDefaultValue.NULL } + { nameof(EpubMetadataMeta.Scheme), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataMeta.TextDirection), PropertyDefaultValue.NULL }, + { nameof(EpubMetadataMeta.Language), PropertyDefaultValue.NULL } } ); yield return CreateType ( optionalProperties: new() { + { nameof(EpubManifest.Id), PropertyDefaultValue.NULL }, { nameof(EpubManifest.Items), PropertyDefaultValue.EMPTY_ARRAY } } ); diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/53/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/53/testcases.json index 86893a8..ac9724b 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/53/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/53/testcases.json @@ -27,7 +27,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { @@ -46,14 +48,14 @@ ], "Identifiers": [ { + "Identifier": "https://example.com/books/123", "Id": "identifier-1", - "Scheme": "URI", - "Identifier": "https://example.com/books/123" + "Scheme": "URI" }, { + "Identifier": "9781234567890", "Id": "identifier-2", - "Scheme": "ISBN", - "Identifier": "9781234567890" + "Scheme": "ISBN" } ] }, diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/55/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/55/testcases.json index c0cb3dc..3195e7a 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/55/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/55/testcases.json @@ -27,7 +27,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/57/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/57/testcases.json index 82a0fcb..b95c5dd 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/57/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/BugFixes/57/testcases.json @@ -27,7 +27,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Features/RemoteContent/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Features/RemoteContent/testcases.json index 7544ed8..10b60f4 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Features/RemoteContent/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Features/RemoteContent/testcases.json @@ -110,7 +110,9 @@ "EpubVersion": "EPUB_3", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { @@ -405,7 +407,9 @@ "EpubVersion": "EPUB_3", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB2/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB2/testcases.json index 0aaba22..1503cd4 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB2/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB2/testcases.json @@ -49,7 +49,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB3/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB3/testcases.json index 4b32616..32e93c3 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB3/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/InvalidManifestItems/EPUB3/testcases.json @@ -54,7 +54,9 @@ "EpubVersion": "EPUB_3", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingContentForNavigationPoint/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingContentForNavigationPoint/testcases.json index f1fe6a7..1054cdd 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingContentForNavigationPoint/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingContentForNavigationPoint/testcases.json @@ -62,7 +62,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingToc/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingToc/testcases.json index 8598d29..bb09e9c 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingToc/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Malformed/MissingToc/testcases.json @@ -28,7 +28,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB2/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB2/testcases.json index 28c05af..df225cc 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB2/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB2/testcases.json @@ -223,42 +223,58 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title 1", - "Test title 2" + { + "Title": "Test title 1" + }, + { + "Title": "Test title 2" + } ], "Creators": [ { - "Id": "creator-1", "Creator": "John Doe", + "Id": "creator-1", "FileAs": "Doe, John", "Role": "author" }, { - "Id": "creator-2", "Creator": "Jane Doe", + "Id": "creator-2", "FileAs": "Doe, Jane", "Role": "author" } ], "Subjects": [ - "Test subject 1", - "Test subject 2" + { + "Subject": "Test subject 1" + }, + { + "Subject": "Test subject 2" + } + ], + "Descriptions": [ + { + "Description": "Test description" + } ], - "Description": "Test description", "Publishers": [ - "Test publisher 1", - "Test publisher 2" + { + "Publisher": "Test publisher 1" + }, + { + "Publisher": "Test publisher 2" + } ], "Contributors": [ { - "Id": "contributor-1", "Contributor": "John Editor", + "Id": "contributor-1", "FileAs": "Editor, John", "Role": "editor" }, { - "Id": "contributor-2", "Contributor": "Jane Editor", + "Id": "contributor-2", "FileAs": "Editor, Jane", "Role": "editor" } @@ -274,44 +290,72 @@ } ], "Types": [ - "dictionary", - "preview" + { + "Type": "dictionary" + }, + { + "Type": "preview" + } ], "Formats": [ - "format-1", - "format-2" + { + "Format": "format-1" + }, + { + "Format": "format-2" + } ], "Identifiers": [ { + "Identifier": "https://example.com/books/123", "Id": "identifier-1", - "Scheme": "URI", - "Identifier": "https://example.com/books/123" + "Scheme": "URI" }, { + "Identifier": "9781234567890", "Id": "identifier-2", - "Scheme": "ISBN", - "Identifier": "9781234567890" + "Scheme": "ISBN" } ], "Sources": [ - "https://example.com/books/123/content-1.html", - "https://example.com/books/123/content-2.html" + { + "Source": "https://example.com/books/123/content-1.html" + }, + { + "Source": "https://example.com/books/123/content-2.html" + } ], "Languages": [ - "en", - "is" + { + "Language": "en" + }, + { + "Language": "is" + } ], "Relations": [ - "https://example.com/books/123/related-1.html", - "https://example.com/books/123/related-2.html" + { + "Relation": "https://example.com/books/123/related-1.html" + }, + { + "Relation": "https://example.com/books/123/related-2.html" + } ], "Coverages": [ - "New York", - "1700-1850" + { + "Coverage": "New York" + }, + { + "Coverage": "1700-1850" + } ], "Rights": [ - "Public domain in the USA", - "All rights reserved" + { + "Rights": "Public domain in the USA" + }, + { + "Rights": "All rights reserved" + } ], "MetaItems": [ { diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB3/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB3/testcases.json index df5222d..9823453 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB3/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Typical/EPUB3/testcases.json @@ -245,42 +245,58 @@ "EpubVersion": "EPUB_3", "Metadata": { "Titles": [ - "Test title 1", - "Test title 2" + { + "Title": "Test title 1" + }, + { + "Title": "Test title 2" + } ], "Creators": [ { - "Id": "creator-1", "Creator": "John Doe", + "Id": "creator-1", "FileAs": "Doe, John", "Role": "author" }, { - "Id": "creator-2", "Creator": "Jane Doe", + "Id": "creator-2", "FileAs": "Doe, Jane", "Role": "author" } ], "Subjects": [ - "Test subject 1", - "Test subject 2" + { + "Subject": "Test subject 1" + }, + { + "Subject": "Test subject 2" + } + ], + "Descriptions": [ + { + "Description": "Test description" + } ], - "Description": "Test description", "Publishers": [ - "Test publisher 1", - "Test publisher 2" + { + "Publisher": "Test publisher 1" + }, + { + "Publisher": "Test publisher 2" + } ], "Contributors": [ { - "Id": "contributor-1", "Contributor": "John Editor", + "Id": "contributor-1", "FileAs": "Editor, John", "Role": "editor" }, { - "Id": "contributor-2", "Contributor": "Jane Editor", + "Id": "contributor-2", "FileAs": "Editor, Jane", "Role": "editor" } @@ -296,57 +312,85 @@ } ], "Types": [ - "dictionary", - "preview" + { + "Type": "dictionary" + }, + { + "Type": "preview" + } ], "Formats": [ - "format-1", - "format-2" + { + "Format": "format-1" + }, + { + "Format": "format-2" + } ], "Identifiers": [ { + "Identifier": "https://example.com/books/123", "Id": "identifier-1", - "Scheme": "URI", - "Identifier": "https://example.com/books/123" + "Scheme": "URI" }, { + "Identifier": "9781234567890", "Id": "identifier-2", - "Scheme": "ISBN", - "Identifier": "9781234567890" + "Scheme": "ISBN" } ], "Sources": [ - "https://example.com/books/123/content-1.html", - "https://example.com/books/123/content-2.html" + { + "Source": "https://example.com/books/123/content-1.html" + }, + { + "Source": "https://example.com/books/123/content-2.html" + } ], "Languages": [ - "en", - "is" + { + "Language": "en" + }, + { + "Language": "is" + } ], "Relations": [ - "https://example.com/books/123/related-1.html", - "https://example.com/books/123/related-2.html" + { + "Relation": "https://example.com/books/123/related-1.html" + }, + { + "Relation": "https://example.com/books/123/related-2.html" + } ], "Coverages": [ - "New York", - "1700-1850" + { + "Coverage": "New York" + }, + { + "Coverage": "1700-1850" + } ], "Rights": [ - "Public domain in the USA", - "All rights reserved" + { + "Rights": "Public domain in the USA" + }, + { + "Rights": "All rights reserved" + } ], "Links": [ { - "Id": "link-1", "Href": "front.html#meta-json", + "Id": "link-1", "MediaType": "application/xhtml+xml", "Relationships": [ "RECORD" ] }, { - "Id": "link-2", "Href": "https://example.com/onix/123", + "Id": "link-2", "MediaType": "application/xml", "Properties": [ "ONIX" @@ -357,16 +401,16 @@ ] }, { - "Id": "link-3", "Href": "book.atom", + "Id": "link-3", "MediaType": "application/atom+xml;type=entry;profile=opds-catalog", "Relationships": [ "RECORD" ] }, { - "Id": "link-4", "Href": "title.mp3", + "Id": "link-4", "MediaType": "audio/mpeg", "Refines": "#title", "Relationships": [ diff --git a/Source/VersOne.Epub.Test/Integration/TestCases/Workarounds/Xml11/testcases.json b/Source/VersOne.Epub.Test/Integration/TestCases/Workarounds/Xml11/testcases.json index 46b63f7..ad39b25 100644 --- a/Source/VersOne.Epub.Test/Integration/TestCases/Workarounds/Xml11/testcases.json +++ b/Source/VersOne.Epub.Test/Integration/TestCases/Workarounds/Xml11/testcases.json @@ -39,7 +39,9 @@ "EpubVersion": "EPUB_2", "Metadata": { "Titles": [ - "Test title" + { + "Title": "Test title" + } ], "Creators": [ { diff --git a/Source/VersOne.Epub.Test/Unit/Entities/EpubBookRefTests.cs b/Source/VersOne.Epub.Test/Unit/Entities/EpubBookRefTests.cs index 9449a29..0bca5bf 100644 --- a/Source/VersOne.Epub.Test/Unit/Entities/EpubBookRefTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Entities/EpubBookRefTests.cs @@ -370,6 +370,7 @@ private static EpubBookRef CreateEpubBookRef(TestZipFile epubFile, EpubVersion e ( package: new EpubPackage ( + uniqueIdentifier: null, epubVersion: epubVersion, metadata: new EpubMetadata(), manifest: manifest ?? new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/BookCoverReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/BookCoverReaderTests.cs index 29d2e07..80741f1 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/BookCoverReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/BookCoverReaderTests.cs @@ -317,6 +317,7 @@ private static EpubSchema CreateEmptyEpubSchema(EpubVersion epubVersion, EpubMan ( package: new EpubPackage ( + uniqueIdentifier: null, epubVersion: epubVersion, metadata: new EpubMetadata(), manifest: manifest ?? new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/ContentReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/ContentReaderTests.cs index c70be7e..06b1b0a 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/ContentReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/ContentReaderTests.cs @@ -603,6 +603,7 @@ private static EpubSchema CreateEpubSchema(EpubManifest? manifest = null) ( package: new EpubPackage ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: manifest ?? new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/Epub2NcxReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/Epub2NcxReaderTests.cs index 0e588d1..7c693be 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/Epub2NcxReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/Epub2NcxReaderTests.cs @@ -373,6 +373,7 @@ public class Epub2NcxReaderTests private static EpubPackage MinimalEpubPackageWithNcx => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest @@ -732,6 +733,7 @@ public async void ReadEpub2NcxAsyncWithoutTocTest() TestZipFile testZipFile = new(); EpubPackage epubPackage = new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -749,6 +751,7 @@ public async void ReadEpub2NcxAsyncWithoutTocManifestItemTest() TestZipFile testZipFile = new(); EpubPackage epubPackage = new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/Epub3NavDocumentReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/Epub3NavDocumentReaderTests.cs index 8220719..97d4a3c 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/Epub3NavDocumentReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/Epub3NavDocumentReaderTests.cs @@ -148,6 +148,7 @@ public class Epub3NavDocumentReaderTests private static EpubPackage MinimalEpubPackageWithNav => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: new EpubManifest @@ -320,6 +321,7 @@ public async void ReadEpub3NavDocumentAsyncForEpub3WithoutNavManifestItemTest() TestZipFile testZipFile = new(); EpubPackage epubPackage = new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: new EpubManifest @@ -347,6 +349,7 @@ public async void ReadEpub3NavDocumentAsyncForEpub2WithoutNavManifestItemTest() TestZipFile testZipFile = new(); EpubPackage epubPackage = new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/MetadataReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/MetadataReaderTests.cs new file mode 100644 index 0000000..92269c4 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Readers/MetadataReaderTests.cs @@ -0,0 +1,449 @@ +using System.Xml.Linq; +using VersOne.Epub.Internal; +using VersOne.Epub.Schema; +using VersOne.Epub.Test.Comparers; + +namespace VersOne.Epub.Test.Unit.Readers +{ + public class MetadataReaderTests + { + private const string MINIMAL_METADATA_XML = ""; + + private const string FULL_METADATA_XML = $""" + + Test title 1 + Test title 2 + John Doe + Jane Doe + Test subject 1 + Test subject 2 + Test description 1 + Test description 2 + Test publisher 1 + Test publisher 2 + John Editor + Jane Editor + 2021-12-31T23:59:59.123456Z + 2022-01-23 + dictionary + preview + format-1 + format-2 + https://example.com/books/123 + 9781234567890 + https://example.com/books/123/content-1.html + https://example.com/books/123/content-2.html + en + is + https://example.com/books/123/related-1.html + https://example.com/books/123/related-2.html + New York + 1700-1850 + Public domain in the USA + All rights reserved + + + + + + landscape + 123 + Brynjólfur Sveinsson + + """; + + private const string METADATA_XML_WITHOUT_HREF_IN_METADATA_LINK = $""" + + + + """; + + private const string METADATA_XML_WITHOUT_REL_IN_METADATA_LINK = $""" + + + + """; + + private static EpubMetadata MinimalMetadata => new(); + + private static EpubMetadata FullMetadata => + new + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title 1", + id: "title-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataTitle + ( + title: "Test title 2", + id: "title-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + creators: new List() + { + new EpubMetadataCreator + ( + role: "author", + id: "creator-1", + fileAs: "Doe, John", + creator: "John Doe", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataCreator + ( + role: "author", + id: "creator-2", + fileAs: "Doe, Jane", + creator: "Jane Doe", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + subjects: new List() + { + new EpubMetadataSubject + ( + subject: "Test subject 1", + id: "subject-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataSubject + ( + subject: "Test subject 2", + id: "subject-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + descriptions: new List() + { + new EpubMetadataDescription + ( + description: "Test description 1", + id: "description-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataDescription + ( + description: "Test description 2", + id: "description-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + publishers: new List() + { + new EpubMetadataPublisher + ( + publisher: "Test publisher 1", + id: "publisher-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataPublisher + ( + publisher: "Test publisher 2", + id: "publisher-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + contributors: new List() + { + new EpubMetadataContributor + ( + role: "editor", + id: "contributor-1", + fileAs: "Editor, John", + contributor: "John Editor", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataContributor + ( + role: "editor", + id: "contributor-2", + fileAs: "Editor, Jane", + contributor: "Jane Editor", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + dates: new List() + { + new EpubMetadataDate + ( + @event: "creation", + id: "date-1", + date: "2021-12-31T23:59:59.123456Z" + ), + new EpubMetadataDate + ( + @event: "publication", + id: "date-2", + date: "2022-01-23" + ) + }, + types: new List() + { + new EpubMetadataType + ( + type: "dictionary", + id: "type-1" + ), + new EpubMetadataType + ( + type: "preview", + id: "type-2" + ) + }, + formats: new List() + { + new EpubMetadataFormat + ( + format: "format-1", + id: "format-1" + ), + new EpubMetadataFormat + ( + format: "format-2", + id: "format-2" + ) + }, + identifiers: new List() + { + new EpubMetadataIdentifier + ( + identifier: "https://example.com/books/123", + id: "identifier-1", + scheme: "URI" + ), + new EpubMetadataIdentifier + ( + identifier: "9781234567890", + id: "identifier-2", + scheme: "ISBN" + ) + }, + sources: new List() + { + new EpubMetadataSource + ( + source: "https://example.com/books/123/content-1.html", + id: "source-1" + ), + new EpubMetadataSource + ( + source: "https://example.com/books/123/content-2.html", + id: "source-2" + ) + }, + languages: new List() + { + new EpubMetadataLanguage + ( + language: "en", + id: "language-1" + ), + new EpubMetadataLanguage + ( + language: "is", + id: "language-2" + ) + }, + relations: new List() + { + new EpubMetadataRelation + ( + relation: "https://example.com/books/123/related-1.html", + id: "relation-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataRelation + ( + relation: "https://example.com/books/123/related-2.html", + id: "relation-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + coverages: new List() + { + new EpubMetadataCoverage + ( + coverage: "New York", + id: "coverage-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataCoverage + ( + coverage: "1700-1850", + id: "coverage-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + rights: new List() + { + new EpubMetadataRights + ( + rights: "Public domain in the USA", + id: "rights-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataRights + ( + rights: "All rights reserved", + id: "rights-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }, + links: new List() + { + new EpubMetadataLink + ( + id: "link-1", + href: "front.html#meta-json", + mediaType: "application/xhtml+xml", + properties: null, + refines: null, + relationships: new List() + { + EpubMetadataLinkRelationship.RECORD + } + ), + new EpubMetadataLink + ( + id: "link-2", + href: "https://example.com/onix/123", + mediaType: "application/xml", + properties: new List() + { + EpubMetadataLinkProperty.ONIX + }, + refines: null, + relationships: new List() + { + EpubMetadataLinkRelationship.RECORD, + EpubMetadataLinkRelationship.ONIX_RECORD + } + ), + new EpubMetadataLink + ( + id: "link-3", + href: "book.atom", + mediaType: "application/atom+xml;type=entry;profile=opds-catalog", + properties: null, + refines: null, + relationships: new List() + { + EpubMetadataLinkRelationship.RECORD + } + ), + new EpubMetadataLink + ( + id: "link-4", + href: "title.mp3", + mediaType: "audio/mpeg", + properties: null, + refines: "#title-1", + relationships: new List() + { + EpubMetadataLinkRelationship.VOICING + } + ) + }, + metaItems: new List() + { + new EpubMetadataMeta + ( + name: "cover", + content: "cover-image" + ), + new EpubMetadataMeta + ( + name: null, + content: "landscape", + id: "meta-1", + refines: null, + property: "rendition:orientation", + scheme: null + ), + new EpubMetadataMeta + ( + name: null, + content: "123", + id: "meta-2", + refines: "#identifier-2", + property: "identifier-type", + scheme: "onix:codelist5", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ), + new EpubMetadataMeta + ( + name: null, + content: "Brynjólfur Sveinsson", + id: "meta-3", + refines: "#creator-1", + property: "alternate-script", + scheme: null, + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + } + ); + + [Fact(DisplayName = "Reading a minimal metadata XML should succeed")] + public void ReadMinimalMetadataTest() + { + TestSuccessfulReadOperation(MINIMAL_METADATA_XML, MinimalMetadata); + } + + [Fact(DisplayName = "Reading a full metadata XML should succeed")] + public void ReadFullMetadataTest() + { + TestSuccessfulReadOperation(FULL_METADATA_XML, FullMetadata); + } + + [Fact(DisplayName = "Trying to read metadata XML without 'href' attribute in a metadata link XML node should fail with EpubPackageException")] + public void ReadPackageWithoutMetadataLinkHrefTest() + { + TestFailingReadOperation(METADATA_XML_WITHOUT_HREF_IN_METADATA_LINK); + } + + [Fact(DisplayName = "Trying to read metadata XML without 'rel' attribute in a metadata link XML node should fail with EpubPackageException")] + public void ReadPackageWithoutMetadataLinkRelTest() + { + TestFailingReadOperation(METADATA_XML_WITHOUT_REL_IN_METADATA_LINK); + } + + + private static void TestSuccessfulReadOperation(string metadataXml, EpubMetadata expectedEpubMetadata) + { + XElement metadataNode = XElement.Parse(metadataXml); + EpubMetadata actualEpubMetadata = MetadataReader.ReadMetadata(metadataNode); + EpubMetadataComparer.CompareEpubMetadatas(expectedEpubMetadata, actualEpubMetadata); + } + + private static void TestFailingReadOperation(string metadataXml) + { + XElement metadataNode = XElement.Parse(metadataXml); + Assert.Throws(() => MetadataReader.ReadMetadata(metadataNode)); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Readers/NavigationReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/NavigationReaderTests.cs index bc6dece..aafc8b7 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/NavigationReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/NavigationReaderTests.cs @@ -727,6 +727,7 @@ private static EpubPackage CreateEmptyPackage(EpubVersion epubVersion) { return new ( + uniqueIdentifier: null, epubVersion: epubVersion, metadata: new EpubMetadata(), manifest: new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Readers/PackageReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/PackageReaderTests.cs index 8a9b89e..e06b96c 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/PackageReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/PackageReaderTests.cs @@ -49,47 +49,16 @@ public class PackageReaderTests private const string FULL_OPF_FILE = $""" - + - Test title 1 - Test title 2 - John Doe - Jane Doe - Test subject 1 - Test subject 2 - Test description - Test publisher 1 - Test publisher 2 - John Editor - Jane Editor - 2021-12-31T23:59:59.123456Z - 2022-01-23 - dictionary - preview - format-1 - format-2 - https://example.com/books/123 - 9781234567890 - https://example.com/books/123/content-1.html - https://example.com/books/123/content-2.html + Test title + John Doe + 9781234567890 en - is - https://example.com/books/123/related-1.html - https://example.com/books/123/related-2.html - New York - 1700-1850 - Public domain in the USA - All rights reserved - - - - - - landscape - 123 - Brynjólfur Sveinsson + 2021-12-31T00:00:00Z - + @@ -120,6 +89,17 @@ public class PackageReaderTests + + + Test title for collection 1 + + + + Test title for collection 2 + + + + """; @@ -165,23 +145,10 @@ public class PackageReaderTests """; - private const string OPF_FILE_WITHOUT_HREF_IN_METADATA_LINK = $""" - - - - - - - - - """; - - private const string OPF_FILE_WITHOUT_REL_IN_METADATA_LINK = $""" + private const string OPF_FILE_WITHOUT_VERSION_IN_PACKAGE = $""" - - - - + + @@ -273,9 +240,20 @@ public class PackageReaderTests """; + private const string OPF_FILE_WITHOUT_ROLE_IN_COLLECTION = $""" + + + + + + + + """; + private static EpubPackage MinimalEpub2Package => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -289,6 +267,7 @@ public class PackageReaderTests private static EpubPackage MinimalEpub3Package => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -299,6 +278,7 @@ public class PackageReaderTests private static EpubPackage MinimalEpub31Package => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3_1, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -306,419 +286,322 @@ public class PackageReaderTests guide: null ); - private static EpubPackage FullPackage - { - get - { - return new + private static EpubPackage FullPackage => + new + ( + uniqueIdentifier: "book-uid", + epubVersion: EpubVersion.EPUB_3, + metadata: new EpubMetadata + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title" + ) + }, + creators: new List() + { + new EpubMetadataCreator + ( + creator: "John Doe" + ) + }, + identifiers: new List() + { + new EpubMetadataIdentifier + ( + identifier: "9781234567890", + id: "book-uid" + ) + }, + languages: new List() + { + new EpubMetadataLanguage + ( + language: "en" + ) + }, + metaItems: new List() + { + new EpubMetadataMeta + ( + name: null, + content: "2021-12-31T00:00:00Z", + property: "dcterms:modified" + ) + } + ), + manifest: new EpubManifest ( - epubVersion: EpubVersion.EPUB_3, - metadata: new EpubMetadata + id: "manifest-id", + items: new List() + { + new EpubManifestItem + ( + id: "item-front", + href: "front.html", + mediaType: "application/xhtml+xml" + ), + new EpubManifestItem + ( + id: "cover", + href: "cover.html", + mediaType: "application/xhtml+xml" + ), + new EpubManifestItem + ( + id: "cover-image", + href: "cover.jpg", + mediaType: "image/jpeg", + properties: new List() + { + EpubManifestProperty.COVER_IMAGE + } + ), + new EpubManifestItem + ( + id: "item-css", + href: "styles.css", + mediaType: "text/css" + ), + new EpubManifestItem + ( + id: "item-font", + href: "font.ttf", + mediaType: "application/x-font-truetype" + ), + new EpubManifestItem + ( + id: "item-1", + href: "chapter1.html", + mediaType: "application/xhtml+xml", + mediaOverlay: "item-1-smil", + requiredNamespace: null, + requiredModules: null, + fallback: null, + fallbackStyle: null, + properties: null + ), + new EpubManifestItem + ( + id: "item-1-smil", + href: "chapter1.smil", + mediaType: "application/smil+xml" + ), + new EpubManifestItem + ( + id: "item-2", + href: "chapter2.html", + mediaType: "application/xhtml+xml" + ), + new EpubManifestItem + ( + id: "item-2-fall", + href: "chapter2.xml", + mediaType: "text/example+xml", + mediaOverlay: null, + requiredNamespace: "http://example.com/ns/example/", + requiredModules: "ruby, server-side-image-map", + fallback: "item-2", + fallbackStyle: "item-css", + properties: null + ), + new EpubManifestItem + ( + id: "item-3", + href: "chapter3.html", + mediaType: "application/xhtml+xml" + ), + new EpubManifestItem + ( + id: "item-3-fall", + href: "chapter3.xml", + mediaType: "application/z3998-auth+xml", + mediaOverlay: null, + requiredNamespace: null, + requiredModules: null, + fallback: "item-3", + fallbackStyle: null, + properties: null + ), + new EpubManifestItem + ( + id: "item-3-remote-audio", + href: "http://example.com/audio/123/chapter3.mp4", + mediaType: "audio/mp4" + ), + new EpubManifestItem + ( + id: "item-image", + href: "image.jpg", + mediaType: "image/jpeg" + ), + new EpubManifestItem + ( + id: "item-title-audio", + href: "title.mp3", + mediaType: "audio/mpeg" + ), + new EpubManifestItem + ( + id: "item-atom", + href: "book.atom", + mediaType: "application/atom+xml" + ), + new EpubManifestItem + ( + id: "item-toc", + href: "toc.html", + mediaType: "application/xhtml+xml", + properties: new List + { + EpubManifestProperty.NAV + } + ), + new EpubManifestItem + ( + id: "ncx", + href: "toc.ncx", + mediaType: "application/x-dtbncx+xml" + ) + } + ), + spine: new EpubSpine + ( + id: "spine", + pageProgressionDirection: EpubPageProgressionDirection.LEFT_TO_RIGHT, + toc: "ncx", + items: new List() + { + new EpubSpineItemRef + ( + id: "itemref-1", + idRef: "item-front", + isLinear: true + ), + new EpubSpineItemRef + ( + id: "itemref-2", + idRef: "item-toc", + isLinear: false + ), + new EpubSpineItemRef + ( + id: "itemref-3", + idRef: "item-1", + isLinear: true + ), + new EpubSpineItemRef + ( + id: "itemref-4", + idRef: "item-2", + isLinear: true, + properties: new List() + { + EpubSpineProperty.PAGE_SPREAD_LEFT + } + ), + new EpubSpineItemRef + ( + id: "itemref-5", + idRef: "item-3", + isLinear: true, + properties: new List() + { + EpubSpineProperty.PAGE_SPREAD_RIGHT + } + ) + } + ), + guide: new EpubGuide + ( + items: new List() + { + new EpubGuideReference + ( + type: "toc", + title: "Contents", + href: "toc.html" + ) + } + ), + collections: new List() + { + new EpubCollection ( - titles: new List() - { - "Test title 1", - "Test title 2" - }, - creators: new List() - { - new EpubMetadataCreator - ( - id: "creator-1", - role: "author", - fileAs: "Doe, John", - creator: "John Doe" - ), - new EpubMetadataCreator - ( - id: "creator-2", - role: "author", - fileAs: "Doe, Jane", - creator: "Jane Doe" - ) - }, - subjects: new List() - { - "Test subject 1", - "Test subject 2" - }, - description: "Test description", - publishers: new List() - { - "Test publisher 1", - "Test publisher 2" - }, - contributors: new List() - { - new EpubMetadataContributor - ( - id: "contributor-1", - role: "editor", - fileAs: "Editor, John", - contributor: "John Editor" - ), - new EpubMetadataContributor - ( - id: "contributor-2", - role: "editor", - fileAs: "Editor, Jane", - contributor: "Jane Editor" - ) - }, - dates: new List() - { - new EpubMetadataDate - ( - @event: "creation", - date: "2021-12-31T23:59:59.123456Z" - ), - new EpubMetadataDate - ( - @event: "publication", - date: "2022-01-23" - ) - }, - types: new List() + role: "http://example.org/roles/group", + metadata: new EpubMetadata + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title for collection 1", + id: "collection-1-title", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ) + } + ), + nestedCollections: new List() { - "dictionary", - "preview" - }, - formats: new List() - { - "format-1", - "format-2" - }, - identifiers: new List() - { - new EpubMetadataIdentifier - ( - id: "identifier-1", - scheme: "URI", - identifier: "https://example.com/books/123" - ), - new EpubMetadataIdentifier - ( - id: "identifier-2", - scheme: "ISBN", - identifier: "9781234567890" + new EpubCollection + ( + role: "http://example.org/roles/unit", + metadata: new EpubMetadata + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title for collection 2", + id: "collection-2-title", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + } + ), + nestedCollections: new List(), + links: new List(), + id: "collection-2", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" ) }, - sources: new List() - { - "https://example.com/books/123/content-1.html", - "https://example.com/books/123/content-2.html" - }, - languages: new List() - { - "en", - "is" - }, - relations: new List() - { - "https://example.com/books/123/related-1.html", - "https://example.com/books/123/related-2.html" - }, - coverages: new List() - { - "New York", - "1700-1850" - }, - rights: new List() - { - "Public domain in the USA", - "All rights reserved" - }, links: new List() { new EpubMetadataLink ( - id: "link-1", - href: "front.html#meta-json", - mediaType: "application/xhtml+xml", - properties: null, - refines: null, - relationships: new List() - { - EpubMetadataLinkRelationship.RECORD - } - ), - new EpubMetadataLink - ( - id: "link-2", href: "https://example.com/onix/123", + id: "collection-1-link", mediaType: "application/xml", properties: new List() { EpubMetadataLinkProperty.ONIX }, - refines: null, relationships: new List() { EpubMetadataLinkRelationship.RECORD, EpubMetadataLinkRelationship.ONIX_RECORD } - ), - new EpubMetadataLink - ( - id: "link-3", - href: "book.atom", - mediaType: "application/atom+xml;type=entry;profile=opds-catalog", - properties: null, - refines: null, - relationships: new List() - { - EpubMetadataLinkRelationship.RECORD - } - ), - new EpubMetadataLink - ( - id: "link-4", - href: "title.mp3", - mediaType: "audio/mpeg", - properties: null, - refines: "#title", - relationships: new List() - { - EpubMetadataLinkRelationship.VOICING - } ) }, - metaItems: new List() - { - new EpubMetadataMeta - ( - name: "cover", - content: "cover-image" - ), - new EpubMetadataMeta - ( - name: null, - content: "landscape", - id: "meta-1", - refines: null, - property: "rendition:orientation", - scheme: null - ), - new EpubMetadataMeta - ( - name: null, - content: "123", - id: "meta-2", - refines: "#identifier-2", - property: "identifier-type", - scheme: "onix:codelist5" - ), - new EpubMetadataMeta - ( - name: null, - content: "Brynjólfur Sveinsson", - id: "meta-3", - refines: "#creator-1", - property: "alternate-script", - scheme: null - ) - } - ), - manifest: new EpubManifest - ( - items: new List() - { - new EpubManifestItem - ( - id: "item-front", - href: "front.html", - mediaType: "application/xhtml+xml" - ), - new EpubManifestItem - ( - id: "cover", - href: "cover.html", - mediaType: "application/xhtml+xml" - ), - new EpubManifestItem - ( - id: "cover-image", - href: "cover.jpg", - mediaType: "image/jpeg", - properties: new List() - { - EpubManifestProperty.COVER_IMAGE - } - ), - new EpubManifestItem - ( - id: "item-css", - href: "styles.css", - mediaType: "text/css" - ), - new EpubManifestItem - ( - id: "item-font", - href: "font.ttf", - mediaType: "application/x-font-truetype" - ), - new EpubManifestItem - ( - id: "item-1", - href: "chapter1.html", - mediaType: "application/xhtml+xml", - mediaOverlay: "item-1-smil", - requiredNamespace: null, - requiredModules: null, - fallback: null, - fallbackStyle: null, - properties: null - ), - new EpubManifestItem - ( - id: "item-1-smil", - href: "chapter1.smil", - mediaType: "application/smil+xml" - ), - new EpubManifestItem - ( - id: "item-2", - href: "chapter2.html", - mediaType: "application/xhtml+xml" - ), - new EpubManifestItem - ( - id: "item-2-fall", - href: "chapter2.xml", - mediaType: "text/example+xml", - mediaOverlay: null, - requiredNamespace: "http://example.com/ns/example/", - requiredModules: "ruby, server-side-image-map", - fallback: "item-2", - fallbackStyle: "item-css", - properties: null - ), - new EpubManifestItem - ( - id: "item-3", - href: "chapter3.html", - mediaType: "application/xhtml+xml" - ), - new EpubManifestItem - ( - id: "item-3-fall", - href: "chapter3.xml", - mediaType: "application/z3998-auth+xml", - mediaOverlay: null, - requiredNamespace: null, - requiredModules: null, - fallback: "item-3", - fallbackStyle: null, - properties: null - ), - new EpubManifestItem - ( - id: "item-3-remote-audio", - href: "http://example.com/audio/123/chapter3.mp4", - mediaType: "audio/mp4" - ), - new EpubManifestItem - ( - id: "item-image", - href: "image.jpg", - mediaType: "image/jpeg" - ), - new EpubManifestItem - ( - id: "item-title-audio", - href: "title.mp3", - mediaType: "audio/mpeg" - ), - new EpubManifestItem - ( - id: "item-atom", - href: "book.atom", - mediaType: "application/atom+xml" - ), - new EpubManifestItem - ( - id: "item-toc", - href: "toc.html", - mediaType: "application/xhtml+xml", - properties: new List - { - EpubManifestProperty.NAV - } - ), - new EpubManifestItem - ( - id: "ncx", - href: "toc.ncx", - mediaType: "application/x-dtbncx+xml" - ) - } - ), - spine: new EpubSpine - ( - id: "spine", - pageProgressionDirection: EpubPageProgressionDirection.LEFT_TO_RIGHT, - toc: "ncx", - items: new List() - { - new EpubSpineItemRef - ( - id: "itemref-1", - idRef: "item-front", - isLinear: true - ), - new EpubSpineItemRef - ( - id: "itemref-2", - idRef: "item-toc", - isLinear: false - ), - new EpubSpineItemRef - ( - id: "itemref-3", - idRef: "item-1", - isLinear: true - ), - new EpubSpineItemRef - ( - id: "itemref-4", - idRef: "item-2", - isLinear: true, - properties: new List() - { - EpubSpineProperty.PAGE_SPREAD_LEFT - } - ), - new EpubSpineItemRef - ( - id: "itemref-5", - idRef: "item-3", - isLinear: true, - properties: new List() - { - EpubSpineProperty.PAGE_SPREAD_RIGHT - } - ) - } - ), - guide: new EpubGuide - ( - items: new List() - { - new EpubGuideReference - ( - type: "toc", - title: "Contents", - href: "toc.html" - ) - } + id: "collection-1", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" ) - ); - } - } + }, + id: "package-id", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + prefix: "foaf: http://xmlns.com/foaf/spec/", + language: "en" + ); private static EpubPackage Epub2PackageWithoutSpineToc => new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -809,16 +692,10 @@ public async void ReadPackageWithoutSpineNodeTest() await TestFailingReadOperation(OPF_FILE_WITHOUT_SPINE); } - [Fact(DisplayName = "Trying to read OPF package without 'href' attribute in a metadata link XML node should fail with EpubPackageException")] - public async void ReadPackageWithoutMetadataLinkHrefTest() + [Fact(DisplayName = "Trying to read OPF package without 'version' attribute in a package XML node should fail with EpubPackageException")] + public async void ReadPackageWithoutVersionTest() { - await TestFailingReadOperation(OPF_FILE_WITHOUT_HREF_IN_METADATA_LINK); - } - - [Fact(DisplayName = "Trying to read OPF package without 'rel' attribute in a metadata link XML node should fail with EpubPackageException")] - public async void ReadPackageWithoutMetadataLinkRelTest() - { - await TestFailingReadOperation(OPF_FILE_WITHOUT_REL_IN_METADATA_LINK); + await TestFailingReadOperation(OPF_FILE_WITHOUT_VERSION_IN_PACKAGE); } [Fact(DisplayName = "Trying to read OPF package without 'id' attribute in a manifest item XML node should fail with EpubPackageException")] @@ -930,6 +807,12 @@ public async void ReadPackageWithoutGuideReferenceHrefTest() await TestFailingReadOperation(OPF_FILE_WITHOUT_HREF_IN_GUIDE_REFERENCE); } + [Fact(DisplayName = "Trying to read OPF package without 'role' attribute in a collection XML node should fail with EpubPackageException")] + public async void ReadPackageWithoutCollectionRoleTest() + { + await TestFailingReadOperation(OPF_FILE_WITHOUT_ROLE_IN_COLLECTION); + } + private static async Task TestSuccessfulReadOperation(string opfFileContent, EpubPackage expectedEpubPackage, EpubReaderOptions? epubReaderOptions = null) { TestZipFile testZipFile = CreateTestZipFileWithOpfFile(opfFileContent); diff --git a/Source/VersOne.Epub.Test/Unit/Readers/SchemaReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/SchemaReaderTests.cs index e8a8afd..fe82779 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/SchemaReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/SchemaReaderTests.cs @@ -29,10 +29,11 @@ public class SchemaReaderTests private const string OPF_PACKAGE_FILE = $""" - + Test title John Doe + 9781234567890 @@ -137,12 +138,16 @@ public async void ReadSchemaAsyncTest() ( package: new EpubPackage ( + uniqueIdentifier: "book-uid", epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata ( - titles: new List() + titles: new List() { - "Test title" + new EpubMetadataTitle + ( + title: "Test title" + ) }, creators: new List() { @@ -150,6 +155,14 @@ public async void ReadSchemaAsyncTest() ( creator: "John Doe" ) + }, + identifiers: new List() + { + new EpubMetadataIdentifier + ( + identifier: "9781234567890", + id: "book-uid" + ) } ), manifest: new EpubManifest diff --git a/Source/VersOne.Epub.Test/Unit/Readers/SpineReaderTests.cs b/Source/VersOne.Epub.Test/Unit/Readers/SpineReaderTests.cs index b9bf566..bca30af 100644 --- a/Source/VersOne.Epub.Test/Unit/Readers/SpineReaderTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Readers/SpineReaderTests.cs @@ -206,6 +206,7 @@ private static EpubSchema CreateEpubSchema(EpubManifest? manifest = null, EpubSp ( package: new EpubPackage ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: manifest ?? new EpubManifest(), diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Collections/EpubCollectionTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Collections/EpubCollectionTests.cs new file mode 100644 index 0000000..3c70f40 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Collections/EpubCollectionTests.cs @@ -0,0 +1,172 @@ +using VersOne.Epub.Schema; +using VersOne.Epub.Test.Comparers; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Collections +{ + public class EpubCollectionTests + { + private const string ROLE = "http://example.org/roles/group"; + private const string ID = ""; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + private static EpubMetadata Metadata => + new + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title for outer collection", + id: "collection-outer-title", + textDirection: EpubTextDirection.LEFT_TO_RIGHT, + language: "en" + ) + } + ); + + private static List NestedCollections => + new() + { + new EpubCollection + ( + role: "http://example.org/roles/unit", + metadata: new EpubMetadata + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: "Test title for inner collection", + id: "collection-inner-title", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + } + ), + nestedCollections: new List(), + links: new List(), + id: "collection-inner", + textDirection: EpubTextDirection.RIGHT_TO_LEFT, + language: "is" + ) + }; + + private static List Links => + new() + { + new EpubMetadataLink + ( + href: "https://example.com/onix/123", + id: "collection-outer-link", + mediaType: "application/xml", + properties: new List() + { + EpubMetadataLinkProperty.ONIX + }, + relationships: new List() + { + EpubMetadataLinkRelationship.RECORD, + EpubMetadataLinkRelationship.ONIX_RECORD + } + ) + }; + + [Fact(DisplayName = "Constructing a EpubCollection instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, NestedCollections, Links, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if contributor parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubCollection(null!, Metadata, NestedCollections, Links, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null metadata parameter should succeed")] + public void ConstructorWithNullMetadataTest() + { + EpubCollection epubCollection = new(ROLE, null, NestedCollections, Links, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + Assert.Null(epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null nestedCollections parameter should succeed")] + public void ConstructorWithNullNestedCollectionsTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, null, Links, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(new List(), epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null links parameter should succeed")] + public void ConstructorWithNullLinksTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, NestedCollections, null, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(new List(), epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, NestedCollections, Links, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Null(epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, NestedCollections, Links, ID, null, LANGUAGE); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Null(epubCollection.TextDirection); + Assert.Equal(LANGUAGE, epubCollection.Language); + } + + [Fact(DisplayName = "Constructing a EpubCollection instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubCollection epubCollection = new(ROLE, Metadata, NestedCollections, Links, ID, TEXT_DIRECTION, null); + Assert.Equal(ROLE, epubCollection.Role); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubCollection.Metadata); + EpubPackageComparer.CompareEpubCollectionLists(NestedCollections, epubCollection.NestedCollections); + EpubMetadataComparer.CompareEpubMetadataLinkLists(Links, epubCollection.Links); + Assert.Equal(ID, epubCollection.Id); + Assert.Equal(TEXT_DIRECTION, epubCollection.TextDirection); + Assert.Null(epubCollection.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Common/EpubTextDirectionTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Common/EpubTextDirectionTests.cs new file mode 100644 index 0000000..a5f0d8a --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Common/EpubTextDirectionTests.cs @@ -0,0 +1,19 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Common +{ + public class EpubTextDirectionTests + { + [Theory(DisplayName = "Converting a string to EpubTextDirection should succeed")] + [InlineData("ltr", EpubTextDirection.LEFT_TO_RIGHT)] + [InlineData("rtl", EpubTextDirection.RIGHT_TO_LEFT)] + [InlineData("test-unknown-property", EpubTextDirection.UNKNOWN)] + [InlineData("", EpubTextDirection.UNKNOWN)] + [InlineData(null, EpubTextDirection.UNKNOWN)] + public void ParseTest(string stringValue, EpubTextDirection expectedTextDirection) + { + EpubTextDirection actualTextDirection = EpubTextDirectionParser.Parse(stringValue); + Assert.Equal(expectedTextDirection, actualTextDirection); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataContributorTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataContributorTests.cs deleted file mode 100644 index a1ed031..0000000 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataContributorTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -using VersOne.Epub.Schema; - -namespace VersOne.Epub.Test.Unit.Schema.Opf -{ - public class EpubMetadataContributorTests - { - private const string ID = "contributor"; - private const string CONTRIBUTOR = "John Editor"; - private const string FILE_AS = "Editor, John"; - private const string ROLE = "editor"; - - [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with non-null parameters should succeed")] - public void ConstructorWithNonNullParametersTest() - { - EpubMetadataContributor epubMetadataContributor = new(ID, CONTRIBUTOR, FILE_AS, ROLE); - Assert.Equal(ID, epubMetadataContributor.Id); - Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); - Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); - Assert.Equal(ROLE, epubMetadataContributor.Role); - } - - [Fact(DisplayName = "Constructor should throw ArgumentNullException if contributor parameter is null")] - public void ConstructorWithNullContributorTest() - { - Assert.Throws(() => new EpubMetadataContributor(ID, null!, FILE_AS, ROLE)); - } - - [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null id parameter should succeed")] - public void ConstructorWithNullIdTest() - { - EpubMetadataContributor epubMetadataContributor = new(null, CONTRIBUTOR, FILE_AS, ROLE); - Assert.Null(epubMetadataContributor.Id); - Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); - Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); - Assert.Equal(ROLE, epubMetadataContributor.Role); - } - - [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null fileAs parameter should succeed")] - public void ConstructorWithNullFileAsTest() - { - EpubMetadataContributor epubMetadataContributor = new(ID, CONTRIBUTOR, null, ROLE); - Assert.Equal(ID, epubMetadataContributor.Id); - Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); - Assert.Null(epubMetadataContributor.FileAs); - Assert.Equal(ROLE, epubMetadataContributor.Role); - } - - [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null role parameter should succeed")] - public void ConstructorWithNullRoleTest() - { - EpubMetadataContributor epubMetadataContributor = new(ID, CONTRIBUTOR, FILE_AS, null); - Assert.Equal(ID, epubMetadataContributor.Id); - Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); - Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); - Assert.Null(epubMetadataContributor.Role); - } - } -} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataCreatorTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataCreatorTests.cs deleted file mode 100644 index 02f9947..0000000 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataCreatorTests.cs +++ /dev/null @@ -1,58 +0,0 @@ -using VersOne.Epub.Schema; - -namespace VersOne.Epub.Test.Unit.Schema.Opf -{ - public class EpubMetadataCreatorTests - { - private const string ID = "creator"; - private const string CREATOR = "John Doe"; - private const string FILE_AS = "Doe, John"; - private const string ROLE = "author"; - - [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with non-null parameters should succeed")] - public void ConstructorWithNonNullParametersTest() - { - EpubMetadataCreator epubMetadataCreator = new(ID, CREATOR, FILE_AS, ROLE); - Assert.Equal(ID, epubMetadataCreator.Id); - Assert.Equal(CREATOR, epubMetadataCreator.Creator); - Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); - Assert.Equal(ROLE, epubMetadataCreator.Role); - } - - [Fact(DisplayName = "Constructor should throw ArgumentNullException if creator parameter is null")] - public void ConstructorWithNullCreatorTest() - { - Assert.Throws(() => new EpubMetadataCreator(ID, null!, FILE_AS, ROLE)); - } - - [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null id parameter should succeed")] - public void ConstructorWithNullIdTest() - { - EpubMetadataCreator epubMetadataCreator = new(null, CREATOR, FILE_AS, ROLE); - Assert.Null(epubMetadataCreator.Id); - Assert.Equal(CREATOR, epubMetadataCreator.Creator); - Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); - Assert.Equal(ROLE, epubMetadataCreator.Role); - } - - [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null fileAs parameter should succeed")] - public void ConstructorWithNullFileAsTest() - { - EpubMetadataCreator epubMetadataCreator = new(ID, CREATOR, null, ROLE); - Assert.Equal(ID, epubMetadataCreator.Id); - Assert.Equal(CREATOR, epubMetadataCreator.Creator); - Assert.Null(epubMetadataCreator.FileAs); - Assert.Equal(ROLE, epubMetadataCreator.Role); - } - - [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null role parameter should succeed")] - public void ConstructorWithNullRoleTest() - { - EpubMetadataCreator epubMetadataCreator = new(ID, CREATOR, FILE_AS, null); - Assert.Equal(ID, epubMetadataCreator.Id); - Assert.Equal(CREATOR, epubMetadataCreator.Creator); - Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); - Assert.Null(epubMetadataCreator.Role); - } - } -} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPackageTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPackageTests.cs deleted file mode 100644 index e7e74c8..0000000 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPackageTests.cs +++ /dev/null @@ -1,120 +0,0 @@ -using VersOne.Epub.Schema; -using VersOne.Epub.Test.Comparers; -using VersOne.Epub.Test.Unit.TestData; -using static VersOne.Epub.Test.Unit.TestData.TestEpubData; - -namespace VersOne.Epub.Test.Unit.Schema.Opf -{ - public class EpubPackageTests - { - private const EpubVersion EPUB_VERSION = EpubVersion.EPUB_3_1; - - private static EpubMetadata Metadata => - new - ( - titles: new List() - { - BOOK_TITLE - }, - creators: new List() - { - new EpubMetadataCreator - ( - creator: BOOK_AUTHOR - ) - }, - description: BOOK_DESCRIPTION - ); - - private static EpubManifest Manifest => TestEpubManifests.CreateFullTestEpubManifest(); - - private static EpubSpine Spine => - new - ( - toc: "ncx", - items: new List() - { - new EpubSpineItemRef - ( - id: "itemref-1", - idRef: "item-1", - isLinear: true - ), - new EpubSpineItemRef - ( - id: "itemref-2", - idRef: "item-2", - isLinear: true - ) - } - ); - - private static EpubGuide Guide => - new - ( - items: new List() - { - new EpubGuideReference - ( - type: "toc", - title: "Contents", - href: "toc.html" - ) - } - ); - - [Fact(DisplayName = "Constructing a EpubPackage instance with non-null parameters should succeed")] - public void ConstructorWithNonNullParametersTest() - { - EpubPackage epubPackage = new(EPUB_VERSION, Metadata, Manifest, Spine, Guide); - Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); - EpubPackageComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); - EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); - EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); - EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); - } - - [Fact(DisplayName = "Constructor should throw ArgumentNullException if metadata parameter is null")] - public void ConstructorWithNullMetadataTest() - { - Assert.Throws(() => new EpubPackage(EPUB_VERSION, null!, Manifest, Spine, Guide)); - } - - [Fact(DisplayName = "Constructor should throw ArgumentNullException if manifest parameter is null")] - public void ConstructorWithNullManifestTest() - { - Assert.Throws(() => new EpubPackage(EPUB_VERSION, Metadata, null!, Spine, Guide)); - } - - [Fact(DisplayName = "Constructor should throw ArgumentNullException if spine parameter is null")] - public void ConstructorWithNullSpineTest() - { - Assert.Throws(() => new EpubPackage(EPUB_VERSION, Metadata, Manifest, null!, Guide)); - } - - [Fact(DisplayName = "Constructing a EpubPackage instance with null guide parameter should succeed")] - public void ConstructorWithNullGuideTest() - { - EpubPackage epubPackage = new(EPUB_VERSION, Metadata, Manifest, Spine, null); - Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); - EpubPackageComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); - EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); - EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); - EpubPackageComparer.CompareEpubGuides(null, epubPackage.Guide); - } - - [Fact(DisplayName = "GetVersionString should return a string representation of the EpubVersion property")] - public void GetVersionStringTest() - { - EpubPackage epubPackage = new - ( - epubVersion: EPUB_VERSION, - metadata: new EpubMetadata(), - manifest: new EpubManifest(), - spine: new EpubSpine(), - guide: null - ); - Assert.Equal("3.1", epubPackage.GetVersionString()); - } - } -} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideReferenceTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideReferenceTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideReferenceTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideReferenceTests.cs index d2a5b47..75f83b4 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideReferenceTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideReferenceTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Guide { public class EpubGuideReferenceTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideTests.cs similarity index 92% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideTests.cs index 76957ab..39e25f4 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubGuideTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Guide/EpubGuideTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Guide { public class EpubGuideTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestItemTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestItemTests.cs similarity index 97% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestItemTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestItemTests.cs index da28816..e36a484 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestItemTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestItemTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Manifest { public class EpubManifestItemTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestPropertyTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestPropertyTests.cs similarity index 94% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestPropertyTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestPropertyTests.cs index fcac7b7..655afa1 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubManifestPropertyTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Manifest/EpubManifestPropertyTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Manifest { public class EpubManifestPropertyTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataContributorTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataContributorTests.cs new file mode 100644 index 0000000..8a1cac3 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataContributorTests.cs @@ -0,0 +1,92 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataContributorTests + { + private const string CONTRIBUTOR = "John Editor"; + private const string ID = "contributor"; + private const string FILE_AS = "Editor, John"; + private const string ROLE = "editor"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, ID, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Equal(ID, epubMetadataContributor.Id); + Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); + Assert.Equal(ROLE, epubMetadataContributor.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataContributor.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataContributor.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if contributor parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataContributor(null!, ID, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, null, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Null(epubMetadataContributor.Id); + Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); + Assert.Equal(ROLE, epubMetadataContributor.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataContributor.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataContributor.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null fileAs parameter should succeed")] + public void ConstructorWithNullFileAsTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, ID, null, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Equal(ID, epubMetadataContributor.Id); + Assert.Null(epubMetadataContributor.FileAs); + Assert.Equal(ROLE, epubMetadataContributor.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataContributor.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataContributor.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null role parameter should succeed")] + public void ConstructorWithNullRoleTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, ID, FILE_AS, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Equal(ID, epubMetadataContributor.Id); + Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); + Assert.Null(epubMetadataContributor.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataContributor.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataContributor.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, ID, FILE_AS, ROLE, null, LANGUAGE); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Equal(ID, epubMetadataContributor.Id); + Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); + Assert.Equal(ROLE, epubMetadataContributor.Role); + Assert.Null(epubMetadataContributor.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataContributor.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataContributor instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataContributor epubMetadataContributor = new(CONTRIBUTOR, ID, FILE_AS, ROLE, TEXT_DIRECTION, null); + Assert.Equal(CONTRIBUTOR, epubMetadataContributor.Contributor); + Assert.Equal(ID, epubMetadataContributor.Id); + Assert.Equal(FILE_AS, epubMetadataContributor.FileAs); + Assert.Equal(ROLE, epubMetadataContributor.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataContributor.TextDirection); + Assert.Null(epubMetadataContributor.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCoverageTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCoverageTests.cs new file mode 100644 index 0000000..d36510e --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCoverageTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataCoverageTests + { + private const string COVERAGE = "1700-1850"; + private const string ID = "coverage"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataCoverage instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataCoverage epubMetadataCoverage = new(COVERAGE, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(COVERAGE, epubMetadataCoverage.Coverage); + Assert.Equal(ID, epubMetadataCoverage.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataCoverage.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCoverage.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if coverage parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataCoverage(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCoverage instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataCoverage epubMetadataCoverage = new(COVERAGE, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(COVERAGE, epubMetadataCoverage.Coverage); + Assert.Null(epubMetadataCoverage.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataCoverage.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCoverage.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCoverage instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataCoverage epubMetadataCoverage = new(COVERAGE, ID, null, LANGUAGE); + Assert.Equal(COVERAGE, epubMetadataCoverage.Coverage); + Assert.Equal(ID, epubMetadataCoverage.Id); + Assert.Null(epubMetadataCoverage.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCoverage.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCoverage instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataCoverage epubMetadataCoverage = new(COVERAGE, ID, TEXT_DIRECTION, null); + Assert.Equal(COVERAGE, epubMetadataCoverage.Coverage); + Assert.Equal(ID, epubMetadataCoverage.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataCoverage.TextDirection); + Assert.Null(epubMetadataCoverage.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCreatorTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCreatorTests.cs new file mode 100644 index 0000000..ab8eebe --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataCreatorTests.cs @@ -0,0 +1,92 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataCreatorTests + { + private const string CREATOR = "John Doe"; + private const string ID = "creator"; + private const string FILE_AS = "Doe, John"; + private const string ROLE = "author"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, ID, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Equal(ID, epubMetadataCreator.Id); + Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); + Assert.Equal(ROLE, epubMetadataCreator.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataCreator.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCreator.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if creator parameter is null")] + public void ConstructorWithNullCreatorTest() + { + Assert.Throws(() => new EpubMetadataCreator(null!, ID, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, null, FILE_AS, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Null(epubMetadataCreator.Id); + Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); + Assert.Equal(ROLE, epubMetadataCreator.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataCreator.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCreator.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null fileAs parameter should succeed")] + public void ConstructorWithNullFileAsTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, ID, null, ROLE, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Equal(ID, epubMetadataCreator.Id); + Assert.Null(epubMetadataCreator.FileAs); + Assert.Equal(ROLE, epubMetadataCreator.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataCreator.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCreator.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null role parameter should succeed")] + public void ConstructorWithNullRoleTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, ID, FILE_AS, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Equal(ID, epubMetadataCreator.Id); + Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); + Assert.Null(epubMetadataCreator.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataCreator.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCreator.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, ID, FILE_AS, ROLE, null, LANGUAGE); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Equal(ID, epubMetadataCreator.Id); + Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); + Assert.Equal(ROLE, epubMetadataCreator.Role); + Assert.Null(epubMetadataCreator.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataCreator.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataCreator instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataCreator epubMetadataCreator = new(CREATOR, ID, FILE_AS, ROLE, TEXT_DIRECTION, null); + Assert.Equal(CREATOR, epubMetadataCreator.Creator); + Assert.Equal(ID, epubMetadataCreator.Id); + Assert.Equal(FILE_AS, epubMetadataCreator.FileAs); + Assert.Equal(ROLE, epubMetadataCreator.Role); + Assert.Equal(TEXT_DIRECTION, epubMetadataCreator.TextDirection); + Assert.Null(epubMetadataCreator.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataDateTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDateTests.cs similarity index 55% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataDateTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDateTests.cs index 356003c..a409c26 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataDateTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDateTests.cs @@ -1,31 +1,43 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataDateTests { private const string DATE = "2021-12-31T23:59:59.123456Z"; + private const string ID = "date"; private const string EVENT = "publication"; [Fact(DisplayName = "Constructing a EpubMetadataDate instance with non-null parameters should succeed")] public void ConstructorWithNonNullParametersTest() { - EpubMetadataDate epubMetadataDate = new(DATE, EVENT); + EpubMetadataDate epubMetadataDate = new(DATE, ID, EVENT); Assert.Equal(DATE, epubMetadataDate.Date); + Assert.Equal(ID, epubMetadataDate.Id); Assert.Equal(EVENT, epubMetadataDate.Event); } [Fact(DisplayName = "Constructor should throw ArgumentNullException if date parameter is null")] public void ConstructorWithNullDateTest() { - Assert.Throws(() => new EpubMetadataDate(null!, EVENT)); + Assert.Throws(() => new EpubMetadataDate(null!, ID, EVENT)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataDate instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataDate epubMetadataDate = new(DATE, null, EVENT); + Assert.Equal(DATE, epubMetadataDate.Date); + Assert.Null(epubMetadataDate.Id); + Assert.Equal(EVENT, epubMetadataDate.Event); } [Fact(DisplayName = "Constructing a EpubMetadataDate instance with null event parameter should succeed")] public void ConstructorWithNullEventTest() { - EpubMetadataDate epubMetadataDate = new(DATE, null); + EpubMetadataDate epubMetadataDate = new(DATE, ID, null); Assert.Equal(DATE, epubMetadataDate.Date); + Assert.Equal(ID, epubMetadataDate.Id); Assert.Null(epubMetadataDate.Event); } } diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDescriptionTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDescriptionTests.cs new file mode 100644 index 0000000..80350f2 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataDescriptionTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataDescriptionTests + { + private const string DESCRIPTION = "Test Description"; + private const string ID = "description"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataDescription instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataDescription epubMetadataDescription = new(DESCRIPTION, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(DESCRIPTION, epubMetadataDescription.Description); + Assert.Equal(ID, epubMetadataDescription.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataDescription.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataDescription.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if description parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataDescription(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataDescription instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataDescription epubMetadataDescription = new(DESCRIPTION, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(DESCRIPTION, epubMetadataDescription.Description); + Assert.Null(epubMetadataDescription.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataDescription.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataDescription.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataDescription instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataDescription epubMetadataDescription = new(DESCRIPTION, ID, null, LANGUAGE); + Assert.Equal(DESCRIPTION, epubMetadataDescription.Description); + Assert.Equal(ID, epubMetadataDescription.Id); + Assert.Null(epubMetadataDescription.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataDescription.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataDescription instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataDescription epubMetadataDescription = new(DESCRIPTION, ID, TEXT_DIRECTION, null); + Assert.Equal(DESCRIPTION, epubMetadataDescription.Description); + Assert.Equal(ID, epubMetadataDescription.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataDescription.TextDirection); + Assert.Null(epubMetadataDescription.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataFormatTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataFormatTests.cs new file mode 100644 index 0000000..9b4c49a --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataFormatTests.cs @@ -0,0 +1,32 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataFormatTests + { + private const string FORMAT = "test-format"; + private const string ID = "format"; + + [Fact(DisplayName = "Constructing a EpubMetadataFormat instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataFormat epubMetadataFormat = new(FORMAT, ID); + Assert.Equal(FORMAT, epubMetadataFormat.Format); + Assert.Equal(ID, epubMetadataFormat.Id); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if format parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataFormat(null!, ID)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataFormat instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataFormat epubMetadataFormat = new(FORMAT, null); + Assert.Equal(FORMAT, epubMetadataFormat.Format); + Assert.Null(epubMetadataFormat.Id); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataIdentifierTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataIdentifierTests.cs similarity index 89% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataIdentifierTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataIdentifierTests.cs index dc3f178..19530c5 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataIdentifierTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataIdentifierTests.cs @@ -1,44 +1,44 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataIdentifierTests { + private const string IDENTIFIER = "9781234567890"; private const string ID = "identifier"; private const string SCHEME = "ISBN"; - private const string IDENTIFIER = "9781234567890"; [Fact(DisplayName = "Constructing a EpubMetadataIdentifier instance with non-null parameters should succeed")] public void ConstructorWithNonNullParametersTest() { - EpubMetadataIdentifier epubMetadataIdentifier = new(ID, SCHEME, IDENTIFIER); + EpubMetadataIdentifier epubMetadataIdentifier = new(IDENTIFIER, ID, SCHEME); + Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); Assert.Equal(ID, epubMetadataIdentifier.Id); Assert.Equal(SCHEME, epubMetadataIdentifier.Scheme); - Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); } [Fact(DisplayName = "Constructor should throw ArgumentNullException if identifier parameter is null")] public void ConstructorWithNullIdentifierTest() { - Assert.Throws(() => new EpubMetadataIdentifier(ID, SCHEME, null!)); + Assert.Throws(() => new EpubMetadataIdentifier(null!, ID, SCHEME)); } [Fact(DisplayName = "Constructing a EpubMetadataIdentifier instance with null id parameter should succeed")] public void ConstructorWithNullIdTest() { - EpubMetadataIdentifier epubMetadataIdentifier = new(null, SCHEME, IDENTIFIER); + EpubMetadataIdentifier epubMetadataIdentifier = new(IDENTIFIER, null, SCHEME); + Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); Assert.Null(epubMetadataIdentifier.Id); Assert.Equal(SCHEME, epubMetadataIdentifier.Scheme); - Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); } [Fact(DisplayName = "Constructing a EpubMetadataIdentifier instance with null scheme parameter should succeed")] public void ConstructorWithNullSchemeTest() { - EpubMetadataIdentifier epubMetadataIdentifier = new(ID, null, IDENTIFIER); + EpubMetadataIdentifier epubMetadataIdentifier = new(IDENTIFIER, ID, null); + Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); Assert.Equal(ID, epubMetadataIdentifier.Id); Assert.Null(epubMetadataIdentifier.Scheme); - Assert.Equal(IDENTIFIER, epubMetadataIdentifier.Identifier); } } } diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLanguageTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLanguageTests.cs new file mode 100644 index 0000000..b9f10d3 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLanguageTests.cs @@ -0,0 +1,32 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataLanguageTests + { + private const string LANGUAGE = "en"; + private const string ID = "language"; + + [Fact(DisplayName = "Constructing a EpubMetadataLanguage instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataLanguage epubMetadataLanguage = new(LANGUAGE, ID); + Assert.Equal(LANGUAGE, epubMetadataLanguage.Language); + Assert.Equal(ID, epubMetadataLanguage.Id); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if language parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataLanguage(null!, ID)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataLanguage instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataLanguage epubMetadataLanguage = new(LANGUAGE, null); + Assert.Equal(LANGUAGE, epubMetadataLanguage.Language); + Assert.Null(epubMetadataLanguage.Id); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkPropertyTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkPropertyTests.cs similarity index 93% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkPropertyTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkPropertyTests.cs index c6ee712..0eeb62e 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkPropertyTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkPropertyTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataLinkPropertyTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkRelationshipTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkRelationshipTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkRelationshipTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkRelationshipTests.cs index 243d050..aed1490 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkRelationshipTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkRelationshipTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataLinkRelationshipTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkTests.cs similarity index 85% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkTests.cs index 2c5860a..23b363c 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataLinkTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataLinkTests.cs @@ -1,11 +1,11 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataLinkTests { - private const string ID = "link"; private const string HREF = "https://example.com/onix/123"; + private const string ID = "link"; private const string MEDIA_TYPE = "application/xml"; private const string REFINES = "#title"; @@ -25,9 +25,9 @@ public class EpubMetadataLinkTests [Fact(DisplayName = "Constructing a EpubMetadataLink instance with non-null parameters should succeed")] public void ConstructorWithNonNullParametersTest() { - EpubMetadataLink epubMetadataLink = new(ID, HREF, MEDIA_TYPE, Properties, REFINES, Relationships); - Assert.Equal(ID, epubMetadataLink.Id); + EpubMetadataLink epubMetadataLink = new(HREF, ID, MEDIA_TYPE, Properties, REFINES, Relationships); Assert.Equal(HREF, epubMetadataLink.Href); + Assert.Equal(ID, epubMetadataLink.Id); Assert.Equal(MEDIA_TYPE, epubMetadataLink.MediaType); Assert.Equal(Properties, epubMetadataLink.Properties); Assert.Equal(REFINES, epubMetadataLink.Refines); @@ -37,15 +37,15 @@ public void ConstructorWithNonNullParametersTest() [Fact(DisplayName = "Constructor should throw ArgumentNullException if href parameter is null")] public void ConstructorWithNullHrefTest() { - Assert.Throws(() => new EpubMetadataLink(ID, null!, MEDIA_TYPE, Properties, REFINES, Relationships)); + Assert.Throws(() => new EpubMetadataLink(null!, ID, MEDIA_TYPE, Properties, REFINES, Relationships)); } [Fact(DisplayName = "Constructing a EpubMetadataLink instance with null id parameter should succeed")] public void ConstructorWithNullIdTest() { - EpubMetadataLink epubMetadataLink = new(null, HREF, MEDIA_TYPE, Properties, REFINES, Relationships); - Assert.Null(epubMetadataLink.Id); + EpubMetadataLink epubMetadataLink = new(HREF, null, MEDIA_TYPE, Properties, REFINES, Relationships); Assert.Equal(HREF, epubMetadataLink.Href); + Assert.Null(epubMetadataLink.Id); Assert.Equal(MEDIA_TYPE, epubMetadataLink.MediaType); Assert.Equal(Properties, epubMetadataLink.Properties); Assert.Equal(REFINES, epubMetadataLink.Refines); @@ -55,9 +55,9 @@ public void ConstructorWithNullIdTest() [Fact(DisplayName = "Constructing a EpubMetadataLink instance with null mediaType parameter should succeed")] public void ConstructorWithNullMediaTypeTest() { - EpubMetadataLink epubMetadataLink = new(ID, HREF, null, Properties, REFINES, Relationships); - Assert.Equal(ID, epubMetadataLink.Id); + EpubMetadataLink epubMetadataLink = new(HREF, ID, null, Properties, REFINES, Relationships); Assert.Equal(HREF, epubMetadataLink.Href); + Assert.Equal(ID, epubMetadataLink.Id); Assert.Null(epubMetadataLink.MediaType); Assert.Equal(Properties, epubMetadataLink.Properties); Assert.Equal(REFINES, epubMetadataLink.Refines); @@ -67,9 +67,9 @@ public void ConstructorWithNullMediaTypeTest() [Fact(DisplayName = "Constructing a EpubMetadataLink instance with null properties parameter should succeed")] public void ConstructorWithNullPropertiesTest() { - EpubMetadataLink epubMetadataLink = new(ID, HREF, MEDIA_TYPE, null, REFINES, Relationships); + EpubMetadataLink epubMetadataLink = new(HREF, ID, MEDIA_TYPE, null, REFINES, Relationships); + Assert.Equal(HREF, epubMetadataLink.Href); Assert.Equal(ID, epubMetadataLink.Id); - Assert.Equal(HREF, epubMetadataLink.Href); Assert.Equal(MEDIA_TYPE, epubMetadataLink.MediaType); Assert.Null(epubMetadataLink.Properties); Assert.Equal(REFINES, epubMetadataLink.Refines); @@ -79,9 +79,9 @@ public void ConstructorWithNullPropertiesTest() [Fact(DisplayName = "Constructing a EpubMetadataLink instance with null refines parameter should succeed")] public void ConstructorWithNullRefinesTest() { - EpubMetadataLink epubMetadataLink = new(ID, HREF, MEDIA_TYPE, Properties, null, Relationships); + EpubMetadataLink epubMetadataLink = new(HREF, ID, MEDIA_TYPE, Properties, null, Relationships); + Assert.Equal(HREF, epubMetadataLink.Href); Assert.Equal(ID, epubMetadataLink.Id); - Assert.Equal(HREF, epubMetadataLink.Href); Assert.Equal(MEDIA_TYPE, epubMetadataLink.MediaType); Assert.Equal(Properties, epubMetadataLink.Properties); Assert.Null(epubMetadataLink.Refines); @@ -91,9 +91,9 @@ public void ConstructorWithNullRefinesTest() [Fact(DisplayName = "Constructing a EpubMetadataLink instance with null relationships parameter should succeed")] public void ConstructorWithNullRelationshipsTest() { - EpubMetadataLink epubMetadataLink = new(ID, HREF, MEDIA_TYPE, Properties, REFINES, null); - Assert.Equal(ID, epubMetadataLink.Id); + EpubMetadataLink epubMetadataLink = new(HREF, ID, MEDIA_TYPE, Properties, REFINES, null); Assert.Equal(HREF, epubMetadataLink.Href); + Assert.Equal(ID, epubMetadataLink.Id); Assert.Equal(MEDIA_TYPE, epubMetadataLink.MediaType); Assert.Equal(Properties, epubMetadataLink.Properties); Assert.Equal(REFINES, epubMetadataLink.Refines); diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataMetaTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataMetaTests.cs similarity index 96% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataMetaTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataMetaTests.cs index f4ab6b6..8fee88c 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubMetadataMetaTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataMetaTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata { public class EpubMetadataMetaTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataPublisherTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataPublisherTests.cs new file mode 100644 index 0000000..2cd7ac1 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataPublisherTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataPublisherTests + { + private const string PUBLISHER = "Test Publisher"; + private const string ID = "publisher"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataPublisher instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataPublisher epubMetadataPublisher = new(PUBLISHER, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(PUBLISHER, epubMetadataPublisher.Publisher); + Assert.Equal(ID, epubMetadataPublisher.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataPublisher.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataPublisher.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if publisher parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataPublisher(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataPublisher instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataPublisher epubMetadataPublisher = new(PUBLISHER, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(PUBLISHER, epubMetadataPublisher.Publisher); + Assert.Null(epubMetadataPublisher.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataPublisher.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataPublisher.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataPublisher instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataPublisher epubMetadataPublisher = new(PUBLISHER, ID, null, LANGUAGE); + Assert.Equal(PUBLISHER, epubMetadataPublisher.Publisher); + Assert.Equal(ID, epubMetadataPublisher.Id); + Assert.Null(epubMetadataPublisher.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataPublisher.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataPublisher instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataPublisher epubMetadataPublisher = new(PUBLISHER, ID, TEXT_DIRECTION, null); + Assert.Equal(PUBLISHER, epubMetadataPublisher.Publisher); + Assert.Equal(ID, epubMetadataPublisher.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataPublisher.TextDirection); + Assert.Null(epubMetadataPublisher.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRelationTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRelationTests.cs new file mode 100644 index 0000000..4bc0517 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRelationTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataRelationTests + { + private const string RELATION = "https://example.com/books/123/related.html"; + private const string ID = "relation"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataRelation instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataRelation epubMetadataRelation = new(RELATION, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(RELATION, epubMetadataRelation.Relation); + Assert.Equal(ID, epubMetadataRelation.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRelation.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRelation.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if relation parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataRelation(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRelation instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataRelation epubMetadataRelation = new(RELATION, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(RELATION, epubMetadataRelation.Relation); + Assert.Null(epubMetadataRelation.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRelation.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRelation.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRelation instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataRelation epubMetadataRelation = new(RELATION, ID, null, LANGUAGE); + Assert.Equal(RELATION, epubMetadataRelation.Relation); + Assert.Equal(ID, epubMetadataRelation.Id); + Assert.Null(epubMetadataRelation.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRelation.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRelation instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataRelation epubMetadataRelation = new(RELATION, ID, TEXT_DIRECTION, null); + Assert.Equal(RELATION, epubMetadataRelation.Relation); + Assert.Equal(ID, epubMetadataRelation.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRelation.TextDirection); + Assert.Null(epubMetadataRelation.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRightsTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRightsTests.cs new file mode 100644 index 0000000..16e8808 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataRightsTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataRightsTests + { + private const string RIGHTS = "All rights reserved"; + private const string ID = "rights"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataRights instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataRights epubMetadataRights = new(RIGHTS, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(RIGHTS, epubMetadataRights.Rights); + Assert.Equal(ID, epubMetadataRights.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRights.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRights.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if rights parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataRights(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRights instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataRights epubMetadataRights = new(RIGHTS, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(RIGHTS, epubMetadataRights.Rights); + Assert.Null(epubMetadataRights.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRights.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRights.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRights instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataRights epubMetadataRights = new(RIGHTS, ID, null, LANGUAGE); + Assert.Equal(RIGHTS, epubMetadataRights.Rights); + Assert.Equal(ID, epubMetadataRights.Id); + Assert.Null(epubMetadataRights.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataRights.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataRights instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataRights epubMetadataRights = new(RIGHTS, ID, TEXT_DIRECTION, null); + Assert.Equal(RIGHTS, epubMetadataRights.Rights); + Assert.Equal(ID, epubMetadataRights.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataRights.TextDirection); + Assert.Null(epubMetadataRights.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSourceTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSourceTests.cs new file mode 100644 index 0000000..005b44d --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSourceTests.cs @@ -0,0 +1,32 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataSourceTests + { + private const string SOURCE = "https://example.com/books/123/content.html"; + private const string ID = "source"; + + [Fact(DisplayName = "Constructing a EpubMetadataSource instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataSource epubMetadataSource = new(SOURCE, ID); + Assert.Equal(SOURCE, epubMetadataSource.Source); + Assert.Equal(ID, epubMetadataSource.Id); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if source parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataSource(null!, ID)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataSource instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataSource epubMetadataSource = new(SOURCE, null); + Assert.Equal(SOURCE, epubMetadataSource.Source); + Assert.Null(epubMetadataSource.Id); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSubjectTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSubjectTests.cs new file mode 100644 index 0000000..372c223 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataSubjectTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataSubjectTests + { + private const string SUBJECT = "Test Subject"; + private const string ID = "subject"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataSubject instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataSubject epubMetadataSubject = new(SUBJECT, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(SUBJECT, epubMetadataSubject.Subject); + Assert.Equal(ID, epubMetadataSubject.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataSubject.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataSubject.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if subject parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataSubject(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataSubject instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataSubject epubMetadataSubject = new(SUBJECT, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(SUBJECT, epubMetadataSubject.Subject); + Assert.Null(epubMetadataSubject.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataSubject.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataSubject.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataSubject instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataSubject epubMetadataSubject = new(SUBJECT, ID, null, LANGUAGE); + Assert.Equal(SUBJECT, epubMetadataSubject.Subject); + Assert.Equal(ID, epubMetadataSubject.Id); + Assert.Null(epubMetadataSubject.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataSubject.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataSubject instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataSubject epubMetadataSubject = new(SUBJECT, ID, TEXT_DIRECTION, null); + Assert.Equal(SUBJECT, epubMetadataSubject.Subject); + Assert.Equal(ID, epubMetadataSubject.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataSubject.TextDirection); + Assert.Null(epubMetadataSubject.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTitleTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTitleTests.cs new file mode 100644 index 0000000..01f57cd --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTitleTests.cs @@ -0,0 +1,58 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataTitleTests + { + private const string TITLE = "Test Title"; + private const string ID = "title"; + private const EpubTextDirection TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string LANGUAGE = "en"; + + [Fact(DisplayName = "Constructing a EpubMetadataTitle instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataTitle epubMetadataTitle = new(TITLE, ID, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(TITLE, epubMetadataTitle.Title); + Assert.Equal(ID, epubMetadataTitle.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataTitle.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataTitle.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if title parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataTitle(null!, ID, TEXT_DIRECTION, LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataTitle instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataTitle epubMetadataTitle = new(TITLE, null, TEXT_DIRECTION, LANGUAGE); + Assert.Equal(TITLE, epubMetadataTitle.Title); + Assert.Null(epubMetadataTitle.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataTitle.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataTitle.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataTitle instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubMetadataTitle epubMetadataTitle = new(TITLE, ID, null, LANGUAGE); + Assert.Equal(TITLE, epubMetadataTitle.Title); + Assert.Equal(ID, epubMetadataTitle.Id); + Assert.Null(epubMetadataTitle.TextDirection); + Assert.Equal(LANGUAGE, epubMetadataTitle.Language); + } + + [Fact(DisplayName = "Constructing a EpubMetadataTitle instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubMetadataTitle epubMetadataTitle = new(TITLE, ID, TEXT_DIRECTION, null); + Assert.Equal(TITLE, epubMetadataTitle.Title); + Assert.Equal(ID, epubMetadataTitle.Id); + Assert.Equal(TEXT_DIRECTION, epubMetadataTitle.TextDirection); + Assert.Null(epubMetadataTitle.Language); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTypeTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTypeTests.cs new file mode 100644 index 0000000..96dd157 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Metadata/EpubMetadataTypeTests.cs @@ -0,0 +1,32 @@ +using VersOne.Epub.Schema; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Metadata +{ + public class EpubMetadataTypeTests + { + private const string TYPE = "dictionary"; + private const string ID = "type"; + + [Fact(DisplayName = "Constructing a EpubMetadataType instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubMetadataType epubMetadataType = new(TYPE, ID); + Assert.Equal(TYPE, epubMetadataType.Type); + Assert.Equal(ID, epubMetadataType.Id); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if type parameter is null")] + public void ConstructorWithNullContributorTest() + { + Assert.Throws(() => new EpubMetadataType(null!, ID)); + } + + [Fact(DisplayName = "Constructing a EpubMetadataType instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubMetadataType epubMetadataType = new(TYPE, null); + Assert.Equal(TYPE, epubMetadataType.Type); + Assert.Null(epubMetadataType.Id); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/Package/EpubPackageTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Package/EpubPackageTests.cs new file mode 100644 index 0000000..68f41b3 --- /dev/null +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Package/EpubPackageTests.cs @@ -0,0 +1,263 @@ +using VersOne.Epub.Schema; +using VersOne.Epub.Test.Comparers; +using VersOne.Epub.Test.Unit.TestData; +using static VersOne.Epub.Test.Unit.TestData.TestEpubData; + +namespace VersOne.Epub.Test.Unit.Schema.Opf.Package +{ + public class EpubPackageTests + { + private const EpubVersion EPUB_VERSION = EpubVersion.EPUB_3_1; + private const string PACKAGE_ID = "package-id"; + private const EpubTextDirection PACKAGE_TEXT_DIRECTION = EpubTextDirection.LEFT_TO_RIGHT; + private const string PACKAGE_PREFIX = "foaf: http://xmlns.com/foaf/spec/"; + private const string PACKAGE_LANGUAGE = "en"; + + private static EpubMetadata Metadata => + new + ( + titles: new List() + { + new EpubMetadataTitle + ( + title: BOOK_TITLE + ) + }, + creators: new List() + { + new EpubMetadataCreator + ( + creator: BOOK_AUTHOR + ) + }, + descriptions: new List() + { + new EpubMetadataDescription + ( + description: BOOK_DESCRIPTION + ) + }, + identifiers: new List() + { + new EpubMetadataIdentifier + ( + identifier: BOOK_UID, + id: BOOK_IDENTIFIER_ID + ) + } + ); + + private static EpubManifest Manifest => TestEpubManifests.CreateFullTestEpubManifest(); + + private static EpubSpine Spine => + new + ( + toc: "ncx", + items: new List() + { + new EpubSpineItemRef + ( + id: "itemref-1", + idRef: "item-1", + isLinear: true + ), + new EpubSpineItemRef + ( + id: "itemref-2", + idRef: "item-2", + isLinear: true + ) + } + ); + + private static EpubGuide Guide => + new + ( + items: new List() + { + new EpubGuideReference + ( + type: "toc", + title: "Contents", + href: "toc.html" + ) + } + ); + + private static List Collections => + new() + { + new EpubCollection + ( + role: COLLECTION_ROLE + ) + }; + + [Fact(DisplayName = "Constructing a EpubPackage instance with non-null parameters should succeed")] + public void ConstructorWithNonNullParametersTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null uniqueIdentifier parameter should succeed")] + public void ConstructorWithNullUniqueIdentifierTest() + { + EpubPackage epubPackage = + new(null, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE); + Assert.Null(epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if metadata parameter is null")] + public void ConstructorWithNullMetadataTest() + { + Assert.Throws(() => + new EpubPackage(BOOK_IDENTIFIER_ID, EPUB_VERSION, null!, Manifest, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE)); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if manifest parameter is null")] + public void ConstructorWithNullManifestTest() + { + Assert.Throws(() => + new EpubPackage(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, null!, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE)); + } + + [Fact(DisplayName = "Constructor should throw ArgumentNullException if spine parameter is null")] + public void ConstructorWithNullSpineTest() + { + Assert.Throws(() => + new EpubPackage(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, null!, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE)); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null guide parameter should succeed")] + public void ConstructorWithNullGuideTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, null, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(null, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null id parameter should succeed")] + public void ConstructorWithNullIdTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, null, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, PACKAGE_LANGUAGE); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Null(epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null textDirection parameter should succeed")] + public void ConstructorWithNullTextDirectionTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, PACKAGE_ID, null, PACKAGE_PREFIX, PACKAGE_LANGUAGE); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Null(epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null prefix parameter should succeed")] + public void ConstructorWithNullPrefixTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, null, PACKAGE_LANGUAGE); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Null(epubPackage.Prefix); + Assert.Equal(PACKAGE_LANGUAGE, epubPackage.Language); + } + + [Fact(DisplayName = "Constructing a EpubPackage instance with null language parameter should succeed")] + public void ConstructorWithNullLanguageTest() + { + EpubPackage epubPackage = + new(BOOK_IDENTIFIER_ID, EPUB_VERSION, Metadata, Manifest, Spine, Guide, Collections, PACKAGE_ID, PACKAGE_TEXT_DIRECTION, PACKAGE_PREFIX, null); + Assert.Equal(BOOK_IDENTIFIER_ID, epubPackage.UniqueIdentifier); + Assert.Equal(EPUB_VERSION, epubPackage.EpubVersion); + EpubMetadataComparer.CompareEpubMetadatas(Metadata, epubPackage.Metadata); + EpubPackageComparer.CompareEpubManifests(Manifest, epubPackage.Manifest); + EpubPackageComparer.CompareEpubSpines(Spine, epubPackage.Spine); + EpubPackageComparer.CompareEpubGuides(Guide, epubPackage.Guide); + EpubPackageComparer.CompareEpubCollectionLists(Collections, epubPackage.Collections); + Assert.Equal(PACKAGE_ID, epubPackage.Id); + Assert.Equal(PACKAGE_TEXT_DIRECTION, epubPackage.TextDirection); + Assert.Equal(PACKAGE_PREFIX, epubPackage.Prefix); + Assert.Null(epubPackage.Language); + } + + [Fact(DisplayName = "GetVersionString should return a string representation of the EpubVersion property")] + public void GetVersionStringTest() + { + EpubPackage epubPackage = new + ( + uniqueIdentifier: BOOK_IDENTIFIER_ID, + epubVersion: EPUB_VERSION, + metadata: new EpubMetadata(), + manifest: new EpubManifest(), + spine: new EpubSpine(), + guide: null, + collections: null, + id: null, + textDirection: null, + prefix: null, + language: null + ); + Assert.Equal("3.1", epubPackage.GetVersionString()); + } + } +} diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPageProgressionDirectionTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubPageProgressionDirectionTests.cs similarity index 93% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPageProgressionDirectionTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubPageProgressionDirectionTests.cs index 38e6612..96f4c65 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubPageProgressionDirectionTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubPageProgressionDirectionTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Spine { public class EpubPageProgressionDirectionTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpineItemRefTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpineItemRefTests.cs similarity index 96% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpineItemRefTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpineItemRefTests.cs index e5cd43d..6b5fad6 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpineItemRefTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpineItemRefTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Spine { public class EpubSpineItemRefTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpinePropertyTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpinePropertyTests.cs similarity index 93% rename from Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpinePropertyTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpinePropertyTests.cs index ef81208..27a3a98 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Opf/EpubSpinePropertyTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Opf/Spine/EpubSpinePropertyTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Opf +namespace VersOne.Epub.Test.Unit.Schema.Opf.Spine { public class EpubSpinePropertyTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilAudioTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilAudioTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilAudioTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilAudioTests.cs index a7a9e9c..42459f3 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilAudioTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilAudioTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilAudioTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilBodyTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilBodyTests.cs similarity index 96% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilBodyTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilBodyTests.cs index ad044d7..a27648b 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilBodyTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilBodyTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilBodyTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilHeadTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilHeadTests.cs similarity index 90% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilHeadTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilHeadTests.cs index bc8239a..5f9f534 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilHeadTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilHeadTests.cs @@ -2,7 +2,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilHeadTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilMetadataTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilMetadataTests.cs similarity index 90% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilMetadataTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilMetadataTests.cs index a5e5aef..cda51f9 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilMetadataTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilMetadataTests.cs @@ -2,7 +2,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilMetadataTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilParTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilParTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilParTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilParTests.cs index ecb7caf..c391a30 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilParTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilParTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilParTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilSeqTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilSeqTests.cs similarity index 96% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilSeqTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilSeqTests.cs index 0d483ca..b9394dd 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilSeqTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilSeqTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilSeqTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTests.cs index 4f08ff9..9f29bc3 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTextTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTextTests.cs similarity index 92% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTextTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTextTests.cs index 706b136..57020f8 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/SmilTextTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Narration/SmilTextTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Narration { public class SmilTextTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavAnchorTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavAnchorTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavAnchorTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavAnchorTests.cs index 0e6f58d..9840f19 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavAnchorTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavAnchorTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Navigation { public class Epub3NavAnchorTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavDocumentTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavDocumentTests.cs similarity index 95% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavDocumentTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavDocumentTests.cs index 18f34ba..bd11fd9 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavDocumentTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavDocumentTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Navigation { public class Epub3NavDocumentTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavSpanTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavSpanTests.cs similarity index 94% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavSpanTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavSpanTests.cs index 4caa258..0cd6535 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavSpanTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavSpanTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Navigation { public class Epub3NavSpanTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavTests.cs similarity index 94% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavTests.cs index b4694a3..774d420 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3NavTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3NavTests.cs @@ -1,7 +1,7 @@ using VersOne.Epub.Schema; using VersOne.Epub.Test.Comparers; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Navigation { public class Epub3NavTests { diff --git a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3StructuralSemanticsPropertyTests.cs b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3StructuralSemanticsPropertyTests.cs similarity index 98% rename from Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3StructuralSemanticsPropertyTests.cs rename to Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3StructuralSemanticsPropertyTests.cs index 70b95ce..70e4088 100644 --- a/Source/VersOne.Epub.Test/Unit/Schema/Ops/Epub3StructuralSemanticsPropertyTests.cs +++ b/Source/VersOne.Epub.Test/Unit/Schema/Ops/Navigation/Epub3StructuralSemanticsPropertyTests.cs @@ -1,6 +1,6 @@ using VersOne.Epub.Schema; -namespace VersOne.Epub.Test.Unit.Schema.Ops +namespace VersOne.Epub.Test.Unit.Schema.Ops.Navigation { public class Epub3StructuralSemanticsPropertyTests { diff --git a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubData.cs b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubData.cs index 268b7d5..57bfdb5 100644 --- a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubData.cs +++ b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubData.cs @@ -50,9 +50,11 @@ internal static class TestEpubData public const string REMOTE_AUDIO_CONTENT_FILE_HREF = "https://example.com/books/123/chapter1.mp3"; public const EpubContentType XML_CONTENT_TYPE = EpubContentType.XML; public const string XML_CONTENT_MIME_TYPE = "application/xml"; + public const string BOOK_IDENTIFIER_ID = "book-uid"; public const string BOOK_TITLE = "Test title"; public const string BOOK_AUTHOR = "John Doe"; public const string BOOK_DESCRIPTION = "Test description"; public const string BOOK_UID = "9781234567890"; + public const string COLLECTION_ROLE = "http://example.org/roles/unit"; } } diff --git a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubFiles.cs b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubFiles.cs index 6ca3114..353349a 100644 --- a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubFiles.cs +++ b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubFiles.cs @@ -42,11 +42,13 @@ internal static class TestEpubFiles public const string FULL_OPF_FILE_CONTENT = $""" - + {BOOK_TITLE} {BOOK_AUTHOR} {BOOK_DESCRIPTION} + {BOOK_UID} diff --git a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubPackages.cs b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubPackages.cs index fe2dd75..0ff3647 100644 --- a/Source/VersOne.Epub.Test/Unit/TestData/TestEpubPackages.cs +++ b/Source/VersOne.Epub.Test/Unit/TestData/TestEpubPackages.cs @@ -9,6 +9,7 @@ public static EpubPackage CreateMinimalTestEpubPackage() { return new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata(), manifest: TestEpubManifests.CreateMinimalTestEpubManifest(), @@ -21,6 +22,7 @@ public static EpubPackage CreateMinimalTestEpub2PackageWithoutNavigation() { return new ( + uniqueIdentifier: null, epubVersion: EpubVersion.EPUB_2, metadata: new EpubMetadata(), manifest: new EpubManifest(), @@ -33,12 +35,16 @@ public static EpubPackage CreateFullTestEpubPackage() { return new ( + uniqueIdentifier: BOOK_IDENTIFIER_ID, epubVersion: EpubVersion.EPUB_3, metadata: new EpubMetadata ( - titles: new List() + titles: new List() { - BOOK_TITLE + new EpubMetadataTitle + ( + title: BOOK_TITLE + ) }, creators: new List() { @@ -47,21 +53,21 @@ public static EpubPackage CreateFullTestEpubPackage() creator: BOOK_AUTHOR ) }, - subjects: new List(), - description: BOOK_DESCRIPTION, - publishers: new List(), - contributors: new List(), - dates: new List(), - types: new List(), - formats: new List(), - identifiers: new List(), - sources: new List(), - languages: new List(), - relations: new List(), - coverages: new List(), - rights: new List(), - links: new List(), - metaItems: new List() + descriptions: new List() + { + new EpubMetadataDescription + ( + description: BOOK_DESCRIPTION + ) + }, + identifiers: new List() + { + new EpubMetadataIdentifier + ( + identifier: BOOK_UID, + id: BOOK_IDENTIFIER_ID + ) + } ), manifest: TestEpubManifests.CreateFullTestEpubManifest(), spine: new EpubSpine diff --git a/Source/VersOne.Epub/Readers/BookRefReader.cs b/Source/VersOne.Epub/Readers/BookRefReader.cs index 4949840..8858895 100644 --- a/Source/VersOne.Epub/Readers/BookRefReader.cs +++ b/Source/VersOne.Epub/Readers/BookRefReader.cs @@ -48,10 +48,10 @@ private async Task OpenBookAsync(IZipFile epubFile, string? filePat { SchemaReader schemaReader = new(epubReaderOptions); EpubSchema schema = await schemaReader.ReadSchemaAsync(epubFile).ConfigureAwait(false); - string title = schema.Package.Metadata.Titles.FirstOrDefault() ?? String.Empty; + string title = schema.Package.Metadata.Titles.FirstOrDefault()?.Title ?? String.Empty; List authorList = schema.Package.Metadata.Creators.Select(creator => creator.Creator).ToList(); string author = String.Join(", ", authorList); - string? description = schema.Package.Metadata.Description; + string? description = schema.Package.Metadata.Descriptions.FirstOrDefault()?.Description; ContentReader contentReader = new(environmentDependencies, epubReaderOptions); EpubContentRef content = await Task.Run(() => contentReader.ParseContentMap(schema, epubFile)).ConfigureAwait(false); return new(epubFile, filePath, title, author, authorList, description, schema, content); diff --git a/Source/VersOne.Epub/Readers/Epub3NavDocumentReader.cs b/Source/VersOne.Epub/Readers/Epub3NavDocumentReader.cs index cf5b19c..f8cc769 100644 --- a/Source/VersOne.Epub/Readers/Epub3NavDocumentReader.cs +++ b/Source/VersOne.Epub/Readers/Epub3NavDocumentReader.cs @@ -35,11 +35,8 @@ public Epub3NavDocumentReader(EpubReaderOptions? epubReaderOptions = null) } } string navFileEntryPath = ZipPathUtils.Combine(contentDirectoryPath, navManifestItem.Href); - IZipFileEntry? navFileEntry = epubFile.GetEntry(navFileEntryPath); - if (navFileEntry == null) - { + IZipFileEntry navFileEntry = epubFile.GetEntry(navFileEntryPath) ?? throw new Epub3NavException($"EPUB parsing error: navigation file {navFileEntryPath} not found in the EPUB file."); - } if (navFileEntry.Length > Int32.MaxValue) { throw new Epub3NavException($"EPUB parsing error: navigation file {navFileEntryPath} is larger than 2 GB."); @@ -50,16 +47,8 @@ public Epub3NavDocumentReader(EpubReaderOptions? epubReaderOptions = null) navDocument = await XmlUtils.LoadDocumentAsync(containerStream, epubReaderOptions.XmlReaderOptions).ConfigureAwait(false); } XNamespace xhtmlNamespace = navDocument.Root.Name.Namespace; - XElement htmlNode = navDocument.Element(xhtmlNamespace + "html"); - if (htmlNode == null) - { - throw new Epub3NavException("EPUB parsing error: navigation file does not contain html element."); - } - XElement bodyNode = htmlNode.Element(xhtmlNamespace + "body"); - if (bodyNode == null) - { - throw new Epub3NavException("EPUB parsing error: navigation file does not contain body element."); - } + XElement htmlNode = navDocument.Element(xhtmlNamespace + "html") ?? throw new Epub3NavException("EPUB parsing error: navigation file does not contain html element."); + XElement bodyNode = htmlNode.Element(xhtmlNamespace + "body") ?? throw new Epub3NavException("EPUB parsing error: navigation file does not contain body element."); List navs = new(); foreach (XElement navNode in bodyNode.Elements(xhtmlNamespace + "nav")) { diff --git a/Source/VersOne.Epub/Readers/MetadataReader.cs b/Source/VersOne.Epub/Readers/MetadataReader.cs new file mode 100644 index 0000000..333cb91 --- /dev/null +++ b/Source/VersOne.Epub/Readers/MetadataReader.cs @@ -0,0 +1,403 @@ +using System.Collections.Generic; +using System.Xml.Linq; +using VersOne.Epub.Schema; +using VersOne.Epub.Utils; + +namespace VersOne.Epub.Internal +{ + internal static class MetadataReader + { + public static EpubMetadata ReadMetadata(XElement metadataNode) + { + List titles = new(); + List creators = new(); + List subjects = new(); + List descriptions = new(); + List publishers = new(); + List contributors = new(); + List dates = new(); + List types = new(); + List formats = new(); + List identifiers = new(); + List sources = new(); + List languages = new(); + List relations = new(); + List coverages = new(); + List rights = new(); + List links = new(); + List metaItems = new(); + foreach (XElement metadataItemNode in metadataNode.Elements()) + { + switch (metadataItemNode.GetLowerCaseLocalName()) + { + case "title": + EpubMetadataTitle title = ReadTitle(metadataItemNode); + titles.Add(title); + break; + case "creator": + EpubMetadataCreator creator = ReadCreator(metadataItemNode); + creators.Add(creator); + break; + case "subject": + EpubMetadataSubject subject = ReadSubject(metadataItemNode); + subjects.Add(subject); + break; + case "description": + EpubMetadataDescription description = ReadDescription(metadataItemNode); + descriptions.Add(description); + break; + case "publisher": + EpubMetadataPublisher publisher = ReadPublisher(metadataItemNode); + publishers.Add(publisher); + break; + case "contributor": + EpubMetadataContributor contributor = ReadContributor(metadataItemNode); + contributors.Add(contributor); + break; + case "date": + EpubMetadataDate date = ReadDate(metadataItemNode); + dates.Add(date); + break; + case "type": + EpubMetadataType type = ReadType(metadataItemNode); + types.Add(type); + break; + case "format": + EpubMetadataFormat format = ReadFormat(metadataItemNode); + formats.Add(format); + break; + case "identifier": + EpubMetadataIdentifier identifier = ReadIdentifier(metadataItemNode); + identifiers.Add(identifier); + break; + case "source": + EpubMetadataSource source = ReadSource(metadataItemNode); + sources.Add(source); + break; + case "language": + EpubMetadataLanguage language = ReadLanguage(metadataItemNode); + languages.Add(language); + break; + case "relation": + EpubMetadataRelation relation = ReadRelation(metadataItemNode); + relations.Add(relation); + break; + case "coverage": + EpubMetadataCoverage coverage = ReadCoverage(metadataItemNode); + coverages.Add(coverage); + break; + case "rights": + EpubMetadataRights rightsItem = ReadRightsItem(metadataItemNode); + rights.Add(rightsItem); + break; + case "link": + EpubMetadataLink link = ReadLink(metadataItemNode); + links.Add(link); + break; + case "meta": + EpubMetadataMeta meta = ReadMeta(metadataItemNode); + metaItems.Add(meta); + break; + } + } + return new(titles, creators, subjects, descriptions, publishers, contributors, dates, types, formats, identifiers, sources, + languages, relations, coverages, rights, links, metaItems); + } + + public static EpubMetadataLink ReadLink(XElement linkNode) + { + string? href = null; + string? id = null; + string? mediaType = null; + List? properties = null; + string? refines = null; + List? relationships = null; + foreach (XAttribute linkNodeAttribute in linkNode.Attributes()) + { + string attributeValue = linkNodeAttribute.Value; + switch (linkNodeAttribute.GetLowerCaseLocalName()) + { + case "href": + href = attributeValue; + break; + case "id": + id = attributeValue; + break; + case "media-type": + mediaType = attributeValue; + break; + case "properties": + properties = EpubMetadataLinkPropertyParser.ParsePropertyList(attributeValue); + break; + case "refines": + refines = attributeValue; + break; + case "rel": + relationships = EpubMetadataLinkRelationshipParser.ParseRelationshipList(attributeValue); + break; + } + } + if (href == null) + { + throw new EpubPackageException("Incorrect EPUB metadata link: href is missing."); + } + if (relationships == null) + { + throw new EpubPackageException("Incorrect EPUB metadata link: rel is missing."); + } + return new(href, id, mediaType, properties, refines, relationships); + } + + private static EpubMetadataTitle ReadTitle(XElement titleNode) + { + ReadMetadataItemWithIdDirLangAndContent(titleNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string title); + return new(title, id, textDirection, language); + } + + private static EpubMetadataCreator ReadCreator(XElement creatorNode) + { + string? id = null; + string? fileAs = null; + string? role = null; + EpubTextDirection? textDirection = null; + string? language = null; + foreach (XAttribute creatorNodeAttribute in creatorNode.Attributes()) + { + string attributeValue = creatorNodeAttribute.Value; + switch (creatorNodeAttribute.GetLowerCaseLocalName()) + { + case "id": + id = attributeValue; + break; + case "file-as": + fileAs = attributeValue; + break; + case "role": + role = attributeValue; + break; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); + break; + case "lang": + language = attributeValue; + break; + } + } + string creator = creatorNode.Value; + return new(creator, id, fileAs, role, textDirection, language); + } + + private static EpubMetadataSubject ReadSubject(XElement subjectNode) + { + ReadMetadataItemWithIdDirLangAndContent(subjectNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string subject); + return new(subject, id, textDirection, language); + } + + private static EpubMetadataDescription ReadDescription(XElement descriptionNode) + { + ReadMetadataItemWithIdDirLangAndContent(descriptionNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string description); + return new(description, id, textDirection, language); + } + + private static EpubMetadataPublisher ReadPublisher(XElement publisherNode) + { + ReadMetadataItemWithIdDirLangAndContent(publisherNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string publisher); + return new(publisher, id, textDirection, language); + } + + private static EpubMetadataContributor ReadContributor(XElement contributorNode) + { + string? id = null; + string? fileAs = null; + string? role = null; + EpubTextDirection? textDirection = null; + string? language = null; + foreach (XAttribute contributorNodeAttribute in contributorNode.Attributes()) + { + string attributeValue = contributorNodeAttribute.Value; + switch (contributorNodeAttribute.GetLowerCaseLocalName()) + { + case "id": + id = attributeValue; + break; + case "file-as": + fileAs = attributeValue; + break; + case "role": + role = attributeValue; + break; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); + break; + case "lang": + language = attributeValue; + break; + } + } + string contributor = contributorNode.Value; + return new(contributor, id, fileAs, role, textDirection, language); + } + + private static EpubMetadataDate ReadDate(XElement dateNode) + { + string date; + string? id = null; + string? @event = null; + foreach (XAttribute dateNodeAttribute in dateNode.Attributes()) + { + string attributeValue = dateNodeAttribute.Value; + switch (dateNodeAttribute.GetLowerCaseLocalName()) + { + case "id": + id = attributeValue; + break; + case "event": + @event = attributeValue; + break; + } + } + date = dateNode.Value; + return new EpubMetadataDate(date, id, @event); + } + + private static EpubMetadataType ReadType(XElement typeNode) + { + ReadMetadataItemWithIdAndContent(typeNode, out string? id, out string type); + return new(type, id); + } + + private static EpubMetadataFormat ReadFormat(XElement formatNode) + { + ReadMetadataItemWithIdAndContent(formatNode, out string? id, out string format); + return new(format, id); + } + + private static EpubMetadataIdentifier ReadIdentifier(XElement identifierNode) + { + string? id = null; + string? scheme = null; + foreach (XAttribute identifierNodeAttribute in identifierNode.Attributes()) + { + string attributeValue = identifierNodeAttribute.Value; + switch (identifierNodeAttribute.GetLowerCaseLocalName()) + { + case "id": + id = attributeValue; + break; + case "scheme": + scheme = attributeValue; + break; + } + } + string identifier = identifierNode.Value; + return new(identifier, id, scheme); + } + + private static EpubMetadataSource ReadSource(XElement sourceNode) + { + ReadMetadataItemWithIdAndContent(sourceNode, out string? id, out string source); + return new(source, id); + } + + private static EpubMetadataLanguage ReadLanguage(XElement languageNode) + { + ReadMetadataItemWithIdAndContent(languageNode, out string? id, out string language); + return new(language, id); + } + + private static EpubMetadataRelation ReadRelation(XElement relationNode) + { + ReadMetadataItemWithIdDirLangAndContent(relationNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string relation); + return new(relation, id, textDirection, language); + } + + private static EpubMetadataCoverage ReadCoverage(XElement coverageNode) + { + ReadMetadataItemWithIdDirLangAndContent(coverageNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string coverage); + return new(coverage, id, textDirection, language); + } + + private static EpubMetadataRights ReadRightsItem(XElement rightsNode) + { + ReadMetadataItemWithIdDirLangAndContent(rightsNode, out string? id, out EpubTextDirection? textDirection, out string? language, out string rights); + return new(rights, id, textDirection, language); + } + + private static EpubMetadataMeta ReadMeta(XElement metaNode) + { + string? name = null; + string? content = null; + string? id = null; + string? refines = null; + string? property = null; + string? scheme = null; + EpubTextDirection? textDirection = null; + string? language = null; + foreach (XAttribute metaNodeAttribute in metaNode.Attributes()) + { + string attributeValue = metaNodeAttribute.Value; + switch (metaNodeAttribute.GetLowerCaseLocalName()) + { + case "name": + name = attributeValue; + break; + case "content": + content = attributeValue; + break; + case "id": + id = attributeValue; + break; + case "refines": + refines = attributeValue; + break; + case "property": + property = attributeValue; + break; + case "scheme": + scheme = attributeValue; + break; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); + break; + case "lang": + language = attributeValue; + break; + } + } + content ??= metaNode.Value; + return new(name, content, id, refines, property, scheme, textDirection, language); + } + + private static void ReadMetadataItemWithIdAndContent(XElement metadataItemNode, out string? id, out string content) + { + XAttribute idAttribute = metadataItemNode.Attribute("id"); + id = idAttribute?.Value; + content = metadataItemNode.Value; + } + + private static void ReadMetadataItemWithIdDirLangAndContent(XElement metadataItemNode, out string? id, out EpubTextDirection? textDirection, out string? language, + out string content) + { + id = null; + textDirection = null; + language = null; + foreach (XAttribute metadataItemNodeAttribute in metadataItemNode.Attributes()) + { + string attributeValue = metadataItemNodeAttribute.Value; + switch (metadataItemNodeAttribute.GetLowerCaseLocalName()) + { + case "id": + id = attributeValue; + break; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); + break; + case "lang": + language = attributeValue; + break; + } + } + content = metadataItemNode.Value; + } + } +} diff --git a/Source/VersOne.Epub/Readers/PackageReader.cs b/Source/VersOne.Epub/Readers/PackageReader.cs index 7affa41..bbbc4bb 100644 --- a/Source/VersOne.Epub/Readers/PackageReader.cs +++ b/Source/VersOne.Epub/Readers/PackageReader.cs @@ -30,292 +30,74 @@ public async Task ReadPackageAsync(IZipFile epubFile, string rootFi XNamespace opfNamespace = "http://www.idpf.org/2007/opf"; XElement packageNode = containerDocument.Element(opfNamespace + "package") ?? throw new EpubPackageException("EPUB parsing error: package XML element not found in the package file."); - string epubVersionValue = packageNode.Attribute("version").Value; - EpubVersion epubVersion = epubVersionValue switch - { - "2.0" => EpubVersion.EPUB_2, - "3.0" => EpubVersion.EPUB_3, - "3.1" => EpubVersion.EPUB_3_1, - _ => throw new EpubPackageException($"Unsupported EPUB version: \"{epubVersionValue}\".") - }; - XElement metadataNode = packageNode.Element(opfNamespace + "metadata") ?? throw new EpubPackageException("EPUB parsing error: metadata not found in the package."); - EpubMetadata metadata = ReadMetadata(metadataNode); - XElement manifestNode = packageNode.Element(opfNamespace + "manifest") ?? throw new EpubPackageException("EPUB parsing error: manifest not found in the package."); - EpubManifest manifest = ReadManifest(manifestNode, epubReaderOptions.PackageReaderOptions); - XElement spineNode = packageNode.Element(opfNamespace + "spine") ?? throw new EpubPackageException("EPUB parsing error: spine not found in the package."); - EpubSpine spine = ReadSpine(spineNode, epubVersion, epubReaderOptions.PackageReaderOptions); - EpubGuide? guide = null; - XElement guideNode = packageNode.Element(opfNamespace + "guide"); - if (guideNode != null) - { - guide = ReadGuide(guideNode); - } - return new(epubVersion, metadata, manifest, spine, guide); - } - - private static EpubMetadata ReadMetadata(XElement metadataNode) - { - List titles = new(); - List creators = new(); - List subjects = new(); - string? description = null; - List publishers = new(); - List contributors = new(); - List dates = new(); - List types = new(); - List formats = new(); - List identifiers = new(); - List sources = new(); - List languages = new(); - List relations = new(); - List coverages = new(); - List rights = new(); - List links = new(); - List metaItems = new(); - foreach (XElement metadataItemNode in metadataNode.Elements()) - { - string innerText = metadataItemNode.Value; - switch (metadataItemNode.GetLowerCaseLocalName()) - { - case "title": - titles.Add(innerText); - break; - case "creator": - EpubMetadataCreator creator = ReadMetadataCreator(metadataItemNode); - creators.Add(creator); - break; - case "subject": - subjects.Add(innerText); - break; - case "description": - description = innerText; - break; - case "publisher": - publishers.Add(innerText); - break; - case "contributor": - EpubMetadataContributor contributor = ReadMetadataContributor(metadataItemNode); - contributors.Add(contributor); - break; - case "date": - EpubMetadataDate date = ReadMetadataDate(metadataItemNode); - dates.Add(date); - break; - case "type": - types.Add(innerText); - break; - case "format": - formats.Add(innerText); - break; - case "identifier": - EpubMetadataIdentifier identifier = ReadMetadataIdentifier(metadataItemNode); - identifiers.Add(identifier); - break; - case "source": - sources.Add(innerText); - break; - case "language": - languages.Add(innerText); - break; - case "relation": - relations.Add(innerText); - break; - case "coverage": - coverages.Add(innerText); - break; - case "rights": - rights.Add(innerText); - break; - case "link": - EpubMetadataLink link = ReadMetadataLink(metadataItemNode); - links.Add(link); - break; - case "meta": - EpubMetadataMeta meta = ReadMetadataMeta(metadataItemNode); - metaItems.Add(meta); - break; - } - } - return new(titles, creators, subjects, description, publishers, contributors, dates, types, formats, identifiers, sources, - languages, relations, coverages, rights, links, metaItems); - } - - private static EpubMetadataCreator ReadMetadataCreator(XElement metadataCreatorNode) - { - string? id = null; - string creator; - string? role = null; - string? fileAs = null; - foreach (XAttribute metadataCreatorNodeAttribute in metadataCreatorNode.Attributes()) - { - string attributeValue = metadataCreatorNodeAttribute.Value; - switch (metadataCreatorNodeAttribute.GetLowerCaseLocalName()) - { - case "id": - id = attributeValue; - break; - case "role": - role = attributeValue; - break; - case "file-as": - fileAs = attributeValue; - break; - } - } - creator = metadataCreatorNode.Value; - return new(id, creator, fileAs, role); - } - - private static EpubMetadataContributor ReadMetadataContributor(XElement metadataContributorNode) - { - string? id = null; - string contributor; - string? role = null; - string? fileAs = null; - foreach (XAttribute metadataContributorNodeAttribute in metadataContributorNode.Attributes()) - { - string attributeValue = metadataContributorNodeAttribute.Value; - switch (metadataContributorNodeAttribute.GetLowerCaseLocalName()) - { - case "id": - id = attributeValue; - break; - case "role": - role = attributeValue; - break; - case "file-as": - fileAs = attributeValue; - break; - } - } - contributor = metadataContributorNode.Value; - return new(id, contributor, fileAs, role); - } - - private static EpubMetadataDate ReadMetadataDate(XElement metadataDateNode) - { - string date; - string? @event = null; - XAttribute eventAttribute = metadataDateNode.Attribute(metadataDateNode.Parent.Name.Namespace + "event"); - if (eventAttribute != null) - { - @event = eventAttribute.Value; - } - date = metadataDateNode.Value; - return new EpubMetadataDate(date, @event); - } - - private static EpubMetadataIdentifier ReadMetadataIdentifier(XElement metadataIdentifierNode) - { + string? uniqueIdentifier = null; + string? epubVersionString = null; string? id = null; - string? scheme = null; - string identifier; - foreach (XAttribute metadataIdentifierNodeAttribute in metadataIdentifierNode.Attributes()) + EpubTextDirection? textDirection = null; + string? prefix = null; + string? language = null; + foreach (XAttribute packageNodeAttribute in packageNode.Attributes()) { - string attributeValue = metadataIdentifierNodeAttribute.Value; - switch (metadataIdentifierNodeAttribute.GetLowerCaseLocalName()) + string attributeValue = packageNodeAttribute.Value; + switch (packageNodeAttribute.GetLowerCaseLocalName()) { - case "id": - id = attributeValue; + case "unique-identifier": + uniqueIdentifier = attributeValue; break; - case "scheme": - scheme = attributeValue; + case "version": + epubVersionString = attributeValue; break; - } - } - identifier = metadataIdentifierNode.Value; - return new(id, scheme, identifier); - } - - private static EpubMetadataLink ReadMetadataLink(XElement metadataIdentifierNode) - { - string? id = null; - string? href = null; - string? mediaType = null; - List? properties = null; - string? refines = null; - List? relationships = null; - foreach (XAttribute metadataIdentifierNodeAttribute in metadataIdentifierNode.Attributes()) - { - string attributeValue = metadataIdentifierNodeAttribute.Value; - switch (metadataIdentifierNodeAttribute.GetLowerCaseLocalName()) - { case "id": id = attributeValue; break; - case "href": - href = attributeValue; - break; - case "media-type": - mediaType = attributeValue; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); break; - case "refines": - refines = attributeValue; + case "prefix": + prefix = attributeValue; break; - case "properties": - properties = EpubMetadataLinkPropertyParser.ParsePropertyList(attributeValue); - break; - case "rel": - relationships = EpubMetadataLinkRelationshipParser.ParseRelationshipList(attributeValue); + case "lang": + language = attributeValue; break; } } - if (href == null) + if (epubVersionString == null) { - throw new EpubPackageException("Incorrect EPUB metadata link: href is missing."); + throw new EpubPackageException("EPUB parsing error: EPUB version is not specified in the package."); } - if (relationships == null) + EpubVersion epubVersion = epubVersionString switch { - throw new EpubPackageException("Incorrect EPUB metadata link: rel is missing."); - } - return new(id, href, mediaType, properties, refines, relationships); - } - - private static EpubMetadataMeta ReadMetadataMeta(XElement metadataMetaNode) - { - string? name = null; - string? content = null; - string? id = null; - string? refines = null; - string? property = null; - string? scheme = null; - foreach (XAttribute metadataMetaNodeAttribute in metadataMetaNode.Attributes()) + "2.0" => EpubVersion.EPUB_2, + "3.0" => EpubVersion.EPUB_3, + "3.1" => EpubVersion.EPUB_3_1, + _ => throw new EpubPackageException($"Unsupported EPUB version: \"{epubVersionString}\".") + }; + XElement metadataNode = packageNode.Element(opfNamespace + "metadata") ?? throw new EpubPackageException("EPUB parsing error: metadata not found in the package."); + EpubMetadata metadata = MetadataReader.ReadMetadata(metadataNode); + XElement manifestNode = packageNode.Element(opfNamespace + "manifest") ?? throw new EpubPackageException("EPUB parsing error: manifest not found in the package."); + EpubManifest manifest = ReadManifest(manifestNode, epubReaderOptions.PackageReaderOptions); + XElement spineNode = packageNode.Element(opfNamespace + "spine") ?? throw new EpubPackageException("EPUB parsing error: spine not found in the package."); + EpubSpine spine = ReadSpine(spineNode, epubVersion, epubReaderOptions.PackageReaderOptions); + EpubGuide? guide = null; + XElement guideNode = packageNode.Element(opfNamespace + "guide"); + if (guideNode != null) { - string attributeValue = metadataMetaNodeAttribute.Value; - switch (metadataMetaNodeAttribute.GetLowerCaseLocalName()) - { - case "name": - name = attributeValue; - break; - case "content": - content = attributeValue; - break; - case "id": - id = attributeValue; - break; - case "refines": - refines = attributeValue; - break; - case "property": - property = attributeValue; - break; - case "scheme": - scheme = attributeValue; - break; - } + guide = ReadGuide(guideNode); } - content ??= metadataMetaNode.Value; - return new(name, content, id, refines, property, scheme); + List collections = ReadCollections(packageNode); + return new(uniqueIdentifier, epubVersion, metadata, manifest, spine, guide, collections, id, textDirection, prefix, language); } private static EpubManifest ReadManifest(XElement manifestNode, PackageReaderOptions packageReaderOptions) { + XAttribute? manifestIdAttribute = manifestNode.Attribute("id"); + string? manifestId = manifestIdAttribute?.Value; List items = new(); foreach (XElement manifestItemNode in manifestNode.Elements()) { if (manifestItemNode.CompareNameTo("item")) { - string? id = null; + string? manifestItemId = null; string? href = null; string? mediaType = null; string? mediaOverlay = null; @@ -330,7 +112,7 @@ private static EpubManifest ReadManifest(XElement manifestNode, PackageReaderOpt switch (manifestItemNodeAttribute.GetLowerCaseLocalName()) { case "id": - id = attributeValue; + manifestItemId = attributeValue; break; case "href": href = Uri.UnescapeDataString(attributeValue); @@ -358,7 +140,7 @@ private static EpubManifest ReadManifest(XElement manifestNode, PackageReaderOpt break; } } - if (id == null) + if (manifestItemId == null) { if (packageReaderOptions != null && packageReaderOptions.SkipInvalidManifestItems) { @@ -382,10 +164,10 @@ private static EpubManifest ReadManifest(XElement manifestNode, PackageReaderOpt } throw new EpubPackageException("Incorrect EPUB manifest: item media type is missing."); } - items.Add(new EpubManifestItem(id, href, mediaType, mediaOverlay, requiredNamespace, requiredModules, fallback, fallbackStyle, properties)); + items.Add(new EpubManifestItem(manifestItemId, href, mediaType, mediaOverlay, requiredNamespace, requiredModules, fallback, fallbackStyle, properties)); } } - return new(items); + return new(manifestId, items); } private static EpubSpine ReadSpine(XElement spineNode, EpubVersion epubVersion, PackageReaderOptions packageReaderOptions) @@ -489,5 +271,67 @@ private static EpubGuide ReadGuide(XElement guideNode) } return new(items); } + + private static List ReadCollections(XElement packageNode) + { + List result = new(); + foreach (XElement collectionNode in packageNode.Elements(packageNode.Name.Namespace + "collection")) + { + result.Add(ReadCollection(collectionNode)); + } + return result; + } + + private static EpubCollection ReadCollection(XElement collectionNode) + { + string? role = null; + string? id = null; + EpubTextDirection? textDirection = null; + string? language = null; + foreach (XAttribute collectionNodeAttribute in collectionNode.Attributes()) + { + string attributeValue = collectionNodeAttribute.Value; + switch (collectionNodeAttribute.GetLowerCaseLocalName()) + { + case "role": + role = attributeValue; + break; + case "id": + id = attributeValue; + break; + case "dir": + textDirection = EpubTextDirectionParser.Parse(attributeValue); + break; + case "lang": + language = attributeValue; + break; + } + } + if (role == null) + { + throw new EpubPackageException("Incorrect EPUB collection: collection role is missing."); + } + EpubMetadata? metadata = null; + List nestedCollections = new(); + List links = new(); + foreach (XElement collectionChildNode in collectionNode.Elements()) + { + switch (collectionChildNode.GetLowerCaseLocalName()) + { + case "metadata": + metadata = MetadataReader.ReadMetadata(collectionChildNode); + break; + case "collection": + EpubCollection nestedCollection = ReadCollection(collectionChildNode); + nestedCollections.Add(nestedCollection); + break; + case "link": + EpubMetadataLink link = MetadataReader.ReadLink(collectionChildNode); + links.Add(link); + break; + } + } + return new(role, metadata, nestedCollections, links, id, textDirection, language); + } } } diff --git a/Source/VersOne.Epub/Schema/Opf/Collections/EpubCollection.cs b/Source/VersOne.Epub/Schema/Opf/Collections/EpubCollection.cs new file mode 100644 index 0000000..8614803 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Collections/EpubCollection.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; + +namespace VersOne.Epub.Schema +{ + /// + /// + /// Represents a unified collection of EPUB metadata items. A collection allows resources to be assembled into logical groups + /// for a variety of potential uses: enabling content that has been split across multiple EPUB Content Documents to be reassembled + /// back into a meaningful unit (e.g., an index split across multiple documents), identifying resources for specialized purposes + /// (e.g., preview content), or collecting together resources that present additional information about this EPUB book. + /// + /// See for more information. + /// + public class EpubCollection + { + /// + /// Initializes a new instance of the class. + /// + /// The role of this collection. + /// The EPUB meta information included into this collection or null if the collection doesn't have any meta information. + /// A list of sub-collections included in this collection. + /// A list of metadata links. + /// The unique ID of this collection or null if the collection doesn't have an ID. + /// The text direction of this collection or null if the collection doesn't specify a text direction. + /// The language of this collection or null if the collection doesn't specify the language. + /// The parameter is null. + public EpubCollection(string role, EpubMetadata? metadata = null, List? nestedCollections = null, List? links = null, + string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Role = role ?? throw new ArgumentNullException(nameof(role)); + Metadata = metadata; + NestedCollections = nestedCollections ?? new List(); + Links = links ?? new List(); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the role of this collection. + /// See for more information. + /// + public string Role { get; } + + /// + /// Gets the EPUB meta information included into this collection or null if the collection doesn't have any meta information. + /// See for more information. + /// + public EpubMetadata? Metadata { get; } + + /// + /// Gets a list of sub-collections included in this collection. + /// See for more information. + /// + public List NestedCollections { get; } + + /// + /// Gets a list of metadata links. Links are used to associate resources with this collection, such as metadata records. + /// See for more information. + /// + public List Links { get; } + + /// + /// Gets the unique ID of this collection or null if the collection doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this collection or null if the collection doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this collection or null if the collection doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Common/EpubTextDirection.cs b/Source/VersOne.Epub/Schema/Opf/Common/EpubTextDirection.cs new file mode 100644 index 0000000..dee6d67 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Common/EpubTextDirection.cs @@ -0,0 +1,46 @@ +using System; +using System.Diagnostics.CodeAnalysis; + +namespace VersOne.Epub.Schema +{ + /// + /// Text direction of the content. + /// See for more information. + /// + public enum EpubTextDirection + { + /// + /// Left-to-right text direction. + /// + LEFT_TO_RIGHT, + + /// + /// Right-to-left text direction. + /// + RIGHT_TO_LEFT, + + /// + /// A text direction which is not present in this enumeration. + /// + UNKNOWN + } + + [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1649:File name should match first type name", + Justification = "Enum and parser need to be close to each other to avoid issues when the enum was changed without changing the parser. The file needs to be named after enum.")] + internal static class EpubTextDirectionParser + { + public static EpubTextDirection Parse(string stringValue) + { + if (String.IsNullOrEmpty(stringValue)) + { + return EpubTextDirection.UNKNOWN; + } + return stringValue.ToLowerInvariant() switch + { + "ltr" => EpubTextDirection.LEFT_TO_RIGHT, + "rtl" => EpubTextDirection.RIGHT_TO_LEFT, + _ => EpubTextDirection.UNKNOWN + }; + } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/EpubGuide.cs b/Source/VersOne.Epub/Schema/Opf/Guide/EpubGuide.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubGuide.cs rename to Source/VersOne.Epub/Schema/Opf/Guide/EpubGuide.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubGuideReference.cs b/Source/VersOne.Epub/Schema/Opf/Guide/EpubGuideReference.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubGuideReference.cs rename to Source/VersOne.Epub/Schema/Opf/Guide/EpubGuideReference.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubManifest.cs b/Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifest.cs similarity index 67% rename from Source/VersOne.Epub/Schema/Opf/EpubManifest.cs rename to Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifest.cs index 0565404..4dce4f9 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubManifest.cs +++ b/Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifest.cs @@ -14,12 +14,22 @@ public class EpubManifest /// /// Initializes a new instance of the class. /// + /// The ID of the manifest or null if the manifest doesn't specify an ID. /// A list of the content items that constitute the EPUB book. - public EpubManifest(List? items = null) + public EpubManifest(string? id = null, List? items = null) { + Id = id; Items = items ?? new List(); } + /// + /// Gets the ID of the manifest or null if the manifest doesn't specify an ID. + /// + /// See for more information. + /// + /// + public string? Id { get; } + /// /// Gets a list of the content items that constitute the EPUB book. /// diff --git a/Source/VersOne.Epub/Schema/Opf/EpubManifestItem.cs b/Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifestItem.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubManifestItem.cs rename to Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifestItem.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubManifestProperty.cs b/Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifestProperty.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubManifestProperty.cs rename to Source/VersOne.Epub/Schema/Opf/Manifest/EpubManifestProperty.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadata.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadata.cs similarity index 78% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadata.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadata.cs index 50e5f97..35558c6 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadata.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadata.cs @@ -14,43 +14,44 @@ public class EpubMetadata /// /// Initializes a new instance of the class. /// - /// A list of titles. - /// A list of creators. - /// A list of subjects. - /// The description of the EPUB book. + /// A list of titles of the EPUB book. + /// A list of creators of the EPUB book. + /// A list of subjects of the EPUB book. + /// A list of descriptions of the EPUB book. /// A list of publishers of the EPUB book. /// A list of names of persons, organizations, etc. that played a secondary role in the creation of the content of the EPUB book. /// A list of dates of the events associated with the EPUB book (e.g. publication date). /// A list of types of the EPUB book. /// A list of file formats, physical media, or dimensions of the EPUB book. /// A list of identifiers associated with the EPUB book, such as a UUID, DOI, or ISBN. - /// A list of sources. + /// A list of sources of the EPUB book. /// A list of languages of the content of the EPUB book. /// A list of related resources of the EPUB book. /// A list of coverages of the EPUB book. /// A list of rights held in and over the EPUB book. - /// A list of metadata links. + /// A list of metadata links of the EPUB book. /// A list of generic metadata items of the EPUB book. - public EpubMetadata(List? titles = null, List? creators = null, List? subjects = null, string? description = null, - List? publishers = null, List? contributors = null, List? dates = null, List? types = null, - List? formats = null, List? identifiers = null, List? sources = null, List? languages = null, - List? relations = null, List? coverages = null, List? rights = null, List? links = null, List? metaItems = null) + public EpubMetadata(List? titles = null, List? creators = null, List? subjects = null, + List? descriptions = null, List? publishers = null, List? contributors = null, + List? dates = null, List? types = null, List? formats = null, List? identifiers = null, + List? sources = null, List? languages = null, List? relations = null, + List? coverages = null, List? rights = null, List? links = null, List? metaItems = null) { - Titles = titles ?? new List(); + Titles = titles ?? new List(); Creators = creators ?? new List(); - Subjects = subjects ?? new List(); - Description = description; - Publishers = publishers ?? new List(); + Subjects = subjects ?? new List(); + Descriptions = descriptions ?? new List(); + Publishers = publishers ?? new List(); Contributors = contributors ?? new List(); Dates = dates ?? new List(); - Types = types ?? new List(); - Formats = formats ?? new List(); + Types = types ?? new List(); + Formats = formats ?? new List(); Identifiers = identifiers ?? new List(); - Sources = sources ?? new List(); - Languages = languages ?? new List(); - Relations = relations ?? new List(); - Coverages = coverages ?? new List(); - Rights = rights ?? new List(); + Sources = sources ?? new List(); + Languages = languages ?? new List(); + Relations = relations ?? new List(); + Coverages = coverages ?? new List(); + Rights = rights ?? new List(); Links = links ?? new List(); MetaItems = metaItems ?? new List(); } @@ -63,7 +64,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Titles { get; } + public List Titles { get; } /// /// @@ -78,24 +79,24 @@ public EpubMetadata(List? titles = null, List? crea public List Creators { get; } /// - /// Gets a list of subjects. Each element in this list identifies the subject of the EPUB book. + /// Gets a list of subjects. Each element in this list identifies a subject of the EPUB book. /// /// See , /// , /// and for more information. /// /// - public List Subjects { get; } + public List Subjects { get; } /// - /// Gets the description of the EPUB book. + /// Gets a list of descriptions of the EPUB book. /// /// See , /// , /// and for more information. /// /// - public string? Description { get; } + public List Descriptions { get; } /// /// Gets a list of publishers of the EPUB book. @@ -105,7 +106,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Publishers { get; } + public List Publishers { get; } /// /// Gets a list of names of persons, organizations, etc. that played a secondary role in the creation of the content of the EPUB book. @@ -138,7 +139,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Types { get; } + public List Types { get; } /// /// Gets a list of file formats, physical media, or dimensions of the EPUB book. @@ -148,7 +149,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Formats { get; } + public List Formats { get; } /// /// Gets a list of identifiers associated with the EPUB book, such as a UUID, DOI, or ISBN. @@ -168,7 +169,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Sources { get; } + public List Sources { get; } /// /// Gets a list of languages of the content of the EPUB book. @@ -178,7 +179,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Languages { get; } + public List Languages { get; } /// /// Gets a list of related resources of the EPUB book. @@ -188,7 +189,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Relations { get; } + public List Relations { get; } /// /// @@ -201,7 +202,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Coverages { get; } + public List Coverages { get; } /// /// Gets a list of rights held in and over the EPUB book. @@ -211,7 +212,7 @@ public EpubMetadata(List? titles = null, List? crea /// and for more information. /// /// - public List Rights { get; } + public List Rights { get; } /// /// Gets a list of metadata links. Links are used to associate resources with the EPUB book, such as metadata records. diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataContributor.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataContributor.cs similarity index 68% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataContributor.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataContributor.cs index bb575dd..dd86fdd 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataContributor.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataContributor.cs @@ -15,31 +15,36 @@ public class EpubMetadataContributor /// /// Initializes a new instance of the class. /// - /// The unique ID of this EPUB metadata contributor item. /// The name of the contributor as the author intends it to be displayed to a user. + /// The unique ID of this EPUB metadata contributor item. /// The normalized form of the name of the contributor for sorting. /// The contributor's role which describes the nature of work performed by the contributor. + /// The text direction for the name of this contributor or null if the contributor doesn't specify a text direction. + /// The language for the name of this contributor or null if the contributor doesn't specify the language. /// The parameter is null. - public EpubMetadataContributor(string? id, string contributor, string? fileAs, string? role) + public EpubMetadataContributor(string contributor, string? id = null, string? fileAs = null, string? role = null, EpubTextDirection? textDirection = null, + string? language = null) { - Id = id; Contributor = contributor ?? throw new ArgumentNullException(nameof(contributor)); + Id = id; FileAs = fileAs; Role = role; + TextDirection = textDirection; + Language = language; } - /// - /// Gets the unique ID of this EPUB metadata contributor item. - /// See for more information. - /// - public string? Id { get; } - /// /// Gets the name of the contributor as the author intends it to be displayed to a user. /// See for more information. /// public string Contributor { get; } + /// + /// Gets the unique ID of this EPUB metadata contributor item. + /// See for more information. + /// + public string? Id { get; } + /// /// Gets the normalized form of the name of the contributor for sorting. /// @@ -57,5 +62,17 @@ public EpubMetadataContributor(string? id, string contributor, string? fileAs, s /// /// public string? Role { get; } + + /// + /// Gets the text direction for the name of this contributor or null if the contributor doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language for the name of this contributor or null if the contributor doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } } } diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCoverage.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCoverage.cs new file mode 100644 index 0000000..378d80a --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCoverage.cs @@ -0,0 +1,62 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// + /// Represents a coverage of the EPUB book. A coverage is the spatial or temporal topic of the book, + /// the spatial applicability of the book, or the jurisdiction under which the book is relevant. + /// + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataCoverage + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of this coverage. + /// The unique ID of this coverage or null if the coverage doesn't have an ID. + /// The text direction of this coverage or null if the coverage doesn't specify a text direction. + /// The language of this coverage or null if the coverage doesn't specify the language. + /// The parameter is null. + public EpubMetadataCoverage(string coverage, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Coverage = coverage ?? throw new ArgumentNullException(nameof(coverage)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of this coverage. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Coverage { get; } + + /// + /// Gets the unique ID of this coverage or null if the coverage doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this coverage or null if the coverage doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this coverage or null if the coverage doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataCreator.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCreator.cs similarity index 69% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataCreator.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCreator.cs index 9415099..5a7f14a 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataCreator.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataCreator.cs @@ -13,43 +13,37 @@ namespace VersOne.Epub.Schema public class EpubMetadataCreator { /// - /// Initializes a new instance of the class with the specified creator's name. + /// Initializes a new instance of the class. /// /// The name of the creator as the author intends it to be displayed to a user. - /// The parameter is null. - public EpubMetadataCreator(string creator) - : this(null, creator, null, null) - { - } - - /// - /// Initializes a new instance of the class with specified ID, creator's name, creator's sorting name, and role. - /// /// The unique ID of this EPUB metadata creator item. - /// The name of the creator as the author intends it to be displayed to a user. /// The normalized form of the name of the creator for sorting. /// The creator's role which indicates the function the creator played in the creation of the content of the EPUB book. + /// The text direction for the name of this creator or null if the creator doesn't specify a text direction. + /// The language for the name of this creator or null if the creator doesn't specify the language. /// The parameter is null. - public EpubMetadataCreator(string? id, string creator, string? fileAs, string? role) + public EpubMetadataCreator(string creator, string? id = null, string? fileAs = null, string? role = null, EpubTextDirection? textDirection = null, string? language = null) { - Id = id; Creator = creator ?? throw new ArgumentNullException(nameof(creator)); + Id = id; FileAs = fileAs; Role = role; + TextDirection = textDirection; + Language = language; } - /// - /// Gets the unique ID of this EPUB metadata creator item. - /// See for more information. - /// - public string? Id { get; } - /// /// Gets the name of the creator as the author intends it to be displayed to a user. /// See for more information. /// public string Creator { get; } + /// + /// Gets the unique ID of this EPUB metadata creator item. + /// See for more information. + /// + public string? Id { get; } + /// /// Gets the normalized form of the name of the creator for sorting. /// @@ -67,5 +61,17 @@ public EpubMetadataCreator(string? id, string creator, string? fileAs, string? r /// /// public string? Role { get; } + + /// + /// Gets the text direction for the name of this creator or null if the creator doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language for the name of this creator or null if the creator doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } } } diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataDate.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDate.cs similarity index 79% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataDate.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDate.cs index 6b6bd56..093eca0 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataDate.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDate.cs @@ -16,13 +16,15 @@ public class EpubMetadataDate /// Initializes a new instance of the class. /// /// The date of the event. + /// The unique ID of this EPUB metadata date item. /// /// The name of the event represented by this date (e.g., creation, publication, modification, etc.) or null if the event doesn't have a name. /// /// The parameter is null. - public EpubMetadataDate(string date, string? @event) + public EpubMetadataDate(string date, string? id = null, string? @event = null) { Date = date ?? throw new ArgumentNullException(nameof(date)); + Id = id; Event = @event; } @@ -36,6 +38,12 @@ public EpubMetadataDate(string date, string? @event) /// public string Date { get; } + /// + /// Gets the unique ID of this EPUB metadata date item. + /// See for more information. + /// + public string? Id { get; } + /// /// Gets the name of the event represented by this date (e.g., creation, publication, modification, etc.) or null if the event doesn't have a name. /// diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDescription.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDescription.cs new file mode 100644 index 0000000..e1c094e --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataDescription.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a description of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataDescription + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of this description. + /// The unique ID of this description or null if the description doesn't have an ID. + /// The text direction of this description or null if the description doesn't specify a text direction. + /// The language of this description or null if the description doesn't specify the language. + /// The parameter is null. + public EpubMetadataDescription(string description, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Description = description ?? throw new ArgumentNullException(nameof(description)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of this description. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Description { get; } + + /// + /// Gets the unique ID of this description or null if the description doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this description or null if the description doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this description or null if the description doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataFormat.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataFormat.cs new file mode 100644 index 0000000..b4db73a --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataFormat.cs @@ -0,0 +1,43 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a file format, physical media, or dimensions of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataFormat + { + /// + /// Initializes a new instance of the class. + /// + /// The format value. + /// The unique ID of this format metadata element or null if the format metadata element doesn't have an ID. + /// The parameter is null. + public EpubMetadataFormat(string format, string? id = null) + { + Format = format ?? throw new ArgumentNullException(nameof(format)); + Id = id; + } + + /// + /// Gets the format value. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Format { get; } + + /// + /// Gets the unique ID of this format metadata element or null if the format metadata element doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataIdentifier.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataIdentifier.cs similarity index 94% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataIdentifier.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataIdentifier.cs index 290fe32..c93df85 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataIdentifier.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataIdentifier.cs @@ -15,19 +15,25 @@ public class EpubMetadataIdentifier /// /// Initializes a new instance of the class. /// + /// The unambiguous identifier for the EPUB book. /// The unique ID of this EPUB metadata identifier item or null if the metadata identifier doesn't have an ID. /// /// The name of the system or authority that generated or assigned the identifier, for example 'ISBN' or 'DOI' or null if the identified doesn't have a scheme. /// - /// The unambiguous identifier for the EPUB book. /// The parameter is null. - public EpubMetadataIdentifier(string? id, string? scheme, string identifier) + public EpubMetadataIdentifier(string identifier, string? id = null, string? scheme = null) { + Identifier = identifier ?? throw new ArgumentNullException(nameof(identifier)); Id = id; Scheme = scheme; - Identifier = identifier ?? throw new ArgumentNullException(nameof(identifier)); } + /// + /// Gets the unambiguous identifier for the EPUB book. + /// See for more information. + /// + public string Identifier { get; } + /// /// Gets the unique ID of this EPUB metadata identifier item or null if the metadata identifier doesn't have an ID. /// See for more information. @@ -41,11 +47,5 @@ public EpubMetadataIdentifier(string? id, string? scheme, string identifier) /// See for more information. /// public string? Scheme { get; } - - /// - /// Gets the unambiguous identifier for the EPUB book. - /// See for more information. - /// - public string Identifier { get; } } } diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLanguage.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLanguage.cs new file mode 100644 index 0000000..3b06d57 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLanguage.cs @@ -0,0 +1,42 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a language of the content of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataLanguage + { + /// + /// Initializes a new instance of the class. + /// + /// The language tag. + /// The unique ID of this language metadata element or null if the language metadata element doesn't have an ID. + /// The parameter is null. + public EpubMetadataLanguage(string language, string? id = null) + { + Language = language ?? throw new ArgumentNullException(nameof(language)); + Id = id; + } + + /// + /// Gets the language tag. + /// + /// See + /// and for more information. + /// + /// + public string Language { get; } + + /// + /// Gets the unique ID of this language metadata element or null if the language metadata element doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataLink.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLink.cs similarity index 93% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataLink.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLink.cs index 48272ee..4e4c3f2 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataLink.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLink.cs @@ -12,8 +12,8 @@ public class EpubMetadataLink /// /// Initializes a new instance of the class. /// - /// The unique ID of this link or null if the link doesn't have an ID. /// The location of the linked resource. + /// The unique ID of this link or null if the link doesn't have an ID. /// The media type of the linked resource or null if the link doesn't specify the media type. /// /// A list of the link properties used to establish the type of record a referenced resource represents or null if the link doesn't specify properties. @@ -21,23 +21,17 @@ public class EpubMetadataLink /// A relative IRI that identifies the resource augmented by the link or null if the link doesn't specify any augmentation. /// A list of properties that establish the relationship the resource has with the EPUB book. /// The parameter is null. - public EpubMetadataLink(string? id, string href, string? mediaType, List? properties, string? refines, - List? relationships) + public EpubMetadataLink(string href, string? id = null, string? mediaType = null, List? properties = null, string? refines = null, + List? relationships = null) { - Id = id; Href = href ?? throw new ArgumentNullException(nameof(href)); + Id = id; MediaType = mediaType; Properties = properties; Refines = refines; Relationships = relationships ?? new List(); } - /// - /// Gets the unique ID of this link or null if the link doesn't have an ID. - /// See for more information. - /// - public string? Id { get; } - /// /// Gets the location of the linked resource. /// @@ -47,6 +41,12 @@ public EpubMetadataLink(string? id, string href, string? mediaType, List public string Href { get; } + /// + /// Gets the unique ID of this link or null if the link doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + /// /// Gets the media type of the linked resource or null if the link doesn't specify the media type. /// diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataLinkProperty.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLinkProperty.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataLinkProperty.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLinkProperty.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataLinkRelationship.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLinkRelationship.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataLinkRelationship.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataLinkRelationship.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubMetadataMeta.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataMeta.cs similarity index 77% rename from Source/VersOne.Epub/Schema/Opf/EpubMetadataMeta.cs rename to Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataMeta.cs index 2b59618..7971055 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubMetadataMeta.cs +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataMeta.cs @@ -13,18 +13,7 @@ namespace VersOne.Epub.Schema public class EpubMetadataMeta { /// - /// Initializes a new instance of the class with specified name and content. - /// - /// The name of the EPUB 2 generic metadata item or null for EPUB 3 generic metadata item. - /// The content (i.e. value) of the EPUB 2 generic metadata item or the metadata expression of the EPUB 3 generic metadata item. - /// The parameter is null. - public EpubMetadataMeta(string? name, string content) - : this(name, content, null, null, null, null) - { - } - - /// - /// Initializes a new instance of the class with specified name, content, ID, refining resource, property, and scheme. + /// Initializes a new instance of the class. /// /// The name of the EPUB 2 generic metadata item or null for EPUB 3 generic metadata item. /// The content (i.e. value) of the EPUB 2 generic metadata item or the metadata expression of the EPUB 3 generic metadata item. @@ -41,8 +30,11 @@ public EpubMetadataMeta(string? name, string content) /// The system or scheme that the expression (see ) of the EPUB 3 generic metadata item is drawn from /// or null if the generic metadata item doesn't specify a scheme for the expression. /// + /// The text direction of this EPUB 3 generic metadata item or null if the generic metadata item doesn't specify a text direction. + /// The language of this EPUB 3 generic metadata item or null if the generic metadata item doesn't specify the language. /// The parameter is null. - public EpubMetadataMeta(string? name, string content, string? id, string? refines, string? property, string? scheme) + public EpubMetadataMeta(string? name, string content, string? id = null, string? refines = null, string? property = null, string? scheme = null, + EpubTextDirection? textDirection = null, string? language = null) { Name = name; Content = content ?? throw new ArgumentNullException(nameof(content)); @@ -50,6 +42,8 @@ public EpubMetadataMeta(string? name, string content, string? id, string? refine Refines = refines; Property = property; Scheme = scheme; + TextDirection = textDirection; + Language = language; } /// @@ -105,5 +99,17 @@ public EpubMetadataMeta(string? name, string content, string? id, string? refine /// /// public string? Scheme { get; } + + /// + /// Gets the text direction of this EPUB 3 generic metadata item or null if the generic metadata item doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this EPUB 3 generic metadata item or null if the generic metadata item doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } } } diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataPublisher.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataPublisher.cs new file mode 100644 index 0000000..54bf99b --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataPublisher.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a publisher of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataPublisher + { + /// + /// Initializes a new instance of the class. + /// + /// The name of this publisher. + /// The unique ID of this publisher or null if the publisher doesn't have an ID. + /// The text direction of this publisher or null if the publisher doesn't specify a text direction. + /// The language of this publisher or null if the publisher doesn't specify the language. + /// The parameter is null. + public EpubMetadataPublisher(string publisher, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Publisher = publisher ?? throw new ArgumentNullException(nameof(publisher)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the name of this publisher. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Publisher { get; } + + /// + /// Gets the unique ID of this publisher or null if the publisher doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this publisher or null if the publisher doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this publisher or null if the publisher doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRelation.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRelation.cs new file mode 100644 index 0000000..8d02d02 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRelation.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a related resource of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataRelation + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of this relation. + /// The unique ID of this relation or null if the relation doesn't have an ID. + /// The text direction of this relation or null if the relation doesn't specify a text direction. + /// The language of this relation or null if the relation doesn't specify the language. + /// The parameter is null. + public EpubMetadataRelation(string relation, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Relation = relation ?? throw new ArgumentNullException(nameof(relation)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of this relation. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Relation { get; } + + /// + /// Gets the unique ID of this relation or null if the relation doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this relation or null if the relation doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this relation or null if the relation doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRights.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRights.cs new file mode 100644 index 0000000..d5f2ea0 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataRights.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents the rights held in and over the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataRights + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of the rights. + /// The unique ID of the rights or null if the rights don't have an ID. + /// The text direction of the rights or null if the rights don't specify a text direction. + /// The language of the rights or null if the rights don't specify the language. + /// The parameter is null. + public EpubMetadataRights(string rights, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Rights = rights ?? throw new ArgumentNullException(nameof(rights)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of the rights. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Rights { get; } + + /// + /// Gets the unique ID of the rights or null if the rights don't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of the rights or null if the rights don't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of the rights or null if the rights don't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSource.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSource.cs new file mode 100644 index 0000000..506a8d1 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSource.cs @@ -0,0 +1,43 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a source of the EPUB book. A source is a related resource from which the EPUB book is derived. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataSource + { + /// + /// Initializes a new instance of the class. + /// + /// The source value. + /// The unique ID of this source metadata element or null if the source metadata element doesn't have an ID. + /// The parameter is null. + public EpubMetadataSource(string source, string? id = null) + { + Source = source ?? throw new ArgumentNullException(nameof(source)); + Id = id; + } + + /// + /// Gets the source value. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Source { get; } + + /// + /// Gets the unique ID of this source metadata element or null if the source metadata element doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSubject.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSubject.cs new file mode 100644 index 0000000..512678d --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataSubject.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents a subject of the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataSubject + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of this subject. + /// The unique ID of this subject or null if the subject doesn't have an ID. + /// The text direction of this subject or null if the subject doesn't specify a text direction. + /// The language of this subject or null if the subject doesn't specify the language. + /// The parameter is null. + public EpubMetadataSubject(string subject, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Subject = subject ?? throw new ArgumentNullException(nameof(subject)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of this subject. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Subject { get; } + + /// + /// Gets the unique ID of this subject or null if the subject doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this subject or null if the subject doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this subject or null if the subject doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataTitle.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataTitle.cs new file mode 100644 index 0000000..4d84694 --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataTitle.cs @@ -0,0 +1,59 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// Represents an instance of a name given to the EPUB book. + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataTitle + { + /// + /// Initializes a new instance of the class. + /// + /// The text content of this title. + /// The unique ID of this title or null if the title doesn't have an ID. + /// The text direction of this title or null if the title doesn't specify a text direction. + /// The language of this title or null if the title doesn't specify the language. + /// The parameter is null. + public EpubMetadataTitle(string title, string? id = null, EpubTextDirection? textDirection = null, string? language = null) + { + Title = title ?? throw new ArgumentNullException(nameof(title)); + Id = id; + TextDirection = textDirection; + Language = language; + } + + /// + /// Gets the text content of this title. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Title { get; } + + /// + /// Gets the unique ID of this title or null if the title doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the text direction of this title or null if the title doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the language of this title or null if the title doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataType.cs b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataType.cs new file mode 100644 index 0000000..b5fd93b --- /dev/null +++ b/Source/VersOne.Epub/Schema/Opf/Metadata/EpubMetadataType.cs @@ -0,0 +1,46 @@ +using System; + +namespace VersOne.Epub.Schema +{ + /// + /// + /// Represents a type of the EPUB book. Types are used to indicate that the EPUB book is of a specialized type + /// (e.g., annotations or a dictionary packaged in EPUB format). + /// + /// + /// See , + /// , + /// and for more information. + /// + /// + public class EpubMetadataType + { + /// + /// Initializes a new instance of the class. + /// + /// The name of the type. + /// The unique ID of this type metadata element or null if the type metadata element doesn't have an ID. + /// The parameter is null. + public EpubMetadataType(string type, string? id = null) + { + Type = type ?? throw new ArgumentNullException(nameof(type)); + Id = id; + } + + /// + /// Gets the name of the type. + /// + /// See , + /// , + /// and for more information. + /// + /// + public string Type { get; } + + /// + /// Gets the unique ID of this type metadata element or null if the type metadata element doesn't have an ID. + /// See for more information. + /// + public string? Id { get; } + } +} diff --git a/Source/VersOne.Epub/Schema/Opf/EpubPackage.cs b/Source/VersOne.Epub/Schema/Opf/Package/EpubPackage.cs similarity index 53% rename from Source/VersOne.Epub/Schema/Opf/EpubPackage.cs rename to Source/VersOne.Epub/Schema/Opf/Package/EpubPackage.cs index 9ac86d3..7f6af07 100644 --- a/Source/VersOne.Epub/Schema/Opf/EpubPackage.cs +++ b/Source/VersOne.Epub/Schema/Opf/Package/EpubPackage.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using VersOne.Epub.Internal; namespace VersOne.Epub.Schema @@ -15,6 +16,10 @@ public class EpubPackage /// /// Initializes a new instance of the class. /// + /// + /// The ID of the element that provides the preferred, or primary, identifier of the EPUB book + /// or null if the package doesn't specify the identifier of the book. + /// /// The version of EPUB specification to which this EPUB package conforms. /// The meta information for the EPUB book. /// The EPUB manifest which provides an exhaustive list of content items that constitute the EPUB book. @@ -22,18 +27,37 @@ public class EpubPackage /// /// The EPUB 2 guide which provides machine-processable navigation to the key structural components of the EPUB book or null if the book doesn't have a EPUB 2 guide. /// + /// A list of elements which define related groups of resources within the EPUB book. + /// The ID of the OPF package or null if the package doesn't specify an ID. + /// The default text direction of the content of the EPUB book or null if the package doesn't specify a text direction. + /// The additional prefix mappings or null if the package doesn't specify additional prefix mappings. + /// The language of the content of the EPUB book or null if the package doesn't specify the language. /// The parameter is null. /// The parameter is null. /// The parameter is null. - public EpubPackage(EpubVersion epubVersion, EpubMetadata metadata, EpubManifest manifest, EpubSpine spine, EpubGuide? guide) + public EpubPackage(string? uniqueIdentifier, EpubVersion epubVersion, EpubMetadata metadata, EpubManifest manifest, EpubSpine spine, EpubGuide? guide, + List? collections = null, string? id = null, EpubTextDirection? textDirection = null, string? prefix = null, string? language = null) { + UniqueIdentifier = uniqueIdentifier; EpubVersion = epubVersion; Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); Manifest = manifest ?? throw new ArgumentNullException(nameof(manifest)); Spine = spine ?? throw new ArgumentNullException(nameof(spine)); Guide = guide; + Collections = collections ?? new List(); + Id = id; + TextDirection = textDirection; + Prefix = prefix; + Language = language; } + /// + /// Gets the ID of the element that provides the preferred, or primary, identifier of the EPUB book + /// or null if the package doesn't specify the identifier of the book. This value is required for EPUB 3 books. + /// See for more information. + /// + public string? UniqueIdentifier { get; } + /// /// Gets the version of EPUB specification to which this EPUB package conforms. /// @@ -81,6 +105,36 @@ public EpubPackage(EpubVersion epubVersion, EpubMetadata metadata, EpubManifest /// public EpubGuide? Guide { get; } + /// + /// Gets a list of elements which define related groups of resources within the EPUB book. + /// See for more information. + /// + public List Collections { get; } + + /// + /// Gets the ID of the OPF package or null if the package doesn't specify an ID. + /// See for more information. + /// + public string? Id { get; } + + /// + /// Gets the default text direction of the content of the EPUB book or null if the package doesn't specify a text direction. + /// See for more information. + /// + public EpubTextDirection? TextDirection { get; } + + /// + /// Gets the additional prefix mappings or null if the package doesn't specify additional prefix mappings. + /// See for more information. + /// + public string? Prefix { get; } + + /// + /// Gets the language of the content of the EPUB book or null if the package doesn't specify the language. + /// See for more information. + /// + public string? Language { get; } + /// /// Gets the string representation of the property. /// diff --git a/Source/VersOne.Epub/Schema/Opf/EpubVersion.cs b/Source/VersOne.Epub/Schema/Opf/Package/EpubVersion.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubVersion.cs rename to Source/VersOne.Epub/Schema/Opf/Package/EpubVersion.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubPageProgressionDirection.cs b/Source/VersOne.Epub/Schema/Opf/Spine/EpubPageProgressionDirection.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubPageProgressionDirection.cs rename to Source/VersOne.Epub/Schema/Opf/Spine/EpubPageProgressionDirection.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubSpine.cs b/Source/VersOne.Epub/Schema/Opf/Spine/EpubSpine.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubSpine.cs rename to Source/VersOne.Epub/Schema/Opf/Spine/EpubSpine.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubSpineItemRef.cs b/Source/VersOne.Epub/Schema/Opf/Spine/EpubSpineItemRef.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubSpineItemRef.cs rename to Source/VersOne.Epub/Schema/Opf/Spine/EpubSpineItemRef.cs diff --git a/Source/VersOne.Epub/Schema/Opf/EpubSpineProperty.cs b/Source/VersOne.Epub/Schema/Opf/Spine/EpubSpineProperty.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Opf/EpubSpineProperty.cs rename to Source/VersOne.Epub/Schema/Opf/Spine/EpubSpineProperty.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Smil.cs b/Source/VersOne.Epub/Schema/Ops/Narration/Smil.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Smil.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/Smil.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilAudio.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilAudio.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilAudio.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilAudio.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilBody.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilBody.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilBody.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilBody.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilHead.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilHead.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilHead.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilHead.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilMetadata.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilMetadata.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilMetadata.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilMetadata.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilPar.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilPar.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilPar.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilPar.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilSeq.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilSeq.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilSeq.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilSeq.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilText.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilText.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilText.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilText.cs diff --git a/Source/VersOne.Epub/Schema/Ops/SmilVersion.cs b/Source/VersOne.Epub/Schema/Ops/Narration/SmilVersion.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/SmilVersion.cs rename to Source/VersOne.Epub/Schema/Ops/Narration/SmilVersion.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3Nav.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3Nav.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3Nav.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3Nav.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3NavAnchor.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavAnchor.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3NavAnchor.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavAnchor.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3NavDocument.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavDocument.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3NavDocument.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavDocument.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3NavLi.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavLi.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3NavLi.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavLi.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3NavOl.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavOl.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3NavOl.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavOl.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3NavSpan.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavSpan.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3NavSpan.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3NavSpan.cs diff --git a/Source/VersOne.Epub/Schema/Ops/Epub3StructuralSemanticsProperty.cs b/Source/VersOne.Epub/Schema/Ops/Navigation/Epub3StructuralSemanticsProperty.cs similarity index 100% rename from Source/VersOne.Epub/Schema/Ops/Epub3StructuralSemanticsProperty.cs rename to Source/VersOne.Epub/Schema/Ops/Navigation/Epub3StructuralSemanticsProperty.cs