summaryrefslogtreecommitdiff
path: root/ThirdParty/CsvHelper-master/tests
diff options
context:
space:
mode:
Diffstat (limited to 'ThirdParty/CsvHelper-master/tests')
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ArrayHelperTests.cs79
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/ReadingTests.cs103
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/WritingTests.cs119
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/AutoMappingTests.cs394
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/BaseClassTests.cs52
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/CircularReferenceTests.cs98
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/ContextTests.cs36
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/IgnoreReferencesTests.cs62
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/MappingTypeOfTypeTest.cs41
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/StructTests.cs76
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ClassMapOrderingTests.cs110
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/ClassMapBuilderTests.cs335
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/CsvClassMapCollectionTests.cs70
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvClassMappingAutoMapTests.cs61
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvConfigurationTests.cs158
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.csproj63
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net452.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net47.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net50.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp2.1.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp3.1.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.v3.ncrunchproject5
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.snkbin0 -> 596 bytes
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserConstructorTests.cs28
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserDelimiterTests.cs344
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserRawRecordTests.cs143
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs1370
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderConstructorTests.cs52
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDefaultValueTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDynamicMappingsTests.cs63
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderErrorMessageTests.cs258
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderMappingTests.cs355
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingPrefixTests.cs92
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingTests.cs113
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderSubClassingTests.cs40
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderTests.cs1166
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterBoxedTypesTests.cs65
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterConstructorTests.cs28
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterFormatTests.cs201
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterMappingTests.cs350
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingPrefixTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingTests.cs156
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterSubClassingTests.cs42
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterTests.cs1030
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Culture/TypeConverterOptionsFactoryTests.cs229
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DataTableTests/CsvDataReaderTests.cs509
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Defaults/WritingDefaultsTests.cs118
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DisposeTests.cs55
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DynamicProxyTests.cs65
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/EnumerateRecordsTests.cs181
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionMessageTests.cs208
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionTests.cs52
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/HeaderValidationTests.cs280
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue1954.cs178
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue920.cs59
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/LocalCultureTests.cs72
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MapPropertyMultipleTimesTests.cs87
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MappingInheritedClassTests.cs42
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs29
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BooleanValuesTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs28
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ConstantTests.cs50
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DateTimeStylesTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DefaultTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs32
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs33
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EnumIgnoreCaseTests.cs91
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs32
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/FormatTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs30
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HeaderPrefixTests.cs205
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBaseTests.cs71
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs36
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreTests.cs93
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs29
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IndexTests.cs42
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameIndexTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameTests.cs38
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NullValuesTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NumberStylesTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/OptionalTests.cs41
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs29
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ReferenceTests.cs43
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs31
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TypeConverterTests.cs125
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs20
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesAttributeTests.cs110
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesMapTests.cs125
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesAttributeTests.cs110
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesMapTests.cs125
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantAttributeTests.cs109
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantMapTests.cs193
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs119
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoMapTests.cs160
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesAttributeTests.cs109
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesMapTests.cs152
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultAttributeTests.cs108
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultMapTests.cs152
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/EnumIgnoreCaseTests.cs113
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatAttributeTests.cs111
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatMapTests.cs156
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixAttributeTests.cs111
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixMapTests.cs6
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreAttributeTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreMapTests.cs150
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexAttributeTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexMapTests.cs149
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameAttributeTests.cs85
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexAttributeTests.cs85
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexMapTests.cs126
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameMapTests.cs126
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesAttributeTests.cs107
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesMapTests.cs122
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesAttributeTests.cs108
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesMapTests.cs151
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalAttributeTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalMapTests.cs150
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterAttributeTests.cs115
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterMapTests.cs158
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/CsvClassMappingTests.cs239
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/FieldMappingTests.cs397
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/HiddenBaseMembersTests.cs117
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/IgnoreHeaderWhiteSpaceTests.cs52
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MapConstructorTests.cs42
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MappingWithNoHeaderTests.cs243
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/OptionalTests.cs220
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Property/ConstantTests.cs74
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ReferenceConstructorArgsTests.cs50
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/RuntimeMapping.cs199
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/SubPropertyMappingTests.cs127
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/DynamicObjectMock.cs31
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMock.cs96
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMockTests.cs37
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ReaderRowMock.cs226
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectCreatorTests.cs351
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/Issue1073.cs72
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/ResolveSingleTypeTests.cs59
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BadDataTests.cs153
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingEscapeAndQuoteTests.cs38
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingLineEndingTests.cs98
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingNewLineEndingTests.cs102
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ByteCountTests.cs137
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CharCountTests.cs124
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CommentTests.cs125
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CrTests.cs235
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CsvModeTests.cs109
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DelimiterTests.cs81
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DetectDelimiterTests.cs286
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EndBufferTests.cs79
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EscapeCharacterTests.cs110
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ExcelCompatibilityTests.cs123
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/FieldCacheTests.cs94
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/MaxFieldSizeTests.cs50
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/NewLineTests.cs176
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/RefillingTextReaderTests.cs59
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/TrimTests.cs1206
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/AnonymousTypesTests.cs707
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/BadDataTests.cs64
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstantTests.cs114
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstructorParametersTests.cs220
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DetectColumnCountChangesTests.cs199
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DynamicTests.cs126
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/EmptyTextReaderTests.cs25
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleGetRecordsTests.cs60
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleHeadersTests.cs114
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/NullableValuesInEmptyColumnsInputTests.cs224
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/PrivateSettersInParentTests.cs90
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ReadHeaderTests.cs166
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ShouldSkipRecordTests.cs87
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/TryGetTests.cs228
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ValidateTests.cs197
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/YieldTests.cs142
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingClassMapTests.cs169
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingIndexTests.cs69
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reflection/GetMemberExpressionStackTests.cs56
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringBuilder.cs34
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringWriter.cs28
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ArrayConverterTests.cs211
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BigIntegerConverterTests.cs40
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BooleanConverterTests.cs166
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteArrayConverterTests.cs139
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteConverterTests.cs47
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CharConverterTests.cs50
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CollectionGenericConverterTests.cs101
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateOnlyConverterTests.cs59
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeConverterTests.cs76
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeOffsetConverterTests.cs75
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultConverterTests.cs81
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultValueTests.cs67
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DoubleConverterTests.cs39
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumConverterTests.cs367
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumerableConverterTests.cs32
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryConverterTests.cs303
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryGenericConverterTests.cs198
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableConverterTests.cs261
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableGenericConverterTests.cs265
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/SingleConverterTests.cs39
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeOnlyConverterTests.cs59
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeSpanConverterTests.cs54
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterCacheTests.cs243
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsFactoryTests.cs211
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsTests.cs110
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterTests.cs51
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/UriConverterTests.cs106
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/AnonymousTypesTests.cs34
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ConstantTests.cs126
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/CsvModeTests.cs145
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/DynamicTests.cs218
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs87
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IAsyncEnumerableTests.cs50
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IgnoreTests.cs51
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/InterfaceTests.cs90
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleFieldsFromOnePropertyTests.cs79
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleHeadersTest.cs84
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NewLineTests.cs92
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NoPropertyMappingTests.cs218
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/SanitizationTests.cs422
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs187
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/TrimTests.cs41
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteBufferTests.cs36
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteCustomEscapeTests.cs63
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteNullTests.cs84
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/XunitException.cs19
-rw-r--r--ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/xunit.runner.json4
242 files changed, 30652 insertions, 0 deletions
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ArrayHelperTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ArrayHelperTests.cs
new file mode 100644
index 0000000..45c26fe
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ArrayHelperTests.cs
@@ -0,0 +1,79 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests
+{
+
+ public class ArrayHelperTests
+ {
+ [Fact]
+ public void Contains_HasValue_ReturnsTrue()
+ {
+ var array = new char[] { 'a' };
+
+ var contains = ArrayHelper.Contains(array, 'a');
+
+ Assert.True(contains);
+ }
+
+ [Fact]
+ public void Contains_DoesNotHaveValue_ReturnsFalse()
+ {
+ var array = new char[] { 'a' };
+
+ var contains = ArrayHelper.Contains(array, 'b');
+
+ Assert.False(contains);
+ }
+
+ [Fact]
+ public void Trim_FullBuffer_TrimsChars()
+ {
+ var buffer = " a ".ToCharArray();
+ var trimChars = new char[] { ' ' };
+ var start = 0;
+ var length = buffer.Length;
+
+ ArrayHelper.Trim(buffer, ref start, ref length, trimChars);
+
+ Assert.Equal(1, start);
+ Assert.Equal(1, length);
+ }
+
+ [Fact]
+ public void Trim_MidBuffer_TrimsChars()
+ {
+ var buffer = "a b c".ToCharArray();
+ var trimChars = new char[] { ' ' };
+ var start = 1;
+ var length = 3;
+
+ ArrayHelper.Trim(buffer, ref start, ref length, trimChars);
+
+ Assert.Equal(2, start);
+ Assert.Equal(1, length);
+ }
+
+ [Fact]
+ public void Trim_AllWhitespace_EmptyString()
+ {
+ var buffer = new string(' ', 100).ToCharArray();
+ var trimChars = new char[] { ' ' };
+ var start = 0;
+ var length = buffer.Length;
+
+ ArrayHelper.Trim(buffer, ref start, ref length, trimChars);
+
+ Assert.Equal(100, start);
+ Assert.Equal(0, length);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/ReadingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/ReadingTests.cs
new file mode 100644
index 0000000..fdd7af8
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/ReadingTests.cs
@@ -0,0 +1,103 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Threading;
+using System;
+using System.Linq;
+
+namespace CsvHelper.Tests.Async
+{
+
+ public class ReadingTests
+ {
+ [Fact]
+ public async Task ReadingTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ null
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = new List<Simple>();
+ await csv.ReadAsync();
+ csv.ReadHeader();
+ while (await csv.ReadAsync())
+ {
+ records.Add(csv.GetRecord<Simple>());
+ }
+
+ Assert.Equal(2, records.Count);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+
+ record = records[1];
+ Assert.Equal(2, record.Id);
+ Assert.Equal("two", record.Name);
+ }
+ }
+
+#if NETCOREAPP
+ [Fact]
+ public async Task GetRecordsTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ null
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecordsAsync<Simple>().GetAsyncEnumerator();
+ await records.MoveNextAsync();
+
+ Assert.Equal(1, records.Current.Id);
+ Assert.Equal("one", records.Current.Name);
+
+ await records.MoveNextAsync();
+
+ Assert.Equal(2, records.Current.Id);
+ Assert.Equal("two", records.Current.Name);
+ }
+ }
+
+ [Fact]
+ public async Task GetRecordsTestCanceled()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ null
+ };
+ using (var source = new CancellationTokenSource())
+ using (var csv = new CsvReader(parser))
+ {
+ source.Cancel();
+ var records = csv.GetRecordsAsync<Simple>(source.Token).GetAsyncEnumerator();
+ await Assert.ThrowsAsync<OperationCanceledException>(async () => await records.MoveNextAsync());
+ }
+ }
+#endif
+
+ private class Simple
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/WritingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/WritingTests.cs
new file mode 100644
index 0000000..95fe623
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Async/WritingTests.cs
@@ -0,0 +1,119 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Async
+{
+
+ public class WritingTests
+ {
+ [Fact]
+ public async Task WritingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<Simple>
+ {
+ new Simple { Id = 1, Name = "one" },
+ new Simple { Id = 2, Name = "two" },
+ };
+ csv.WriteHeader<Simple>();
+ await csv.NextRecordAsync();
+ foreach (var record in records)
+ {
+ csv.WriteRecord(record);
+ await csv.NextRecordAsync();
+ }
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+ expected.AppendLine("2,two");
+
+ Assert.Equal(expected.ToString(), reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public async Task WriteRecordsTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<Simple>
+ {
+ new Simple { Id = 1, Name = "one" },
+ new Simple { Id = 2, Name = "two" },
+ };
+ await csv.WriteRecordsAsync(records);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+ expected.AppendLine("2,two");
+
+ Assert.Equal(expected.ToString(), reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public async Task WriteRecordsTestCanceled()
+ {
+ using (var source = new CancellationTokenSource())
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<Simple>
+ {
+ new Simple { Id = 1, Name = "one" },
+ new Simple { Id = 2, Name = "two" },
+ new Simple { Id = 3, Name = "three" },
+ };
+ source.Cancel();
+
+ try
+ {
+ await csv.WriteRecordsAsync(records, source.Token);
+ }
+ catch (WriterException ex)
+ {
+ if (ex.InnerException is OperationCanceledException || ex.InnerException is TaskCanceledException)
+ {
+ return;
+ }
+ }
+
+ throw new XUnitException("Did not throw exception");
+ }
+ }
+
+ private class Simple
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/AutoMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/AutoMappingTests.cs
new file mode 100644
index 0000000..6e9cd89
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/AutoMappingTests.cs
@@ -0,0 +1,394 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+ public class AutoMappingTests
+ {
+ public AutoMappingTests()
+ {
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+ }
+
+ [Fact]
+ public void ReaderSimpleTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var list = csv.GetRecords<Simple>().ToList();
+
+ Assert.NotNull(list);
+ Assert.Equal(2, list.Count);
+ var row = list[0];
+ Assert.Equal(1, row.Id);
+ Assert.Equal("one", row.Name);
+ row = list[1];
+ Assert.Equal(2, row.Id);
+ Assert.Equal("two", row.Name);
+ }
+ }
+
+ [Fact]
+ public void ReaderFloatingCultureDeTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.GetCultureInfo("de-DE")))
+ {
+ writer.WriteLine("Single;Double;Decimal");
+ writer.WriteLine("1,1;+0000002,20;3,30000");
+ writer.WriteLine("-0,1;-0,2;-,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ var list = csv.GetRecords<Numbers>().ToList();
+
+ Assert.NotNull(list);
+ Assert.Equal(2, list.Count);
+ var row = list[0];
+ Assert.Equal(1.1f, row.Single, 4);
+ Assert.Equal(2.2d, row.Double, 4);
+ Assert.Equal(3.3m, row.Decimal);
+
+ row = list[1];
+ Assert.Equal(-0.1f, row.Single, 4);
+ Assert.Equal(-0.2d, row.Double, 4);
+ Assert.Equal(-0.3m, row.Decimal);
+ }
+ }
+
+ [Fact]
+ public void ReaderReferenceTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("AId,BId");
+ writer.WriteLine("1,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ var list = csv.GetRecords<A>().ToList();
+
+ Assert.NotNull(list);
+ Assert.Single(list);
+ var row = list[0];
+ Assert.Equal(1, row.AId);
+ Assert.NotNull(row.B);
+ Assert.Equal(2, row.B.BId);
+ }
+ }
+
+ [Fact]
+ public void ReaderReferenceHasNoDefaultConstructorTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => args.Header.ToLower(),
+ };
+ var s = new StringBuilder();
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one");
+ using (var csv = new CsvReader(new StringReader(s.ToString()), config))
+ {
+ var records = csv.GetRecords<SimpleReferenceHasNoDefaultConstructor>().ToList();
+ var row = records[0];
+ Assert.Equal(1, row.Id);
+ Assert.Equal("one", row.Ref.Name);
+ }
+ }
+
+ [Fact]
+ public void ReaderHasNoDefaultConstructorReferenceHasNoDefaultConstructorTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => args.Header.ToLower(),
+ };
+ var s = new StringBuilder();
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one");
+ using (var csv = new CsvReader(new StringReader(s.ToString()), config))
+ {
+ var records = csv.GetRecords<SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor>().ToList();
+ var row = records[0];
+ Assert.Equal(1, row.Id);
+ Assert.Equal("one", row.Ref.Name);
+ }
+ }
+
+ [Fact]
+ public void WriterSimpleTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Simple>
+ {
+ new Simple { Id = 1, Name = "one" }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ [Fact]
+ public void WriterReferenceTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<A>
+ {
+ new A
+ {
+ AId = 1,
+ B = new B
+ {
+ BId = 2
+ }
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("AId,BId");
+ expected.AppendLine("1,2");
+
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ [Fact]
+ public void WriterReferenceHasNoDefaultConstructorTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<SimpleReferenceHasNoDefaultConstructor>
+ {
+ new SimpleReferenceHasNoDefaultConstructor
+ {
+ Id = 1,
+ Ref = new NoDefaultConstructor( "one" )
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriterHasNoDefaultConstructorReferenceHasNoDefaultConstructorTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor>
+ {
+ new SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor(1, new NoDefaultConstructor("one"))
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void AutoMapEnumerableTest()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+
+ Assert.Throws<ConfigurationException>(() => context.AutoMap(typeof(List<string>)));
+ }
+
+ [Fact]
+ public void AutoMapWithExistingMapTest()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var existingMap = new SimpleMap();
+ context.Maps.Add(existingMap);
+ var data = new
+ {
+ Simple = new Simple
+ {
+ Id = 1,
+ Name = "one"
+ }
+ };
+ var map = context.AutoMap(data.GetType());
+
+ Assert.NotNull(map);
+ Assert.Empty(map.MemberMaps);
+ Assert.Single(map.ReferenceMaps);
+
+ // Since Simple is a reference on the anonymous object, the type won't
+ // be re-used. Types which are created from automapping aren't added
+ // to the list of registered maps either.
+ Assert.IsNotType<SimpleMap>(map.ReferenceMaps[0].Data.Mapping);
+ }
+
+ [Fact]
+ public void AutoMapWithNestedHeaders()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReferenceHeaderPrefix = args => $"{args.MemberName}."
+ };
+ var context = new CsvContext(config);
+ var map = context.AutoMap<Nested>();
+ Assert.Equal("Simple1.Id", map.ReferenceMaps[0].Data.Mapping.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("Simple1.Name", map.ReferenceMaps[0].Data.Mapping.MemberMaps[1].Data.Names[0]);
+ Assert.Equal("Simple2.Id", map.ReferenceMaps[1].Data.Mapping.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("Simple2.Name", map.ReferenceMaps[1].Data.Mapping.MemberMaps[1].Data.Names[0]);
+ }
+
+ [Fact]
+ public void AutoMapWithDefaultConstructor()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ ClassMap map = context.AutoMap<SimpleReferenceHasNoDefaultConstructor>();
+
+ Assert.Equal("Id", map.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ReferenceMaps[0].Data.Mapping.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("name", map.ReferenceMaps[0].Data.Mapping.ParameterMaps[0].Data.Names[0]);
+ }
+
+ [Fact]
+ public void AutoMapWithNoDefaultConstructor()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor>();
+
+ Assert.Equal("Id", map.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("id", map.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("name", map.ParameterMaps[1].ConstructorTypeMap.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ReferenceMaps[0].Data.Mapping.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("name", map.ReferenceMaps[0].Data.Mapping.ParameterMaps[0].Data.Names[0]);
+ }
+
+ private class Nested
+ {
+ public Simple Simple1 { get; set; }
+
+ public Simple Simple2 { get; set; }
+ }
+
+ private class Simple
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class SimpleMap : ClassMap<Simple>
+ {
+ public SimpleMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+
+ private class Numbers
+ {
+ public float Single { get; set; }
+ public double Double { get; set; }
+ public decimal Decimal { get; set; }
+ }
+
+ private class A
+ {
+ public int AId { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public int BId { get; set; }
+ }
+
+ private class SimpleReferenceHasNoDefaultConstructor
+ {
+ public int Id { get; set; }
+
+ public NoDefaultConstructor Ref { get; set; }
+ }
+
+ private class SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor
+ {
+ public int Id { get; set; }
+
+ public NoDefaultConstructor Ref { get; set; }
+
+ public SimpleHasNoDefaultConstructorReferenceHasNoDefaultConstructor(int id, NoDefaultConstructor ref_)
+ {
+ Id = id;
+ Ref = ref_;
+ }
+ }
+
+ private class NoDefaultConstructor
+ {
+ public string Name { get; set; }
+
+ public NoDefaultConstructor(string name)
+ {
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/BaseClassTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/BaseClassTests.cs
new file mode 100644
index 0000000..52118f3
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/BaseClassTests.cs
@@ -0,0 +1,52 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class BaseClassTests
+ {
+ [Fact]
+ public void EnsureChildNotWrittenWhenListIsParent()
+ {
+ var record = new Child
+ {
+ ChildProp = "child",
+ ParentProp = "parent"
+ };
+ Parent[] records = { record };
+
+ using( var stream = new MemoryStream() )
+ using( var writer = new StreamWriter( stream ) )
+ using( var reader = new StreamReader( stream ) )
+ using( var csv = new CsvWriter(writer, CultureInfo.InvariantCulture) )
+ {
+ csv.WriteRecords( records );
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine( "ParentProp" );
+ expected.AppendLine( "parent" );
+
+ Assert.Equal( expected.ToString(), reader.ReadToEnd() );
+ }
+ }
+
+ private class Parent
+ {
+ public string ParentProp { get; set; }
+ }
+
+ private class Child : Parent
+ {
+ public string ChildProp { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/CircularReferenceTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/CircularReferenceTests.cs
new file mode 100644
index 0000000..0ae94e7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/CircularReferenceTests.cs
@@ -0,0 +1,98 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System.Globalization;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class CircularReferenceTests
+ {
+ [Fact]
+ public void SelfCircularDependencyTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<SelfCircularA>();
+ }
+
+ [Fact]
+ public void CircularDependencyTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<ACircular>();
+ Assert.NotNull(map);
+ Assert.Single(map.MemberMaps);
+ Assert.Single(map.ReferenceMaps);
+ Assert.Single(map.ReferenceMaps[0].Data.Mapping.MemberMaps);
+ Assert.Empty(map.ReferenceMaps[0].Data.Mapping.ReferenceMaps);
+ }
+
+ [Fact]
+ public void CircularDependencyWithMultiplePropertiesTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<A>();
+ Assert.Single(map.MemberMaps);
+ Assert.Equal(3, map.ReferenceMaps.Count);
+ }
+
+ private class SelfCircularA
+ {
+ public SelfCircularB Circular { get; set; }
+ }
+
+ private class SelfCircularB
+ {
+ public SelfCircularB Self { get; set; }
+
+ public SelfCircularC C { get; set; }
+ }
+
+ private class SelfCircularC
+ {
+ public string Id { get; set; }
+ }
+
+ private class ACircular
+ {
+ public string Id { get; set; }
+
+ public BCircular B { get; set; }
+ }
+
+ private class BCircular
+ {
+ public string Id { get; set; }
+
+ public ACircular A { get; set; }
+ }
+
+ private class A
+ {
+ public string Id { get; set; }
+
+ public B B1 { get; set; }
+
+ public B B2 { get; set; }
+
+ public B B3 { get; set; }
+ }
+
+ private class B
+ {
+ public string Id { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string Id { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/ContextTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/ContextTests.cs
new file mode 100644
index 0000000..2e41972
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/ContextTests.cs
@@ -0,0 +1,36 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class ContextTests
+ {
+ [Fact]
+ public void AutoMap_UsesContext()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("Bar");
+
+ var map = context.AutoMap<Foo>();
+
+ Assert.Contains("Bar", map.MemberMaps.Find<Foo>(x => x.Name).Data.TypeConverterOptions.NullValues);
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/IgnoreReferencesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/IgnoreReferencesTests.cs
new file mode 100644
index 0000000..bc9e8b2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/IgnoreReferencesTests.cs
@@ -0,0 +1,62 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class IgnoreReferencesTests
+ {
+ [Fact]
+ public void IgnoreReferncesWritingTest()
+ {
+ var records = new List<Foo>
+ {
+ new Foo
+ {
+ Id = 1,
+ Bar = new Bar { Name = "one" }
+ }
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreReferences = true,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public Bar Bar { get; set; }
+ }
+
+ private class Bar
+ {
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/MappingTypeOfTypeTest.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/MappingTypeOfTypeTest.cs
new file mode 100644
index 0000000..f244505
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/MappingTypeOfTypeTest.cs
@@ -0,0 +1,41 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class MappingTypeOfTypeTest
+ {
+ [Fact]
+ public void ClassWithPropertyOfTypeTypeShouldNotCauseStackOverflowExceptionTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<EquipmentDataPoint>().ToList();
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ }
+ }
+
+ public class EquipmentDataPoint
+ {
+ public int Id { get; set; }
+
+ [CsvHelper.Configuration.Attributes.Ignore]
+ public Type ValueType { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/StructTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/StructTests.cs
new file mode 100644
index 0000000..8ad3da9
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/AutoMapping/StructTests.cs
@@ -0,0 +1,76 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.AutoMapping
+{
+
+ public class StructTests
+ {
+ [Fact]
+ public void StructTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<B>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void StructPropertyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReferenceHeaderPrefix = args => $"{args.MemberName}.",
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Simple1.Id,Simple1.Name,Simple2.Id,Simple2.Name,Title");
+ writer.WriteLine("1,one,2,two,Works!");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal(1, records[0].Simple1.Id);
+ Assert.Equal("one", records[0].Simple1.Name);
+ Assert.Equal(2, records[0].Simple2.Id);
+ Assert.Equal("two", records[0].Simple2.Name);
+ Assert.Equal("Works!", records[0].Title);
+ }
+ }
+
+ public class A
+ {
+ public B Simple1 { get; set; }
+ public string Title { get; set; }
+ public B Simple2 { get; set; }
+ }
+
+ public struct B
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ClassMapOrderingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ClassMapOrderingTests.cs
new file mode 100644
index 0000000..c0c4382
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ClassMapOrderingTests.cs
@@ -0,0 +1,110 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class ClassMapOrderingTests
+ {
+ [Fact]
+ public void OrderingTest()
+ {
+ var list = new List<ContainerClass>
+ {
+ new ContainerClass
+ {
+ Contents = new ThirdClass
+ {
+ Third = 3,
+ Second = new SecondClass
+ {
+ Second = 2,
+ },
+ First = new FirstClass
+ {
+ First = 1,
+ },
+ }
+ },
+ };
+
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<ContainerClassMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.Equal("First,Second,Third", reader.ReadLine());
+ }
+ }
+
+ private class ContainerClass
+ {
+ public ThirdClass Contents { get; set; }
+ }
+
+ private class ThirdClass
+ {
+ public int Third { get; set; }
+
+ public SecondClass Second { get; set; }
+
+ public FirstClass First { get; set; }
+ }
+
+ private sealed class ContainerClassMap : ClassMap<ContainerClass>
+ {
+ public ContainerClassMap()
+ {
+ References<ThirdClassMap>(m => m.Contents);
+ }
+ }
+
+ private sealed class ThirdClassMap : ClassMap<ThirdClass>
+ {
+ public ThirdClassMap()
+ {
+ References<FirstClassMap>(m => m.First);
+ References<SecondClassMap>(m => m.Second);
+ Map(m => m.Third);
+ }
+ }
+
+ private class SecondClass
+ {
+ public int Second { get; set; }
+ }
+
+ private sealed class SecondClassMap : ClassMap<SecondClass>
+ {
+ public SecondClassMap()
+ {
+ Map(m => m.Second);
+ }
+ }
+
+ private class FirstClass
+ {
+ public int First { get; set; }
+ }
+
+ private sealed class FirstClassMap : ClassMap<FirstClass>
+ {
+ public FirstClassMap()
+ {
+ Map(m => m.First);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/ClassMapBuilderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/ClassMapBuilderTests.cs
new file mode 100644
index 0000000..f1921ee
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/ClassMapBuilderTests.cs
@@ -0,0 +1,335 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Linq;
+using System.Linq.Expressions;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.Configuration
+{
+
+ public class ClassMapBuilderTests
+ {
+ private static readonly Factory csvFactory = new Factory();
+ private static ConvertFromString<FakeInnerClass> ConvertExpression => args => new FakeInnerClass { E = args.Row.GetField(4) };
+ private static readonly ClassMap<FakeClass> map = csvFactory.CreateClassMapBuilder<FakeClass>()
+ /*
+ .Map( m => m.A ).Constant( "a" )
+ .Map( m => m.A ).ConvertUsing( row => row.GetField( 0 ) )
+ .Map( m => m.A ).Default( "a" )
+ .Map( m => m.A ).Index( 0 )
+ .Map( m => m.A ).Index( 0 ).Validate( field => true )
+ .Map( m => m.A ).Index( 0 ).Default( "a" )
+ .Map( m => m.A ).Index( 0 ).Default( "a" ).Validate( field => true )
+ .Map( m => m.A ).Index( 0 ).Name( "a" )
+ .Map( m => m.A ).Index( 0 ).Name( "a" ).Validate( field => true )
+ .Map( m => m.A ).Index( 0 ).TypeConverter<StringConverter>()
+ .Map( m => m.A ).Index( 0 ).TypeConverter<StringConverter>().Validate( field => true )
+ .Map( m => m.A ).Name( "a" )
+ .Map( m => m.A ).Name( "a" ).Validate( field => true )
+ .Map( m => m.A ).Name( "a" ).Default( "a" )
+ .Map( m => m.A ).Name( "a" ).Default( "a" ).Validate( field => true )
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 )
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 ).Validate( field => true )
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 ).Default( "a" )
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 ).Default( "a" ).Validate( field => true )
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 ).TypeConverter<StringConverter>()
+ .Map( m => m.A ).Name( "a" ).NameIndex( 0 ).TypeConverter<StringConverter>().Validate( field => true )
+ .Map( m => m.A ).Name( "a" ).TypeConverter<StringConverter>()
+ .Map( m => m.A ).Name( "a" ).TypeConverter<StringConverter>().Validate( field => true )
+ .Map( m => m.A ).TypeConverter<StringConverter>()
+ .Map( m => m.A ).TypeConverter<StringConverter>().Validate( field => true )
+ .Map( m => m.A ).TypeConverter<StringConverter>().Default( "a" )
+ .Map( m => m.A ).TypeConverter<StringConverter>().Default( "a" ).Validate( field => true )
+ */
+
+ .Map(m => m.A).Name("A1").NameIndex(2).Default("WEW")
+ .Map(m => m.B).Name("B2").Default(2)
+ .Map(m => m.C).Index(2).TypeConverter(new DateTimeConverter())
+ .Map(m => m.D).Name("D4").TypeConverter<DoubleConverter>().Default(4d)
+ .Map(m => m.E).ConvertUsing(ConvertExpression)
+ .Map(m => m.Optional).Optional()
+ .Build();
+
+ [Fact]
+ public void ClassMapBuilderAddsPropertyMapsCorrectly()
+ {
+ Assert.Equal(6, map.MemberMaps.Count);//IMappable
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsOptionalCorrectly()
+ {
+ Assert.True(map.MemberMaps[5].Data.IsOptional);
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsTypeConvertersCorrectly()
+ {
+ Assert.Equal(typeof(DateTimeConverter), map.MemberMaps[2].Data.TypeConverter.GetType());//2
+ Assert.Equal(typeof(DoubleConverter), map.MemberMaps[3].Data.TypeConverter.GetType());//2
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsIndexesCorrectly()
+ {
+ Assert.Equal(2, map.MemberMaps[2].Data.Index); //3
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsNamesCorrectly()
+ {
+ Assert.Equal("D4", map.MemberMaps[3].Data.Names.Single()); //4
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsNameIndexesCorrectly()
+ {
+ Assert.Equal(2, map.MemberMaps[0].Data.NameIndex); //5
+ }
+
+ //this one is kind of hacky, but i'm not sure how else to test it more robustly since the function gets converted to an expression inside the CsvClassMap
+ [Fact]
+ public void ClassMapBuilderAddsConvertUsingFunctionCorrectly()
+ {
+ var fakeRow = new BuilderRowFake();
+ var args = new ConvertFromStringArgs(fakeRow);
+ Assert.Equal(ConvertExpression(args).E, (map.MemberMaps[4].Data.ReadingConvertExpression as Expression<ConvertFromString<FakeInnerClass>>).Compile()(args).E); //6
+ }
+
+ [Fact]
+ public void ClassMapBuilderAddsDefaultsCorrectly()
+ {
+ Assert.Equal("WEW", map.MemberMaps[0].Data.Default);//7
+ Assert.Equal(4d, map.MemberMaps[3].Data.Default);//7
+ }
+
+ private class BuilderRowFake : IReaderRow
+ {
+ public IReaderConfiguration Configuration { get; }
+ public string[] FieldHeaders { get; }
+ public string[] CurrentRecord { get; }
+ public int Row { get; }
+
+ public CsvContext Context => throw new NotImplementedException();
+
+ public int CurrentIndex => throw new NotImplementedException();
+
+ public string[] HeaderRecord => throw new NotImplementedException();
+
+ public IParser Parser => throw new NotImplementedException();
+
+ public int ColumnCount => throw new NotImplementedException();
+
+ string IReaderRow.this[int index] => throw new NotImplementedException();
+
+ string IReaderRow.this[string name] => throw new NotImplementedException();
+
+ string IReaderRow.this[string name, int index] => throw new NotImplementedException();
+
+ public string GetField(int index)
+ {
+ return index.ToString();
+ }
+
+ public string GetField(string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetField(string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(int index) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(string name) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(string name, int index) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, int index, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, int index, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, int index, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, int index, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(int index, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, int index, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(int index, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, int index, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(int index, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(string name, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(string name, int index, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool IsRecordEmpty()
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetRecord<T>()
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetRecord(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetRecord<T>(T anonymousTypeDefinition)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
+ private class FakeClass
+ {
+ public string A { get; set; }
+ public int B { get; set; }
+ public DateTime C { get; set; }
+ public double D { get; set; }
+ public FakeInnerClass E { get; set; }
+ public string Optional { get; set; }
+ }
+
+ private class FakeInnerClass
+ {
+ public string E { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/CsvClassMapCollectionTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/CsvClassMapCollectionTests.cs
new file mode 100644
index 0000000..d93b22c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Configuration/CsvClassMapCollectionTests.cs
@@ -0,0 +1,70 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.Collections;
+using System;
+
+namespace CsvHelper.Tests.Configuration
+{
+
+ public class CsvClassMapCollectionTests
+ {
+ [Fact]
+ public void GetChildMapWhenParentIsMappedBeforeIt()
+ {
+ var parentMap = new ParentMap();
+ var childMap = new ChildMap();
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var c = new ClassMapCollection(context);
+ c.Add(parentMap);
+ c.Add(childMap);
+
+ var map = c[typeof(Child)];
+ Assert.Equal(childMap, map);
+ }
+
+ [Fact]
+ public void Add_Enumerable_HasConvertSet_DoesNotAssignTypeConverter()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var collection = new ClassMapCollection(context);
+
+ var map = new EnumerablePropertyClassMap();
+ collection.Add(map);
+ Assert.Null(map.MemberMaps.Find<EnumerablePropertyClass>(m => m.Enumerable).Data.TypeConverter);
+ }
+
+ private class Parent { }
+
+ private class Child : Parent { }
+
+ private sealed class ParentMap : ClassMap<Parent> { }
+
+ private sealed class ChildMap : ClassMap<Child> { }
+
+ private class EnumerablePropertyClass
+ {
+ public Enumerable Enumerable { get; set; }
+ }
+
+ private class EnumerablePropertyClassMap : ClassMap<EnumerablePropertyClass>
+ {
+ public EnumerablePropertyClassMap()
+ {
+ Map(m => m.Enumerable).Convert(_ => new Enumerable());
+ }
+ }
+
+ private class Enumerable : IEnumerable
+ {
+ public IEnumerator GetEnumerator()
+ {
+ throw new NotSupportedException();
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvClassMappingAutoMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvClassMappingAutoMapTests.cs
new file mode 100644
index 0000000..610a288
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvClassMappingAutoMapTests.cs
@@ -0,0 +1,61 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using CsvHelper.Configuration;
+using System.Globalization;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvClassMappingAutoMapTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var aMap = new AMap();
+
+ Assert.Equal(3, aMap.MemberMaps.Count);
+ Assert.Equal(0, aMap.MemberMaps[0].Data.Index);
+ Assert.Equal(1, aMap.MemberMaps[1].Data.Index);
+ Assert.Equal(2, aMap.MemberMaps[2].Data.Index);
+ Assert.True(aMap.MemberMaps[2].Data.Ignore);
+
+ Assert.Single(aMap.ReferenceMaps);
+ }
+
+ private class A
+ {
+ public int One { get; set; }
+
+ public int Two { get; set; }
+
+ public int Three { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public int Four { get; set; }
+
+ public int Five { get; set; }
+
+ public int Six { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ AutoMap(CultureInfo.InvariantCulture);
+ Map(m => m.Three).Ignore();
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvConfigurationTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvConfigurationTests.cs
new file mode 100644
index 0000000..26294fa
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvConfigurationTests.cs
@@ -0,0 +1,158 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvConfigurationTests
+ {
+ [Fact]
+ public void EnsureReaderAndParserConfigIsAreSameTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ {
+ var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
+
+ Assert.Same(csvReader.Configuration, csvReader.Parser.Configuration);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var parser = new CsvParser(reader, config);
+ csvReader = new CsvReader(parser);
+
+ Assert.Same(csvReader.Configuration, csvReader.Parser.Configuration);
+ }
+ }
+
+ [Fact]
+ public void AddingMappingsWithGenericMethod1Test()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap<TestClassMappings>();
+
+ Assert.Equal(2, context.Maps[typeof(TestClass)].MemberMaps.Count);
+ }
+
+ [Fact]
+ public void AddingMappingsWithGenericMethod2Test()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap<TestClassMappings>();
+
+ Assert.Equal(2, context.Maps[typeof(TestClass)].MemberMaps.Count);
+ }
+
+ [Fact]
+ public void AddingMappingsWithNonGenericMethodTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap(typeof(TestClassMappings));
+
+ Assert.Equal(2, context.Maps[typeof(TestClass)].MemberMaps.Count);
+ }
+
+ [Fact]
+ public void AddingMappingsWithInstanceMethodTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap(new TestClassMappings());
+
+ Assert.Equal(2, context.Maps[typeof(TestClass)].MemberMaps.Count);
+ }
+
+ [Fact]
+ public void RegisterClassMapGenericTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ context.RegisterClassMap<TestClassMappings>();
+ Assert.NotNull(context.Maps[typeof(TestClass)]);
+ }
+
+ [Fact]
+ public void RegisterClassMapNonGenericTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ context.RegisterClassMap(typeof(TestClassMappings));
+ Assert.NotNull(context.Maps[typeof(TestClass)]);
+ }
+
+ [Fact]
+ public void RegisterClassInstanceTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ context.RegisterClassMap(new TestClassMappings());
+ Assert.NotNull(context.Maps[typeof(TestClass)]);
+ }
+
+ [Fact]
+ public void UnregisterClassMapGenericTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ context.RegisterClassMap<TestClassMappings>();
+ Assert.NotNull(context.Maps[typeof(TestClass)]);
+
+ context.UnregisterClassMap<TestClassMappings>();
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ }
+
+ [Fact]
+ public void UnregisterClassNonMapGenericTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ context.RegisterClassMap(typeof(TestClassMappings));
+ Assert.NotNull(context.Maps[typeof(TestClass)]);
+
+ context.UnregisterClassMap(typeof(TestClassMappings));
+ Assert.Null(context.Maps[typeof(TestClass)]);
+ }
+
+ [Fact]
+ public void AddingMappingsWithNonGenericMethodThrowsWhenNotACsvClassMap()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+
+ Assert.Throws<ArgumentException>(() => context.RegisterClassMap(typeof(TestClass)));
+ }
+
+ private class TestClass
+ {
+ public string StringColumn { get; set; }
+ public int IntColumn { get; set; }
+ }
+
+ private class TestClassMappings : ClassMap<TestClass>
+ {
+ public TestClassMappings()
+ {
+ Map(c => c.StringColumn);
+ Map(c => c.IntColumn);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.csproj b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.csproj
new file mode 100644
index 0000000..345fbd3
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.csproj
@@ -0,0 +1,63 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <!--<TargetFrameworks>net6.0;net5.0;netcoreapp3.1;netcoreapp2.1;net47;net45</TargetFrameworks>-->
+ <TargetFrameworks>net6.0</TargetFrameworks>
+ <LangVersion>preview</LangVersion>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>CsvHelper.snk</AssemblyOriginatorKeyFile>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <None Remove="*.ncrunchproject" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Castle.Core" Version="4.4.1" />
+ <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
+ <PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
+ <PackageReference Include="System.Linq.Async" Version="5.0.0" />
+ <PackageReference Include="xunit" Version="2.4.1" />
+ <PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ <PrivateAssets>all</PrivateAssets>
+ </PackageReference>
+ <PackageReference Include="coverlet.collector" Version="3.0.3">
+ <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+ <PrivateAssets>all</PrivateAssets>
+ </PackageReference>
+ </ItemGroup>
+
+ <!-- .NET 4.5 -->
+ <ItemGroup Condition="'$(TargetFramework)' == 'net45'">
+ <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
+ <PackageReference Include="System.Buffers" Version="4.5.1" />
+ <PackageReference Include="System.Memory" Version="4.5.4" />
+ <PackageReference Include="System.ValueTuple" Version="4.4.0" />
+ <PackageReference Remove="System.Linq.Async" Version="*" />
+ </ItemGroup>
+
+ <!-- .NET 4.7 -->
+ <ItemGroup Condition="'$(TargetFramework)' == 'net47'">
+ <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
+ <PackageReference Include="Microsoft.Bcl.HashCode" Version="1.1.0" />
+ <PackageReference Include="Microsoft.CSharp" Version="4.5.0" />
+ <PackageReference Include="System.Buffers" Version="4.5.1" />
+ <PackageReference Include="System.Memory" Version="4.5.4" />
+ <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
+ </ItemGroup>
+
+ <!-- .NET Standard 2.0 -->
+ <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
+ <PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
+ <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\..\src\CsvHelper\CsvHelper.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <Content Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net452.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net452.v3.ncrunchproject
new file mode 100644
index 0000000..9d694dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net452.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>True</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net47.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net47.v3.ncrunchproject
new file mode 100644
index 0000000..9d694dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net47.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>True</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net50.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net50.v3.ncrunchproject
new file mode 100644
index 0000000..9d694dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.net50.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>True</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp2.1.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp2.1.v3.ncrunchproject
new file mode 100644
index 0000000..9d694dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp2.1.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>True</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp3.1.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp3.1.v3.ncrunchproject
new file mode 100644
index 0000000..9d694dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.netcoreapp3.1.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>True</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.v3.ncrunchproject b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.v3.ncrunchproject
new file mode 100644
index 0000000..ba4c70e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.Tests.v3.ncrunchproject
@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+ <Settings>
+ <PreventSigningOfAssembly>False</PreventSigningOfAssembly>
+ </Settings>
+</ProjectConfiguration> \ No newline at end of file
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.snk b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.snk
new file mode 100644
index 0000000..8c9bfaf
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvHelper.snk
Binary files differ
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserConstructorTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserConstructorTests.cs
new file mode 100644
index 0000000..867e551
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserConstructorTests.cs
@@ -0,0 +1,28 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvParserConstructorTests
+ {
+ [Fact]
+ public void EnsureInternalsAreSetupWhenPassingReaderAndConfigTest()
+ {
+ using( var stream = new MemoryStream() )
+ using( var reader = new StreamReader( stream ) )
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ using( var parser = new CsvParser( reader, config ) )
+ {
+ Assert.Same( config, parser.Configuration );
+ }
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserDelimiterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserDelimiterTests.cs
new file mode 100644
index 0000000..3ae27ba
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserDelimiterTests.cs
@@ -0,0 +1,344 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvParserDelimiterTests
+ {
+ [Fact]
+ public void DifferentDelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "\t",
+ WhiteSpaceChars = new[] { ' ' },
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1\t2\t3");
+ writer.WriteLine("4\t5\t6");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void MultipleCharDelimiter2Test()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "``",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1``2``3");
+ writer.WriteLine("4``5``6");
+ writer.Flush();
+ stream.Position = 0;
+
+ var hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.False(hasRecords);
+ }
+ }
+
+ [Fact]
+ public void MultipleCharDelimiter3Test()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`\t`",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1`\t`2`\t`3");
+ writer.WriteLine("4`\t`5`\t`6");
+ writer.Flush();
+ stream.Position = 0;
+
+ var hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.False(hasRecords);
+ }
+ }
+
+ [Fact]
+ public void AllFieldsEmptyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine(";;;;");
+ writer.WriteLine(";;;;");
+ writer.Flush();
+ stream.Position = 0;
+
+ var hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.False(hasRecords);
+ }
+ }
+
+ [Fact]
+ public void AllFieldsEmptyNoEolOnLastLineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write(";;;;\r\n");
+ writer.Write(";;;;");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void EmptyLastFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1;;2;;");
+ writer.WriteLine("4;;5;;");
+ writer.Flush();
+ stream.Position = 0;
+
+ var hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ hasRecords = parser.Read();
+ Assert.False(hasRecords);
+ }
+ }
+
+ [Fact]
+ public void EmptyLastFieldNoEolOnLastLineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1;;2;;\r\n");
+ writer.Write("4;;5;;");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void DifferentDelimiter2ByteCountTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1;;2\r\n");
+ writer.Write("4;;5\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(6, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(12, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void DifferentDelimiter3ByteCountTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ Delimiter = ";;;",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1;;;2\r\n");
+ writer.Write("4;;;5\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(7, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(14, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void MultipleCharDelimiterWithBufferEndingInMiddleOfDelimiterTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "|~|",
+ BufferSize = 16,
+ };
+
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("12340000004321|~|2");
+ writer.Flush();
+ stream.Position = 0;
+
+ var hasRecords = parser.Read();
+ Assert.True(hasRecords);
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("12340000004321", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ hasRecords = parser.Read();
+ Assert.False(hasRecords);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserRawRecordTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserRawRecordTests.cs
new file mode 100644
index 0000000..ec127da
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserRawRecordTests.cs
@@ -0,0 +1,143 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvParserRawRecordTests
+ {
+ [Fact]
+ public void RawRecordCrLfTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1,2\r\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal("3,4\r\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(string.Empty, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void RawRecordCrTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r");
+ writer.Write("3,4\r");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1,2\r", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal("3,4\r", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(string.Empty, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void RawRecordLfTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\n");
+ writer.Write("3,4\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1,2\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal("3,4\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(string.Empty, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void RawRecordCr2DelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";;",
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1;;2\r");
+ writer.Write("3;;4\r");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1;;2\r", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal("3;;4\r", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(string.Empty, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void TinyBufferTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 1,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1,2\r\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal("3,4\r\n", parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(string.Empty, parser.RawRecord.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs
new file mode 100644
index 0000000..78beeaf
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvParserTests.cs
@@ -0,0 +1,1370 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvParserTests
+ {
+ [Fact]
+ public void SimpleParseTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.True(parser.Read());
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseNewRecordTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ var count = 0;
+ while (parser.Read())
+ {
+ count++;
+ }
+
+ Assert.Equal(2, count);
+ }
+
+ [Fact]
+ public void ParseEmptyRowsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.WriteLine(",,");
+ writer.WriteLine("");
+ writer.WriteLine("");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, config);
+
+ var records = new List<string[]>();
+ while (parser.Read())
+ {
+ records.Add(parser.Record);
+ }
+
+ Assert.Equal(4, records.Count);
+ }
+
+ [Fact]
+ public void ParseTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("five", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseFieldQuotesTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,\"two\",three");
+ writer.WriteLine("four,\"\"\"five\"\"\",six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("\"five\"", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseSpacesTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine(" one , \"two three\" , four ");
+ writer.WriteLine(" \" five \"\" six \"\" seven \" ");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal(" one ", parser[0]);
+ Assert.Equal(" \"two three\" ", parser[1]);
+ Assert.Equal(" four ", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(" \" five \"\" six \"\" seven \" ", parser[0]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void CallingReadMultipleTimesAfterDoneReadingTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("four,five,six");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ }
+
+ [Fact]
+ public void ParseEmptyTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseCrOnlyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("\r");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseLfOnlyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseCrLnOnlyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Parse1RecordWithNoCrlfTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two,three");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Parse2RecordsLastWithNoCrlfTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("one,two,three");
+ streamWriter.Write("four,five,six");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ parser.Read();
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("four", parser[0]);
+ Assert.Equal("five", parser[1]);
+ Assert.Equal("six", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ParseFirstFieldIsEmptyQuotedTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"\",\"two\",\"three\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseLastFieldIsEmptyQuotedTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"one\",\"two\",\"\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseQuoteOnlyQuotedFieldTest()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("\"\"\"\",\"two\",\"three\"");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("\"", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordsWithOnlyOneField()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.WriteLine("row one");
+ streamWriter.WriteLine("row two");
+ streamWriter.WriteLine("row three");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row one", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row two", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Count);
+ Assert.Equal("row three", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordWhereOnlyCarriageReturnLineEndingIsUsed()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two\r");
+ streamWriter.Write("three,four\r");
+ streamWriter.Write("five,six\r");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("three", parser[0]);
+ Assert.Equal("four", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("five", parser[0]);
+ Assert.Equal("six", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void ParseRecordWhereOnlyLineFeedLineEndingIsUsed()
+ {
+ using (var memoryStream = new MemoryStream())
+ using (var streamReader = new StreamReader(memoryStream))
+ using (var streamWriter = new StreamWriter(memoryStream))
+ using (var parser = new CsvParser(streamReader, CultureInfo.InvariantCulture))
+ {
+ streamWriter.Write("one,two\n");
+ streamWriter.Write("three,four\n");
+ streamWriter.Write("five,six\n");
+ streamWriter.Flush();
+ memoryStream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("three", parser[0]);
+ Assert.Equal("four", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("five", parser[0]);
+ Assert.Equal("six", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithCommentsOn()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("#four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("seven", parser[0]);
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithCommentsOff()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = false,
+ };
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("#four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("#four", parser[0]);
+ }
+
+ [Fact]
+ public void ParseCommentedOutLineWithDifferentCommentCommentsOn()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one,two,three");
+ writer.WriteLine("*four,five,six");
+ writer.WriteLine("seven,eight,nine");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ Comment = '*',
+ };
+ var parser = new CsvParser(reader, config);
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("seven", parser[0]);
+ }
+
+ [Fact]
+ public void ParseUsingDifferentDelimiter()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("one\ttwo\tthree");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "\t",
+ WhiteSpaceChars = new[] { ' ' },
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+
+ [Fact]
+ public void ParseUsingDifferentQuote()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("'one','two','three'");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Quote = '\''
+ };
+ var parser = new CsvParser(reader, config);
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+
+ [Fact]
+ public void ParseFinalRecordWithNoEndOfLineTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.WriteLine("1,2,");
+ writer.Write("4,5,");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void ParseLastLineHasNoCrLf()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ writer.Write("a");
+ writer.Flush();
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ Assert.True(parser.Read());
+ Assert.Equal("a", parser[0]);
+
+ Assert.False(parser.Read());
+ }
+
+ [Fact]
+ public void CharReadTotalTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new TestStreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(9, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(16, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(19, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(40, parser.CharCount);
+
+ parser.Read();
+ Assert.Equal(57, parser.CharCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void StreamSeekingUsingCharPositionTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.CharCount, SeekOrigin.Begin);
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("three, four", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void RowTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 0;
+ while (parser.Read())
+ {
+ rowCount++;
+ Assert.Equal(rowCount, parser.Row);
+ }
+ }
+ }
+
+ [Fact]
+ public void RowBlankLinesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("\r\n");
+ writer.Write("3,4\r\n");
+ writer.Write("\r\n");
+ writer.Write("5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 1;
+ while (parser.Read())
+ {
+ Assert.Equal(rowCount, parser.Row);
+ rowCount += 2;
+ }
+ }
+ }
+
+ [Fact]
+ public void IgnoreBlankLinesRowCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,a");
+ writer.WriteLine();
+ writer.WriteLine("3,c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ Assert.Equal("1", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Row);
+ Assert.Equal("3", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void DoNotIgnoreBlankLinesRowCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,a");
+ writer.WriteLine();
+ writer.WriteLine("3,c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ Assert.Equal("1", parser[0]);
+
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Row);
+ Assert.Equal(1, parser.Count);
+
+ Assert.True(parser.Read());
+ Assert.Equal(3, parser.Row);
+ Assert.Equal("3", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void RowCommentLinesTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("# comment 1\r\n");
+ writer.Write("3,4\r\n");
+ writer.Write("# comment 2\r\n");
+ writer.Write("5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ var rowCount = 1;
+ while (parser.Read())
+ {
+ Assert.Equal(rowCount, parser.Row);
+ rowCount += 2;
+ }
+ }
+ }
+
+ [Fact]
+ public void RowRawTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new TestStreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("1,\"2");
+ writer.WriteLine("2 continued");
+ writer.WriteLine("end of 2\",3");
+ writer.WriteLine("4,5,6");
+ writer.WriteLine("7,\"8");
+ writer.WriteLine("8 continued");
+ writer.WriteLine("end of 8\",9");
+ writer.WriteLine("10,11,12");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2\r\n2 continued\r\nend of 2", parser[1]);
+ Assert.Equal("3", parser[2]);
+ Assert.Equal(3, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ Assert.Equal(4, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("7", parser[0]);
+ Assert.Equal("8\r\n8 continued\r\nend of 8", parser[1]);
+ Assert.Equal("9", parser[2]);
+ Assert.Equal(7, parser.RawRow);
+
+ Assert.True(parser.Read());
+ Assert.Equal("10", parser[0]);
+ Assert.Equal("11", parser[1]);
+ Assert.Equal("12", parser[2]);
+ Assert.Equal(8, parser.RawRow);
+ }
+ }
+
+ [Fact]
+ public void ByteCountTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(5, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFields()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2\"\r\n");
+ writer.Write("\"3\",4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(7, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(14, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsEmptyQuotedField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"\",2\r\n");
+ writer.Write("\"3\",4,\"5\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(8, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(19, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsClosingQuoteAtStartOfBuffer()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ BufferSize = 4
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2\",3\r\n");
+ writer.Write("\"4\",5,\"6\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(9, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(20, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountTestWithQuotedFieldsEscapedQuoteAtStartOfBuffer()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ BufferSize = 4
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, config.Encoding))
+ using (var reader = new StreamReader(stream, config.Encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,\"2a\",3\r\n");
+ writer.Write("\"\"\"4\"\"\",5,\"6\"\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(25, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void ByteCountUsingCharWithMoreThanSingleByteTest()
+ {
+ var encoding = Encoding.Unicode;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CountBytes = true,
+ Encoding = encoding,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, encoding))
+ using (var reader = new StreamReader(stream, encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ //崔钟铉
+ writer.Write("1,崔\r\n");
+ writer.Write("3,钟\r\n");
+ writer.Write("5,铉\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal(10, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(20, parser.ByteCount);
+
+ parser.Read();
+ Assert.Equal(30, parser.ByteCount);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void StreamSeekingUsingByteCountTest()
+ {
+ var encoding = Encoding.Unicode;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ CountBytes = true,
+ Encoding = encoding,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream, encoding))
+ using (var reader = new StreamReader(stream, encoding))
+ using (var parser = new CsvParser(reader, config))
+ {
+ // This is a breakdown of the char counts.
+ // Read() will read up to the first line end char
+ // and any more on the line will get read with the next read.
+
+ // [I][d][,][N][a][m][e][\r][\n]
+ // 1 2 3 4 5 6 7 8 9
+ // [1][,][o][n][e][\r][\n]
+ // 10 11 12 13 14 15 16
+ // [,][\r][\n]
+ // 17 18 19
+ // [\r][\n]
+ // 20 21
+ // [#][ ][c][o][m][m][e][n][t][s][\r][\n]
+ // 22 23 24 25 26 27 28 29 30 31 32 33
+ // [2][,][t][w][o][\r][\n]
+ // 34 35 36 37 38 39 40
+ // [3][,]["][t][h][r][e][e][,][ ][f][o][u][r]["][\r][\n]
+ // 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("# comments");
+ writer.WriteLine("2,two");
+ writer.WriteLine("3,\"three, four\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ var record = parser.Read();
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("2", parser[0]);
+ Assert.Equal("two", parser[1]);
+
+ stream.Position = 0;
+ stream.Seek(parser.ByteCount, SeekOrigin.Begin);
+ record = parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("three, four", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void SimulateSeekingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ // Already read:
+ // 1,2,3\r
+ // Seeked to this position.
+ writer.Write("\n4,5,6\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ // Make sure this doesn't throw an exception.
+ Assert.True(parser.Read());
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void NullCharTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("1,\0,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("\0", parser[1]);
+ Assert.Equal("3", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void RawRecordCorruptionTest()
+ {
+ var row1 = new string('a', 2038) + ",b\r\n";
+ var row2 = "test1,test2";
+ var val = row1 + row2;
+
+ using (var reader = new StringReader(val))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal(row1, parser.RawRecord.ToString());
+
+ parser.Read();
+ Assert.Equal(row2, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void ParseNoQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("one,\"two\",three \" four, \"five\" \n"); // `one,"two",three " four, "five" `
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("\"two\"", parser[1]);
+ Assert.Equal("three \" four", parser[2]);
+ Assert.Equal(" \"five\" ", parser[3]);
+ }
+ }
+
+ [Fact]
+ public void LastLineHasCommentTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("#comment");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void LastLineHasCommentNoEolTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("#c");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void DoNotIgnoreBlankLinesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.WriteLine("1,2,3");
+ writer.WriteLine(",,");
+ writer.WriteLine("");
+ writer.WriteLine("4,5,6");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ parser.Read();
+ Assert.Equal("", parser[0]);
+ Assert.Equal("", parser[1]);
+ Assert.Equal("", parser[2]);
+
+ parser.Read();
+ Assert.Equal(1, parser.Count);
+
+ parser.Read();
+ Assert.Equal("4", parser[0]);
+ Assert.Equal("5", parser[1]);
+ Assert.Equal("6", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void QuotedFieldWithCarriageReturnTest()
+ {
+ using (var reader = new StringReader("\"a\r\",b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(new[] { "a\r", "b" }, parser.Record);
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void QuotedFieldWithLineFeedTest()
+ {
+ using (var reader = new StringReader("\"a\n\",b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(new[] { "a\n", "b" }, parser.Record);
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void RowCountWithSingleLineAndNoLineEndingTest()
+ {
+ using (var reader = new StringReader("a,b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.Row);
+ }
+ }
+
+ [Fact]
+ public void RawRowCountWithSingleLineAndNoLineEndingTest()
+ {
+ using (var reader = new StringReader("a,b"))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(1, parser.RawRow);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderConstructorTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderConstructorTests.cs
new file mode 100644
index 0000000..fe24eac
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderConstructorTests.cs
@@ -0,0 +1,52 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderConstructorTests
+ {
+ [Fact]
+ public void EnsureInternalsAreSetupCorrectlyWhenPassingTextReaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.Same(csv.Configuration, csv.Parser.Configuration);
+ }
+ }
+
+ [Fact]
+ public void EnsureInternalsAreSetupCorrectlyWhenPassingTextReaderAndConfigurationTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)))
+ {
+ Assert.Same(csv.Configuration, csv.Parser.Configuration);
+ }
+ }
+
+ [Fact]
+ public void EnsureInternalsAreSetupCorrectlyWhenPassingParserTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ {
+ var parser = new CsvParser(reader, CultureInfo.InvariantCulture);
+
+ using (var csv = new CsvReader(parser))
+ {
+ Assert.Same(csv.Configuration, csv.Parser.Configuration);
+ Assert.Same(parser, csv.Parser);
+ }
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDefaultValueTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDefaultValueTests.cs
new file mode 100644
index 0000000..ba5d832
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDefaultValueTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderDefaultValueTests
+ {
+ [Fact]
+ public void DefaultValueTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name,Order");
+ writer.WriteLine(",,");
+ writer.WriteLine("2,two,2");
+ writer.WriteLine(",three,");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.RegisterClassMap<TestMap>();
+
+ var records = csvReader.GetRecords<Test>().ToList();
+
+ var record = records[0];
+ Assert.Equal(-1, record.Id);
+ Assert.Null(record.Name);
+ Assert.Equal(-2, record.Order);
+
+ record = records[1];
+ Assert.Equal(2, record.Id);
+ Assert.Equal("two", record.Name);
+ }
+ }
+
+ [Fact]
+ public void DefaultStringValueTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name,Order");
+ writer.WriteLine(",,");
+ writer.WriteLine("2,two,2");
+ writer.WriteLine(",three,");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.RegisterClassMap<TestStringMap>();
+
+ var records = csvReader.GetRecords<Test>().ToList();
+
+ var record = records[0];
+ Assert.Equal(-1, record.Id);
+ Assert.Null(record.Name);
+ Assert.Equal(-2, record.Order);
+
+ record = records[1];
+ Assert.Equal(2, record.Id);
+ Assert.Equal("two", record.Name);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public int Order { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Id).Default(-1);
+ Map(m => m.Name).Default((string)null);
+ Map(m => m.Order).Default(-2);
+ }
+ }
+
+ private sealed class TestStringMap : ClassMap<Test>
+ {
+ public TestStringMap()
+ {
+ Map(m => m.Id).Default("-1");
+ Map(m => m.Name).Default(null);
+ Map(m => m.Order).Default("-2");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDynamicMappingsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDynamicMappingsTests.cs
new file mode 100644
index 0000000..e2d9336
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderDynamicMappingsTests.cs
@@ -0,0 +1,63 @@
+// Copyright 2009-2020 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+ public class CsvReaderDynamicMappingsTests
+ {
+ [Fact]
+ public void CanMapDynamics()
+ {
+ var parserMock = new ParserMock
+ {
+ { "IntCol", "StringCol" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<DynamicMappingsTypeClassMap>();
+
+ var records = csvReader.GetRecords<DynamicMappingsType>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].IntCol);
+ Assert.Equal("one", records[0].StringCol);
+ Assert.Equal(2, records[1].IntCol);
+ Assert.Equal("two", records[1].StringCol);
+ }
+
+ private class DynamicMappingsType
+ {
+ public int IntCol { get; set; }
+ public string StringCol { get; set; }
+
+ public static IEnumerable<Expression<Func<DynamicMappingsType, dynamic>>> Mappings =>
+ new List<Expression<Func<DynamicMappingsType, dynamic>>>
+ {
+ i => i.IntCol,
+ i => i.StringCol
+ };
+ }
+
+ private class DynamicMappingsTypeClassMap : ClassMap<DynamicMappingsType>
+ {
+ public DynamicMappingsTypeClassMap()
+ {
+ foreach (var mapping in DynamicMappingsType.Mappings)
+ {
+ Map(mapping);
+ }
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderErrorMessageTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderErrorMessageTests.cs
new file mode 100644
index 0000000..be9db27
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderErrorMessageTests.cs
@@ -0,0 +1,258 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderErrorMessageTests
+ {
+ public CsvReaderErrorMessageTests()
+ {
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+ }
+
+ [Fact]
+ public void FirstColumnEmptyFirstRowErrorWithNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ csvReader.Context.RegisterClassMap<Test1Map>();
+ writer.WriteLine(",one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ var records = csvReader.GetRecords<Test1>().ToList();
+ throw new Exception();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(1, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+ }
+
+ [Fact]
+ public void FirstColumnEmptySecondRowErrorWithHeader()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ csvReader.Context.RegisterClassMap<Test1Map>();
+ writer.WriteLine("IntColumn,StringColumn");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",two");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ var records = csvReader.GetRecords<Test1>().ToList();
+ throw new Exception();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(3, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+ }
+
+ [Fact]
+ public void FirstColumnEmptyErrorWithHeaderAndCommentRowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ csvReader.Context.RegisterClassMap<Test1Map>();
+ writer.WriteLine("IntColumn,StringColumn");
+ writer.WriteLine("# comment");
+ writer.WriteLine();
+ writer.WriteLine(",one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ var records = csvReader.GetRecords<Test1>().ToList();
+ throw new Exception();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(4, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+ }
+
+ [Fact]
+ public void FirstColumnErrorTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csvReader.Context.RegisterClassMap<Test1Map>();
+ writer.WriteLine("IntColumn,StringColumn");
+ writer.WriteLine();
+ writer.WriteLine("one,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ var records = csvReader.GetRecords<Test1>().ToList();
+ throw new Exception();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(3, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+ }
+
+ [Fact]
+ public void SecondColumnEmptyErrorTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csvReader.Context.RegisterClassMap<Test2Map>();
+ writer.WriteLine("StringColumn,IntColumn");
+ writer.WriteLine("one,");
+ writer.WriteLine("two,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ var records = csvReader.GetRecords<Test2>().ToList();
+ throw new Exception();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(1, ex.Context.Reader.CurrentIndex);
+ }
+ }
+ }
+
+ [Fact]
+ public void Test()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,9/24/2012");
+ writer.Flush();
+ stream.Position = 0;
+
+ try
+ {
+ csvReader.Context.RegisterClassMap<Test3Map>();
+ var records = csvReader.GetRecords<Test3>().ToList();
+ }
+ catch (ReaderException)
+ {
+ // Should throw this exception.
+ }
+ }
+ }
+
+ private class Test1
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+ }
+
+ private sealed class Test1Map : ClassMap<Test1>
+ {
+ public Test1Map()
+ {
+ Map(m => m.IntColumn).Index(0);
+ Map(m => m.StringColumn).Index(1);
+ }
+ }
+
+ private class Test2
+ {
+ public string StringColumn { get; set; }
+
+ public int IntColumn { get; set; }
+ }
+
+ private sealed class Test2Map : ClassMap<Test2>
+ {
+ public Test2Map()
+ {
+ Map(m => m.StringColumn);
+ Map(m => m.IntColumn);
+ }
+ }
+
+ private class Test3
+ {
+ public int Id { get; set; }
+
+ public DateTime CreationDate { get; set; }
+
+ public string Description { get; set; }
+ }
+
+ private sealed class Test3Map : ClassMap<Test3>
+ {
+ public Test3Map()
+ {
+ Map(m => m.Id).Index(0);
+ Map(m => m.CreationDate).Index(1);
+ Map(m => m.Description).Index(2);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderMappingTests.cs
new file mode 100644
index 0000000..38255da
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderMappingTests.cs
@@ -0,0 +1,355 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderMappingTests
+ {
+ [Fact]
+ public void ReadWithConvertUsingTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "int2", "string.3" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ // csvReader.Configuration.HeaderValidated = (isValid, headerNames, headerNameIndex, context) => {};
+ csvReader.Context.RegisterClassMap<ConvertUsingClassMap>();
+
+ var records = csvReader.GetRecords<MultipleNamesClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].IntColumn);
+ Assert.Equal("one", records[0].StringColumn);
+ Assert.Equal(2, records[1].IntColumn);
+ Assert.Equal("two", records[1].StringColumn);
+ }
+
+ [Fact]
+ public void ReadMultipleNamesTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "int2", "string3" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<MultipleNamesClassMap>();
+
+ var records = csvReader.GetRecords<MultipleNamesClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].IntColumn);
+ Assert.Equal("one", records[0].StringColumn);
+ Assert.Equal(2, records[1].IntColumn);
+ Assert.Equal("two", records[1].StringColumn);
+ }
+
+ [Fact]
+ public void ConvertUsingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ { "3", "4" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<ConvertUsingMap>();
+
+ var records = csvReader.GetRecords<TestClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(3, records[0].IntColumn);
+ Assert.Equal(7, records[1].IntColumn);
+ }
+
+ [Fact]
+ public void ConvertUsingCovarianceTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<CovarianceClassMap>();
+
+ var records = csvReader.GetRecords<CovarianceClass>().ToList();
+ }
+
+ [Fact]
+ public void ConvertUsingBlockTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ { "3", "4" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<ConvertUsingBlockMap>();
+
+ var records = csvReader.GetRecords<TestClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(3, records[0].IntColumn);
+ Assert.Equal(7, records[1].IntColumn);
+ }
+
+ [Fact]
+ public void ConvertUsingConstantTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ { "3", "4" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<ConvertUsingConstantMap>();
+
+ var records = csvReader.GetRecords<TestClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].IntColumn);
+ Assert.Equal(1, records[1].IntColumn);
+ }
+
+ [Fact]
+ public void ReadSameNameMultipleTimesTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "ColumnName", "ColumnName", "ColumnName" },
+ { "2", "3", "1" },
+ };
+
+ var csv = new CsvReader(parserMock);
+ csv.Context.RegisterClassMap<SameNameMultipleTimesClassMap>();
+
+ var records = csv.GetRecords<SameNameMultipleTimesClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Single(records);
+ }
+
+ [Fact]
+ public void ConvertUsingInstanceMethodTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ { "3", "4" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<ConvertUsingInstanceMethodMap>();
+
+ var records = csvReader.GetRecords<TestClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(3, records[0].IntColumn);
+ Assert.Equal(7, records[1].IntColumn);
+ }
+
+ [Fact]
+ public void ConvertUsingStaticFunctionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ { "3", "4" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<ConvertUsingStaticFunctionMap>();
+
+ var records = csvReader.GetRecords<TestClass>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(3, records[0].IntColumn);
+ Assert.Equal(7, records[1].IntColumn);
+ }
+
+ private class CovarianceClass
+ {
+ public int? Id { get; set; }
+ }
+
+ private sealed class CovarianceClassMap : ClassMap<CovarianceClass>
+ {
+ public CovarianceClassMap()
+ {
+ Map(m => m.Id).Convert(args => args.Row.GetField<int>(0));
+ }
+ }
+
+ private class ContravarianceClass
+ {
+ public int Id { get; set; }
+ }
+
+ private class TestClass
+ {
+ public int IntColumn { get; set; }
+ }
+
+ private class SameNameMultipleTimesClass
+ {
+ public string Name1 { get; set; }
+
+ public string Name2 { get; set; }
+
+ public string Name3 { get; set; }
+ }
+
+ private sealed class SameNameMultipleTimesClassMap : ClassMap<SameNameMultipleTimesClass>
+ {
+ public SameNameMultipleTimesClassMap()
+ {
+ Map(m => m.Name1).Name("ColumnName").NameIndex(1);
+ Map(m => m.Name2).Name("ColumnName").NameIndex(2);
+ Map(m => m.Name3).Name("ColumnName").NameIndex(0);
+ }
+ }
+
+ private class MultipleNamesClass
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+ }
+
+ private sealed class MultipleNamesClassMap : ClassMap<MultipleNamesClass>
+ {
+ public MultipleNamesClassMap()
+ {
+ Map(m => m.IntColumn).Name("int1", "int2", "int3");
+ Map(m => m.StringColumn).Name("string1", "string2", "string3");
+ }
+ }
+
+
+ private class ConstructorMappingClass
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+
+ public ConstructorMappingClass(string stringColumn)
+ {
+ StringColumn = stringColumn;
+ }
+ }
+
+ private sealed class ConvertUsingMap : ClassMap<TestClass>
+ {
+ public ConvertUsingMap()
+ {
+ Map(m => m.IntColumn).Convert(args => args.Row.GetField<int>(0) + args.Row.GetField<int>(1));
+ }
+ }
+
+ private sealed class ConvertUsingBlockMap : ClassMap<TestClass>
+ {
+ public ConvertUsingBlockMap()
+ {
+ Map(m => m.IntColumn).Convert(args =>
+ {
+ var x = args.Row.GetField<int>(0);
+ var y = args.Row.GetField<int>(1);
+ return x + y;
+ });
+ }
+ }
+
+ private sealed class ConvertUsingConstantMap : ClassMap<TestClass>
+ {
+ public ConvertUsingConstantMap()
+ {
+ Map(m => m.IntColumn).Convert(row => 1);
+ }
+ }
+
+ private sealed class ConvertUsingClassMap : ClassMap<MultipleNamesClass>
+ {
+ public ConvertUsingClassMap()
+ {
+ Map(m => m.IntColumn).Name("int2");
+ Map(m => m.StringColumn).Convert(args => args.Row.GetField("string.3"));
+ }
+ }
+
+ private sealed class ConvertUsingInstanceMethodMap : ClassMap<TestClass>
+ {
+ public ConvertUsingInstanceMethodMap()
+ {
+ Map(m => m.IntColumn).Convert(ConvertFromStringFunction);
+ }
+
+ private int ConvertFromStringFunction(ConvertFromStringArgs args)
+ {
+ return args.Row.GetField<int>(0) + args.Row.GetField<int>(1);
+ }
+ }
+
+ private sealed class ConvertUsingStaticFunctionMap : ClassMap<TestClass>
+ {
+ public ConvertUsingStaticFunctionMap()
+ {
+ Map(m => m.IntColumn).Convert(ConvertFromStringFunction);
+ }
+
+ private static int ConvertFromStringFunction(ConvertFromStringArgs args)
+ {
+ return args.Row.GetField<int>(0) + args.Row.GetField<int>(1);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingPrefixTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingPrefixTests.cs
new file mode 100644
index 0000000..4116ada
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingPrefixTests.cs
@@ -0,0 +1,92 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.IO;
+using System.Linq;
+using Xunit;
+using CsvHelper.Configuration;
+using System.Globalization;
+using CsvHelper.Tests.Mocks;
+
+namespace CsvHelper.Tests
+{
+ public class CsvReaderReferenceMappingPrefixTests
+ {
+ [Fact]
+ public void ReferencesWithPrefixTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "BPrefix_Id", "C.CId" },
+ { "a1", "b1", "c1" },
+ { "a2", "b2", "c2" },
+ { "a3", "b3", "c3" },
+ { "a4", "b4", "c4" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<AMap>();
+
+ var list = csv.GetRecords<A>().ToList();
+
+ Assert.NotNull(list);
+ Assert.Equal(4, list.Count);
+
+ for (var i = 0; i < 4; i++)
+ {
+ var rowId = i + 1;
+ var row = list[i];
+ Assert.Equal("a" + rowId, row.Id);
+ Assert.Equal("b" + rowId, row.B.Id);
+ Assert.Equal("c" + rowId, row.B.C.Id);
+ }
+ }
+ }
+
+ private class A
+ {
+ public string Id { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string Id { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string Id { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id);
+ References<BMap>(m => m.B).Prefix("BPrefix_", false);
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.Id);
+ References<CMap>(m => m.C).Prefix();
+ }
+ }
+
+ private sealed class CMap : ClassMap<C>
+ {
+ public CMap()
+ {
+ Map(m => m.Id).Name("CId");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingTests.cs
new file mode 100644
index 0000000..32907ef
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderReferenceMappingTests.cs
@@ -0,0 +1,113 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.IO;
+using System.Linq;
+using Xunit;
+using CsvHelper.Configuration;
+using System.Globalization;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderReferenceMappingTests
+ {
+ [Fact]
+ public void NestedReferencesClassMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<AMap>();
+
+ writer.WriteLine("AId,BId,CId,DId");
+ writer.WriteLine("a1,b1,c1,d1");
+ writer.WriteLine("a2,b2,c2,d2");
+ writer.WriteLine("a3,b3,c3,d3");
+ writer.WriteLine("a4,b4,c4,d4");
+ writer.Flush();
+ stream.Position = 0;
+
+ var list = csv.GetRecords<A>().ToList();
+
+ Assert.NotNull(list);
+ Assert.Equal(4, list.Count);
+
+ for (var i = 0; i < 4; i++)
+ {
+ var rowId = i + 1;
+ var row = list[i];
+ Assert.Equal("a" + rowId, row.Id);
+ Assert.Equal("b" + rowId, row.B.Id);
+ Assert.Equal("c" + rowId, row.B.C.Id);
+ Assert.Equal("d" + rowId, row.B.C.D.Id);
+ }
+ }
+ }
+
+ private class A
+ {
+ public string Id { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string Id { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string Id { get; set; }
+
+ public D D { get; set; }
+ }
+
+ private class D
+ {
+ public string Id { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id).Name("AId");
+ References<BMap>(m => m.B);
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.Id).Name("BId");
+ References<CMap>(m => m.C);
+ }
+ }
+
+ private sealed class CMap : ClassMap<C>
+ {
+ public CMap()
+ {
+ Map(m => m.Id).Name("CId");
+ References<DMap>(m => m.D);
+ }
+ }
+
+ private sealed class DMap : ClassMap<D>
+ {
+ public DMap()
+ {
+ Map(m => m.Id).Name("DId");
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderSubClassingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderSubClassingTests.cs
new file mode 100644
index 0000000..2a530d7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderSubClassingTests.cs
@@ -0,0 +1,40 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Linq;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderSubClassingTests
+ {
+ [Fact]
+ public void GetRecordTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csvReader = new MyCsvReader(parserMock);
+ csvReader.GetRecords<Test>().ToList();
+ }
+
+ private class MyCsvReader : CsvReader
+ {
+ public MyCsvReader(IParser parser) : base(parser) { }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderTests.cs
new file mode 100644
index 0000000..09df221
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvReaderTests.cs
@@ -0,0 +1,1166 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+#pragma warning disable 649
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvReaderTests
+ {
+ [Fact]
+ public void HasHeaderRecordNotReadExceptionTest()
+ {
+ var parserMock = new ParserMock();
+ var reader = new CsvReader(parserMock);
+
+ Assert.Throws<ReaderException>(() => reader.GetField<int>(0));
+ }
+
+ [Fact]
+ public void HasHeaderRecordTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ // Check to see if the header record and first record are set properly.
+ Assert.Equal(Convert.ToInt32("1"), reader.GetField<int>("One"));
+ Assert.Equal(Convert.ToInt32("2"), reader.GetField<int>("Two"));
+ Assert.Equal(Convert.ToInt32("1"), reader.GetField<int>(0));
+ Assert.Equal(Convert.ToInt32("2"), reader.GetField<int>(1));
+ }
+
+ [Fact]
+ public void GetTypeTest()
+ {
+ var data = new[]
+ {
+ "1",
+ "blah",
+ DateTime.Now.ToString("O"),
+ "true",
+ "c",
+ "",
+ Guid.NewGuid().ToString(),
+ };
+
+ var parserMock = new ParserMock();
+ parserMock.Add(data);
+ parserMock.Add(data);
+ parserMock.Add(null);
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Equal(Convert.ToInt16(data[0]), reader.GetField<short>(0));
+ Assert.Equal(Convert.ToInt16(data[0]), reader.GetField<short?>(0));
+ Assert.Null(reader.GetField<short?>(5));
+ Assert.Equal(Convert.ToInt32(data[0]), reader.GetField<int>(0));
+ Assert.Equal(Convert.ToInt32(data[0]), reader.GetField<int?>(0));
+ Assert.Null(reader.GetField<int?>(5));
+ Assert.Equal(Convert.ToInt64(data[0]), reader.GetField<long>(0));
+ Assert.Equal(Convert.ToInt64(data[0]), reader.GetField<long?>(0));
+ Assert.Null(reader.GetField<long?>(5));
+ Assert.Equal(Convert.ToDecimal(data[0]), reader.GetField<decimal>(0));
+ Assert.Equal(Convert.ToDecimal(data[0]), reader.GetField<decimal?>(0));
+ Assert.Null(reader.GetField<decimal?>(5));
+ Assert.Equal(Convert.ToSingle(data[0]), reader.GetField<float>(0));
+ Assert.Equal(Convert.ToSingle(data[0]), reader.GetField<float?>(0));
+ Assert.Null(reader.GetField<float?>(5));
+ Assert.Equal(Convert.ToDouble(data[0]), reader.GetField<double>(0));
+ Assert.Equal(Convert.ToDouble(data[0]), reader.GetField<double?>(0));
+ Assert.Null(reader.GetField<double?>(5));
+ Assert.Equal(data[1], reader.GetField<string>(1));
+ Assert.Equal(string.Empty, reader.GetField<string>(5));
+ Assert.Equal(Convert.ToDateTime(data[2]), reader.GetField<DateTime>(2));
+ Assert.Equal(Convert.ToDateTime(data[2]), reader.GetField<DateTime?>(2));
+ Assert.Null(reader.GetField<DateTime?>(5));
+ Assert.Equal(Convert.ToBoolean(data[3]), reader.GetField<bool>(3));
+ Assert.Equal(Convert.ToBoolean(data[3]), reader.GetField<bool?>(3));
+ Assert.Null(reader.GetField<bool?>(5));
+ Assert.Equal(Convert.ToChar(data[4]), reader.GetField<char>(4));
+ Assert.Equal(Convert.ToChar(data[4]), reader.GetField<char?>(4));
+ Assert.Null(reader.GetField<char?>(5));
+ Assert.Equal(new Guid(data[6]), reader.GetField<Guid>(6));
+ Assert.Null(reader.GetField<Guid?>(5));
+ }
+
+ [Fact]
+ public void GetFieldByIndexTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" },
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Equal(1, reader.GetField<int>(0));
+ Assert.Equal(2, reader.GetField<int>(1));
+ }
+
+ [Fact]
+ public void GetFieldByNameTest()
+ {
+ var data1 = new[] { "One", "Two" };
+ var data2 = new[] { "1", "2" };
+ var parserMock = new ParserMock();
+ parserMock.Add(data1);
+ parserMock.Add(data2);
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ Assert.Equal(Convert.ToInt32(data2[0]), reader.GetField<int>("One"));
+ Assert.Equal(Convert.ToInt32(data2[1]), reader.GetField<int>("Two"));
+ }
+
+ [Fact]
+ public void GetFieldByNameAndIndexTest()
+ {
+ var data1 = new[] { "One", "One" };
+ var data2 = new[] { "1", "2" };
+ var parserMock = new ParserMock();
+ parserMock.Add(data1);
+ parserMock.Add(data2);
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ Assert.Equal(Convert.ToInt32(data2[0]), reader.GetField<int>("One", 0));
+ Assert.Equal(Convert.ToInt32(data2[1]), reader.GetField<int>("One", 1));
+ }
+
+ [Fact]
+ public void GetMissingFieldByNameTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ var data1 = new[] { "One", "Two" };
+ var data2 = new[] { "1", "2" };
+ var parserMock = new ParserMock(config);
+ parserMock.Add(data1);
+ parserMock.Add(data2);
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+
+ Assert.Null(reader.GetField<string>("blah"));
+ }
+
+ [Fact]
+ public void GetMissingFieldByNameStrictTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+
+ Assert.Throws<MissingFieldException>(() => reader.GetField<string>("blah"));
+ }
+
+ [Fact]
+ public void GetMissingFieldByIndexStrictTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ null,
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Throws<MissingFieldException>(() => reader.GetField(2));
+ }
+
+ [Fact]
+ public void GetMissingFieldGenericByIndexStrictTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ null,
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Throws<MissingFieldException>(() => reader.GetField<string>(2));
+ }
+
+ [Fact]
+ public void GetMissingFieldByIndexStrictOffTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ null,
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Null(reader.GetField(2));
+ }
+
+ [Fact]
+ public void GetMissingFieldGenericByIndexStrictOffTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "One", "Two" },
+ { "1", "2" },
+ null,
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Null(reader.GetField<string>(2));
+ }
+
+ [Fact]
+ public void GetFieldByNameNoHeaderExceptionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2" }
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ Assert.Throws<ReaderException>(() => reader.GetField<int>("One"));
+ }
+
+ [Fact]
+ public void GetRecordWithDuplicateHeaderFields()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "Field1", "Field1" },
+ { "Field1", "Field1" },
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ }
+
+ [Fact]
+ public void GetRecordGenericTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ HeaderValidated = null,
+ };
+ var headerData = new[]
+ {
+ "IntColumn",
+ "String Column",
+ "GuidColumn",
+ };
+ var recordData = new[]
+ {
+ "1",
+ "string column",
+ Guid.NewGuid().ToString(),
+ };
+ var csvParserMock = new ParserMock(config)
+ {
+ headerData,
+ recordData,
+ null,
+ };
+
+ var csv = new CsvReader(csvParserMock);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+ csv.Read();
+ var record = csv.GetRecord<TestRecord>();
+
+ Assert.Equal(Convert.ToInt32(recordData[0]), record.IntColumn);
+ Assert.Equal(recordData[1], record.StringColumn);
+ Assert.Equal("test", record.TypeConvertedColumn);
+ Assert.Equal(Convert.ToInt32(recordData[0]), record.FirstColumn);
+ Assert.Equal(new Guid(recordData[2]), record.GuidColumn);
+ }
+
+ [Fact]
+ public void GetRecordTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ HeaderValidated = null,
+ };
+ var headerData = new[]
+ {
+ "IntColumn",
+ "String Column",
+ "GuidColumn",
+ };
+ var recordData = new[]
+ {
+ "1",
+ "string column",
+ Guid.NewGuid().ToString(),
+ };
+ var csvParserMock = new ParserMock(config)
+ {
+ headerData,
+ recordData,
+ null,
+ };
+
+ var csv = new CsvReader(csvParserMock);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+ csv.Read();
+ var record = (TestRecord)csv.GetRecord(typeof(TestRecord));
+
+ Assert.Equal(Convert.ToInt32(recordData[0]), record.IntColumn);
+ Assert.Equal(recordData[1], record.StringColumn);
+ Assert.Equal("test", record.TypeConvertedColumn);
+ Assert.Equal(Convert.ToInt32(recordData[0]), record.FirstColumn);
+ Assert.Equal(new Guid(recordData[2]), record.GuidColumn);
+ }
+
+ [Fact]
+ public void GetRecordsGenericTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ HeaderValidated = null,
+ };
+ var headerData = new[]
+ {
+ "IntColumn",
+ "String Column",
+ "GuidColumn",
+ };
+ var guid = Guid.NewGuid();
+ var csvParserMock = new ParserMock(config)
+ {
+ headerData,
+ { "1", "string column 1", guid.ToString() },
+ { "2", "string column 2", guid.ToString() },
+ };
+
+ var csv = new CsvReader(csvParserMock);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+ var records = csv.GetRecords<TestRecord>().ToList();
+
+ Assert.Equal(2, records.Count);
+
+ for (var i = 1; i <= records.Count; i++)
+ {
+ var record = records[i - 1];
+ Assert.Equal(i, record.IntColumn);
+ Assert.Equal("string column " + i, record.StringColumn);
+ Assert.Equal("test", record.TypeConvertedColumn);
+ Assert.Equal(i, record.FirstColumn);
+ Assert.Equal(guid, record.GuidColumn);
+ }
+ }
+
+ [Fact]
+ public void GetRecordsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ HeaderValidated = null,
+ };
+ var headerData = new[]
+ {
+ "IntColumn",
+ "String Column",
+ "GuidColumn",
+ };
+ var guid = Guid.NewGuid();
+ var csvParserMock = new ParserMock(config)
+ {
+ headerData,
+ { "1", "string column 1", guid.ToString() },
+ { "2", "string column 2", guid.ToString() },
+ };
+
+ var csv = new CsvReader(csvParserMock);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+ var records = csv.GetRecords(typeof(TestRecord)).ToList();
+
+ Assert.Equal(2, records.Count);
+
+ for (var i = 1; i <= records.Count; i++)
+ {
+ var record = (TestRecord)records[i - 1];
+ Assert.Equal(i, record.IntColumn);
+ Assert.Equal("string column " + i, record.StringColumn);
+ Assert.Equal("test", record.TypeConvertedColumn);
+ Assert.Equal(i, record.FirstColumn);
+ Assert.Equal(guid, record.GuidColumn);
+ }
+ }
+
+ [Fact]
+ public void GetRecordsWithDuplicateHeaderNames()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ var headerData = new[]
+ {
+ "Column",
+ "Column",
+ "Column"
+ };
+
+ var csvParserMock = new ParserMock(config)
+ {
+ headerData,
+ { "one", "two", "three" },
+ { "one", "two", "three" },
+ };
+
+ var csv = new CsvReader(csvParserMock);
+ csv.Context.RegisterClassMap<TestRecordDuplicateHeaderNamesMap>();
+ var records = csv.GetRecords<TestRecordDuplicateHeaderNames>().ToList();
+
+ Assert.Equal(2, records.Count);
+
+ for (var i = 1; i <= records.Count; i++)
+ {
+ var record = records[i - 1];
+ Assert.Equal("one", record.Column1);
+ Assert.Equal("two", record.Column2);
+ Assert.Equal("three", record.Column3);
+ }
+ }
+
+ [Fact]
+ public void GetRecordEmptyFileWithHeaderOnTest()
+ {
+ var parserMock = new ParserMock
+ {
+ null,
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ try
+ {
+ csvReader.Read();
+ csvReader.ReadHeader();
+ csvReader.Read();
+ throw new XUnitException();
+ }
+ catch (ReaderException) { }
+ }
+
+ [Fact]
+ public void GetRecordEmptyValuesNullableTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+
+ writer.WriteLine("StringColumn,IntColumn,GuidColumn");
+ writer.WriteLine("one,1,11111111-1111-1111-1111-111111111111");
+ writer.WriteLine(",,");
+ writer.WriteLine("three,3,33333333-3333-3333-3333-333333333333");
+ writer.Flush();
+ stream.Position = 0;
+
+ var reader = new StreamReader(stream);
+ var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
+
+ csvReader.Read();
+ var record = csvReader.GetRecord<TestNullable>();
+ Assert.NotNull(record);
+ Assert.Equal("one", record.StringColumn);
+ Assert.Equal(1, record.IntColumn);
+ Assert.Equal(new Guid("11111111-1111-1111-1111-111111111111"), record.GuidColumn);
+
+ csvReader.Read();
+ record = csvReader.GetRecord<TestNullable>();
+ Assert.NotNull(record);
+ Assert.Equal(string.Empty, record.StringColumn);
+ Assert.Null(record.IntColumn);
+ Assert.Null(record.GuidColumn);
+
+ csvReader.Read();
+ record = csvReader.GetRecord<TestNullable>();
+ Assert.NotNull(record);
+ Assert.Equal("three", record.StringColumn);
+ Assert.Equal(3, record.IntColumn);
+ Assert.Equal(new Guid("33333333-3333-3333-3333-333333333333"), record.GuidColumn);
+ }
+
+ [Fact]
+ public void CaseInsensitiveHeaderMatchingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => args.Header.ToLower(),
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("One,Two,Three");
+ writer.WriteLine("1,2,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.Equal("1", csv.GetField("one"));
+ Assert.Equal("2", csv.GetField("TWO"));
+ Assert.Equal("3", csv.GetField("ThreE"));
+ }
+ }
+
+ [Fact]
+ public void SpacesInHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => Regex.Replace(args.Header, @"\s", string.Empty),
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { " Int Column ", " String Column " },
+ { "1", "one" },
+ };
+ var reader = new CsvReader(parserMock);
+ var data = reader.GetRecords<TestDefaultValues>().ToList();
+ Assert.NotNull(data);
+ Assert.Single(data);
+ Assert.Equal(1, data[0].IntColumn);
+ Assert.Equal("one", data[0].StringColumn);
+ }
+
+ [Fact]
+ public void BooleanTypeConverterTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+
+ writer.WriteLine("BoolColumn,BoolNullableColumn,StringColumn");
+ writer.WriteLine("true,true,1");
+ writer.WriteLine("True,True,2");
+ writer.WriteLine("1,1,3");
+ writer.WriteLine("false,false,4");
+ writer.WriteLine("False,False,5");
+ writer.WriteLine("0,0,6");
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var reader = new StreamReader(stream);
+ var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture);
+
+ var records = csvReader.GetRecords<TestBoolean>().ToList();
+
+ Assert.True(records[0].BoolColumn);
+ Assert.True(records[0].BoolNullableColumn);
+ Assert.True(records[1].BoolColumn);
+ Assert.True(records[1].BoolNullableColumn);
+ Assert.True(records[2].BoolColumn);
+ Assert.True(records[2].BoolNullableColumn);
+ Assert.False(records[3].BoolColumn);
+ Assert.False(records[3].BoolNullableColumn);
+ Assert.False(records[4].BoolColumn);
+ Assert.False(records[4].BoolNullableColumn);
+ Assert.False(records[5].BoolColumn);
+ Assert.False(records[5].BoolNullableColumn);
+ }
+
+ [Fact]
+ public void SkipEmptyRecordsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ ShouldSkipRecord = args => args.Row.Parser.Record.All(string.IsNullOrWhiteSpace),
+ };
+
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2", "3" },
+ { "", "", "" },
+ { "4", "5", "6" },
+ };
+
+ var reader = new CsvReader(parserMock);
+
+ reader.Read();
+ Assert.Equal("1", reader.Parser.Record[0]);
+ Assert.Equal("2", reader.Parser.Record[1]);
+ Assert.Equal("3", reader.Parser.Record[2]);
+
+ reader.Read();
+ Assert.Equal("4", reader.Parser.Record[0]);
+ Assert.Equal("5", reader.Parser.Record[1]);
+ Assert.Equal("6", reader.Parser.Record[2]);
+
+ Assert.False(reader.Read());
+ }
+
+ [Fact]
+ public void SkipRecordCallbackTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ ShouldSkipRecord = args => args.Row[1] == "2",
+ };
+
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "2", "3" },
+ { " ", "", "" },
+ { "4", "5", "6" },
+ };
+
+ var reader = new CsvReader(parserMock);
+
+ reader.Read();
+ Assert.Equal(" ", reader.Parser.Record[0]);
+ Assert.Equal("", reader.Parser.Record[1]);
+ Assert.Equal("", reader.Parser.Record[2]);
+
+ reader.Read();
+ Assert.Equal("4", reader.Parser.Record[0]);
+ Assert.Equal("5", reader.Parser.Record[1]);
+ Assert.Equal("6", reader.Parser.Record[2]);
+
+ Assert.False(reader.Read());
+ }
+
+ [Fact]
+ public void MultipleGetRecordsCalls()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("IntColumn,String Column");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.RegisterClassMap<TestRecordMap>();
+ var records = csvReader.GetRecords<TestRecord>();
+ Assert.Equal(2, records.Count());
+ Assert.Empty(records);
+ }
+ }
+
+ [Fact]
+ public void IgnoreExceptionsTest()
+ {
+ var callbackCount = 0;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReadingExceptionOccurred = (ex) =>
+ {
+ callbackCount++;
+ return false;
+ },
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "BoolColumn", "BoolNullableColumn", "StringColumn" },
+ { "1", "1", "one" },
+ { "two", "1", "two" },
+ { "1", "1", "three" },
+ { "four", "1", "four" },
+ { "1", "1", "five" },
+ };
+ var csv = new CsvReader(parserMock);
+
+ var records = csv.GetRecords<TestBoolean>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(3, records.Count);
+ Assert.Equal(2, callbackCount);
+ Assert.Equal("one", records[0].StringColumn);
+ Assert.Equal("three", records[1].StringColumn);
+ Assert.Equal("five", records[2].StringColumn);
+ }
+
+ [Fact]
+ public void ReadStructRecordsTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+ var csv = new CsvReader(parserMock);
+ var records = csv.GetRecords<TestStruct>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ Assert.Equal(2, records[1].Id);
+ Assert.Equal("two", records[1].Name);
+ }
+
+ [Fact]
+ public void WriteStructReferenceRecordsTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ var csv = new CsvReader(parserMock);
+ csv.Context.RegisterClassMap<TestStructParentMap>();
+ var records = csv.GetRecords<TestStructParent>().ToList();
+ Assert.NotNull(records);
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Test.Id);
+ Assert.Equal("one", records[0].Test.Name);
+ }
+
+ [Fact]
+ public void ReadPrimitiveRecordsHasHeaderTrueTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ { "2" },
+ };
+ var csv = new CsvReader(parserMock);
+ var records = csv.GetRecords<int>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0]);
+ Assert.Equal(2, records[1]);
+ }
+
+ [Fact]
+ public void ReadPrimitiveRecordsHasHeaderFalseTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1" },
+ { "2" },
+ };
+ var csv = new CsvReader(parserMock);
+ var records = csv.GetRecords<int>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0]);
+ Assert.Equal(2, records[1]);
+ }
+
+ [Fact]
+ public void TrimHeadersTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ PrepareHeaderForMatch = args => args.Header.Trim(),
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { " one ", " two three " },
+ { "1", "2" },
+ };
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+ Assert.Equal("1", reader.GetField("one"));
+ Assert.Equal("2", reader.GetField("two three"));
+ Assert.Null(reader.GetField("twothree"));
+ }
+
+ [Fact]
+ public void RowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csv = new CsvReader(parserMock);
+
+ csv.Read();
+ Assert.Equal(1, csv.Parser.Row);
+
+ csv.Read();
+ Assert.Equal(2, csv.Parser.Row);
+ }
+
+ [Fact]
+ public void DoNotIgnoreBlankLinesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ IgnoreBlankLines = false,
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.RegisterClassMap<SimpleMap>();
+
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine(",");
+ writer.WriteLine("");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<Simple>().ToList();
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ Assert.Null(records[1].Id);
+ Assert.Equal("", records[1].Name);
+ Assert.Null(records[2].Id);
+ Assert.Equal("", records[2].Name);
+ Assert.Equal(2, records[3].Id);
+ Assert.Equal("two", records[3].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteNestedHeadersTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReferenceHeaderPrefix = args => $"{args.MemberName}.",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Simple1.Id,Simple1.Name,Simple2.Id,Simple2.Name");
+ writer.WriteLine("1,one,2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<Nested>().ToList();
+ Assert.NotNull(records);
+ Assert.Equal(1, records[0].Simple1.Id);
+ Assert.Equal("one", records[0].Simple1.Name);
+ Assert.Equal(2, records[0].Simple2.Id);
+ Assert.Equal("two", records[0].Simple2.Name);
+ }
+ }
+
+ [Fact]
+ public void ReaderDynamicHasHeaderTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ null
+ };
+
+ var csv = new CsvReader(parserMock);
+ csv.Read();
+ var row = csv.GetRecord<dynamic>();
+
+ Assert.Equal("1", row.Id);
+ Assert.Equal("one", row.Name);
+ }
+
+ [Fact]
+ public void ReaderDynamicNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+
+ var parserMock = new ParserMock(config)
+ {
+ { "1", "one" },
+ { "2", "two" },
+ null,
+ };
+
+ var csv = new CsvReader(parserMock);
+ csv.Read();
+ var row = csv.GetRecord<dynamic>();
+
+ Assert.Equal("1", row.Field1);
+ Assert.Equal("one", row.Field2);
+ }
+
+ [Fact]
+ public void TryGetFieldNotInHeaderTest() // https://github.com/JoshClose/CsvHelper/issues/1981
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "piz z/a"},
+ { "1", "one" },
+ { "Id" },
+ { "2" }
+ };
+ var csv = new CsvReader(parserMock);
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ csv.GetField<string>("piz z/a");
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.False(csv.TryGetField<string>("piz z/a", out var tmp));
+ }
+ private class Nested
+ {
+ public Simple Simple1 { get; set; }
+
+ public Simple Simple2 { get; set; }
+ }
+
+ private class Simple
+ {
+ public int? Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class SimpleMap : ClassMap<Simple>
+ {
+ public SimpleMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+
+ private class TestStructParent
+ {
+ public TestStruct Test { get; set; }
+ }
+
+ private sealed class TestStructParentMap : ClassMap<TestStructParent>
+ {
+ public TestStructParentMap()
+ {
+ References<TestStructMap>(m => m.Test);
+ }
+ }
+
+ private struct TestStruct
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class TestStructMap : ClassMap<TestStruct>
+ {
+ public TestStructMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+
+ private class OnlyFields
+ {
+ public string Name;
+ }
+
+ private sealed class OnlyFieldsMap : ClassMap<OnlyFields>
+ {
+ public OnlyFieldsMap()
+ {
+ Map(m => m.Name);
+ }
+ }
+
+ private class TestBoolean
+ {
+ public bool BoolColumn { get; set; }
+
+ public bool BoolNullableColumn { get; set; }
+
+ public string StringColumn { get; set; }
+ }
+
+ private class TestDefaultValues
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+ }
+
+ private sealed class TestDefaultValuesMap : ClassMap<TestDefaultValues>
+ {
+ public TestDefaultValuesMap()
+ {
+ Map(m => m.IntColumn).Default(-1);
+ Map(m => m.StringColumn).Default((string)null);
+ }
+ }
+
+ private class TestNullable
+ {
+ public int? IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+
+ public Guid? GuidColumn { get; set; }
+ }
+
+ [DebuggerDisplay("IntColumn = {IntColumn}, StringColumn = {StringColumn}, IgnoredColumn = {IgnoredColumn}, TypeConvertedColumn = {TypeConvertedColumn}, FirstColumn = {FirstColumn}")]
+ private class TestRecord
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+
+ public string IgnoredColumn { get; set; }
+
+ public string TypeConvertedColumn { get; set; }
+
+ public int FirstColumn { get; set; }
+
+ public Guid GuidColumn { get; set; }
+
+ public int NoMatchingFields { get; set; }
+ }
+
+ private sealed class TestRecordMap : ClassMap<TestRecord>
+ {
+ public TestRecordMap()
+ {
+ Map(m => m.IntColumn).TypeConverter<Int32Converter>();
+ Map(m => m.StringColumn).Name("String Column");
+ Map(m => m.TypeConvertedColumn).Index(1).TypeConverter<TestTypeConverter>();
+ Map(m => m.FirstColumn).Index(0);
+ Map(m => m.GuidColumn);
+ Map(m => m.NoMatchingFields);
+ }
+ }
+
+ private class TestRecordDuplicateHeaderNames
+ {
+ public string Column1 { get; set; }
+
+ public string Column2 { get; set; }
+
+ public string Column3 { get; set; }
+ }
+
+ private sealed class TestRecordDuplicateHeaderNamesMap : ClassMap<TestRecordDuplicateHeaderNames>
+ {
+ public TestRecordDuplicateHeaderNamesMap()
+ {
+ Map(m => m.Column1).Name("Column").NameIndex(0);
+ Map(m => m.Column2).Name("Column").NameIndex(1);
+ Map(m => m.Column3).Name("Column").NameIndex(2);
+ }
+ }
+
+ private class TestTypeConverter : DefaultTypeConverter
+ {
+ public override object ConvertFromString(string text, IReaderRow row, MemberMapData propertyMapData)
+ {
+ return "test";
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterBoxedTypesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterBoxedTypesTests.cs
new file mode 100644
index 0000000..2064889
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterBoxedTypesTests.cs
@@ -0,0 +1,65 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterBoxedTypesTests
+ {
+ [Fact]
+ public void TypeMixedWithBoxedTypeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var recordsTyped = new List<A>
+ {
+ new A { Id = 1, Name = "one" },
+ };
+ var recordsBoxed = new List<object>
+ {
+ new A { Id = 2, Name = "two" },
+ };
+
+ csv.Context.RegisterClassMap<AMap>();
+ csv.WriteRecords(recordsTyped);
+ csv.WriteRecords(recordsBoxed);
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("1,one");
+ expected.AppendLine("2,two");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+ }
+
+ public class A
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ public sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id).Index(0);
+ Map(m => m.Name).Index(1);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterConstructorTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterConstructorTests.cs
new file mode 100644
index 0000000..47a887b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterConstructorTests.cs
@@ -0,0 +1,28 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterConstructorTests
+ {
+ [Fact]
+ public void EnsureInternalsAreSetupWhenPassingWriterAndConfigTest()
+ {
+ using( var stream = new MemoryStream() )
+ using( var writer = new StreamWriter( stream ) )
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ using( var csv = new CsvWriter( writer, config ) )
+ {
+ Assert.Same( config, csv.Configuration );
+ }
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterFormatTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterFormatTests.cs
new file mode 100644
index 0000000..08a2c43
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterFormatTests.cs
@@ -0,0 +1,201 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterFormatTests
+ {
+ [Fact]
+ public void WriteFieldTest()
+ {
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ DateColumn = new DateTime(2012, 10, 1, 12, 12, 12),
+ DecimalColumn = 150.99m,
+ FirstColumn = "first column",
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, new CultureInfo("en-US"));
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "first column,0001,10/1/2012,$150.99\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteFieldShouldQuoteNoTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+
+ csv.WriteField("a \"b\" c", false);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "a \"b\" c\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteFieldShouldQuoteYesTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+
+ csv.WriteField("a \"b\" c", true);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "\"a \"\"b\"\" c\"\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordWithReferencesTest()
+ {
+ var record = new Person
+ {
+ FirstName = "First Name",
+ LastName = "Last Name",
+ Updated = new DateTime(2012, 10, 1, 12, 12, 12, 123),
+ HomeAddress = new Address
+ {
+ Street = "Home Street",
+ City = "Home City",
+ State = "Home State",
+ Zip = 02201,
+ },
+ WorkAddress = new Address
+ {
+ Street = "Work Street",
+ City = "Work City",
+ State = "Work State",
+ Zip = 04100,
+ }
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<PersonMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+
+ var expected = "First Name,Last Name,2012-10-01 12:12:12.123,Home Street,Home City,Home State,02201,Work Street,Work City,Work State,04100\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ private class TestRecord
+ {
+ public int IntColumn { get; set; }
+
+ public DateTime DateColumn { get; set; }
+
+ public decimal DecimalColumn { get; set; }
+
+ public string FirstColumn { get; set; }
+ }
+
+ private sealed class TestRecordMap : ClassMap<TestRecord>
+ {
+ public TestRecordMap()
+ {
+ Map(m => m.IntColumn).Name("Int Column").Index(1).TypeConverterOption.Format("0000");
+ Map(m => m.DateColumn).Index(2).TypeConverterOption.Format("d");
+ Map(m => m.DecimalColumn).Index(3).TypeConverterOption.Format("c");
+ Map(m => m.FirstColumn).Index(0);
+ }
+ }
+
+ private class Person
+ {
+ public string FirstName { get; set; }
+
+ public string LastName { get; set; }
+
+ public DateTime Updated { get; set; }
+
+ public Address HomeAddress { get; set; }
+
+ public Address WorkAddress { get; set; }
+ }
+
+ private class Address
+ {
+ public string Street { get; set; }
+
+ public string City { get; set; }
+
+ public string State { get; set; }
+
+ public int Zip { get; set; }
+ }
+
+ private sealed class PersonMap : ClassMap<Person>
+ {
+ public PersonMap()
+ {
+ Map(m => m.FirstName);
+ Map(m => m.LastName);
+ Map(m => m.Updated).TypeConverterOption.Format("yyyy-MM-dd HH:mm:ss.fff");
+ References<HomeAddressMap>(m => m.HomeAddress);
+ References<WorkAddressMap>(m => m.WorkAddress);
+ }
+ }
+
+ private sealed class HomeAddressMap : ClassMap<Address>
+ {
+ public HomeAddressMap()
+ {
+ Map(m => m.Street).Name("HomeStreet");
+ Map(m => m.City).Name("HomeCity");
+ Map(m => m.State).Name("HomeState");
+ Map(m => m.Zip).Name("HomeZip").TypeConverterOption.Format("00000");
+ }
+ }
+
+ private sealed class WorkAddressMap : ClassMap<Address>
+ {
+ public WorkAddressMap()
+ {
+ Map(m => m.Street).Name("WorkStreet");
+ Map(m => m.City).Name("WorkCity");
+ Map(m => m.State).Name("WorkState");
+ Map(m => m.Zip).Name("WorkZip").TypeConverterOption.Format("00000");
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterMappingTests.cs
new file mode 100644
index 0000000..82ddc1f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterMappingTests.cs
@@ -0,0 +1,350 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterMappingTests
+ {
+ [Fact]
+ public void WriteMultipleNamesTest()
+ {
+ var records = new List<MultipleNamesClass>
+ {
+ new MultipleNamesClass { IntColumn = 1, StringColumn = "one" },
+ new MultipleNamesClass { IntColumn = 2, StringColumn = "two" }
+ };
+
+ string csv;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csvWriter.Context.RegisterClassMap<MultipleNamesClassMap>();
+ csvWriter.WriteRecords(records);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ csv = reader.ReadToEnd();
+ }
+
+ var expected = string.Empty;
+ expected += "int1,string1\r\n";
+ expected += "1,one\r\n";
+ expected += "2,two\r\n";
+
+ Assert.NotNull(csv);
+ Assert.Equal(expected, csv);
+ }
+
+ [Fact]
+ public void SameNameMultipleTimesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<SameNameMultipleTimesClass>
+ {
+ new SameNameMultipleTimesClass
+ {
+ Name1 = "1",
+ Name2 = "2",
+ Name3 = "3"
+ }
+ };
+ csv.Context.RegisterClassMap<SameNameMultipleTimesClassMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ var expected = "ColumnName,ColumnName,ColumnName\r\n1,2,3\r\n";
+ Assert.Equal(expected, text);
+ }
+ }
+
+ [Fact]
+ public void ConvertUsingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ string result;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<TestClass>
+ {
+ new TestClass { IntColumn = 1 }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ result = reader.ReadToEnd();
+ }
+
+ Assert.Equal("Converted1\r\n", result);
+ }
+
+ [Fact]
+ public void ConvertUsingBlockTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ string result;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<TestClass>
+ {
+ new TestClass { IntColumn = 1 }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingBlockMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ result = reader.ReadToEnd();
+ }
+
+ Assert.Equal("Converted1\r\n", result);
+ }
+
+ [Fact]
+ public void ConvertUsingConstantTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ string result;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<TestClass>
+ {
+ new TestClass { IntColumn = 1 }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingConstantMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ result = reader.ReadToEnd();
+ }
+
+ Assert.Equal("Constant\r\n", result);
+ }
+
+
+ [Fact]
+ public void ConvertUsingNullTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";",
+ HasHeaderRecord = false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<MultipleNamesClass>
+ {
+ new MultipleNamesClass { IntColumn = 1, StringColumn = "test" }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingNullMap>();
+ csv.WriteRecords(records);
+
+ Assert.Equal(";test\r\n", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ConvertUsingInstanceMethodTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ string result;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<TestClass>
+ {
+ new TestClass { IntColumn = 1 }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingInstanceMethodMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ result = reader.ReadToEnd();
+ }
+
+ Assert.Equal("Converted1\r\n", result);
+ }
+
+ [Fact]
+ public void ConvertUsingStaticFunctionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ string result;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<TestClass>
+ {
+ new TestClass { IntColumn = 1 }
+ };
+
+ csv.Context.RegisterClassMap<ConvertUsingStaticFunctionMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ result = reader.ReadToEnd();
+ }
+
+ Assert.Equal("Converted1\r\n", result);
+ }
+
+ private class SameNameMultipleTimesClass
+ {
+ public string Name1 { get; set; }
+
+ public string Name2 { get; set; }
+
+ public string Name3 { get; set; }
+ }
+
+ private sealed class SameNameMultipleTimesClassMap : ClassMap<SameNameMultipleTimesClass>
+ {
+ public SameNameMultipleTimesClassMap()
+ {
+ Map(m => m.Name1).Name("ColumnName").NameIndex(1);
+ Map(m => m.Name2).Name("ColumnName").NameIndex(2);
+ Map(m => m.Name3).Name("ColumnName").NameIndex(0);
+ }
+ }
+
+ private class MultipleNamesClass
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+ }
+
+ private sealed class MultipleNamesClassMap : ClassMap<MultipleNamesClass>
+ {
+ public MultipleNamesClassMap()
+ {
+ Map(m => m.IntColumn).Name("int1", "int2", "int3");
+ Map(m => m.StringColumn).Name("string1", "string2", "string3");
+ }
+ }
+
+ private class TestClass
+ {
+ public int IntColumn { get; set; }
+ }
+
+ private sealed class ConvertUsingMap : ClassMap<TestClass>
+ {
+ public ConvertUsingMap()
+ {
+ Map(m => m.IntColumn).Convert(args => $"Converted{args.Value.IntColumn}");
+ }
+ }
+
+ private sealed class ConvertUsingBlockMap : ClassMap<TestClass>
+ {
+ public ConvertUsingBlockMap()
+ {
+ Map(m => m.IntColumn).Convert(args =>
+ {
+ var x = "Converted";
+ x += args.Value.IntColumn;
+ return x;
+ });
+ }
+ }
+
+ private sealed class ConvertUsingConstantMap : ClassMap<TestClass>
+ {
+ public ConvertUsingConstantMap()
+ {
+ Map(m => m.IntColumn).Convert(m => "Constant");
+ }
+ }
+
+ private sealed class ConvertUsingNullMap : ClassMap<MultipleNamesClass>
+ {
+ public ConvertUsingNullMap()
+ {
+ Map(m => m.IntColumn).Convert(m => (string)null);
+ Map(m => m.StringColumn).Convert(args => args.Value.StringColumn);
+ }
+ }
+
+ private sealed class ConvertUsingInstanceMethodMap : ClassMap<TestClass>
+ {
+ public ConvertUsingInstanceMethodMap()
+ {
+ Map(m => m.IntColumn).Convert(ConvertToStringFunction);
+ }
+
+ private string ConvertToStringFunction(ConvertToStringArgs<TestClass> args)
+ {
+ return $"Converted{args.Value.IntColumn}";
+ }
+ }
+
+ private sealed class ConvertUsingStaticFunctionMap : ClassMap<TestClass>
+ {
+ public ConvertUsingStaticFunctionMap()
+ {
+ Map(m => m.IntColumn).Convert(ConvertToStringFunction);
+ }
+
+ private static string ConvertToStringFunction(ConvertToStringArgs<TestClass> args)
+ {
+ return $"Converted{args.Value.IntColumn}";
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingPrefixTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingPrefixTests.cs
new file mode 100644
index 0000000..45a5243
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingPrefixTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterReferenceMappingPrefixTests
+ {
+ [Fact]
+ public void ReferencesWithPrefixTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<AMap>();
+
+ var list = new List<A>();
+ for (var i = 0; i < 4; i++)
+ {
+ var row = i + 1;
+ list.Add(new A
+ {
+ Id = "a" + row,
+ B = new B
+ {
+ Id = "b" + row,
+ C = new C
+ {
+ Id = "c" + row
+ }
+ }
+ });
+ }
+
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,BPrefix_Id,C.CId");
+ expected.AppendLine("a1,b1,c1");
+ expected.AppendLine("a2,b2,c2");
+ expected.AppendLine("a3,b3,c3");
+ expected.AppendLine("a4,b4,c4");
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ private class A
+ {
+ public string Id { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string Id { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string Id { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id);
+ References<BMap>(m => m.B).Prefix("BPrefix_", false);
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.Id);
+ References<CMap>(m => m.C).Prefix();
+ }
+ }
+
+ private sealed class CMap : ClassMap<C>
+ {
+ public CMap()
+ {
+ Map(m => m.Id).Name("CId");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingTests.cs
new file mode 100644
index 0000000..4a0053f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterReferenceMappingTests.cs
@@ -0,0 +1,156 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterReferenceMappingTests
+ {
+ [Fact]
+ public void NestedReferencesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<AMap>();
+
+ var list = new List<A>();
+ for (var i = 0; i < 4; i++)
+ {
+ var row = i + 1;
+ list.Add(
+ new A
+ {
+ Id = "a" + row,
+ B = new B
+ {
+ Id = "b" + row,
+ C = new C
+ {
+ Id = "c" + row,
+ D = new D
+ {
+ Id = "d" + row
+ }
+ }
+ }
+ });
+ };
+
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("AId,BId,CId,DId");
+ expected.AppendLine("a1,b1,c1,d1");
+ expected.AppendLine("a2,b2,c2,d2");
+ expected.AppendLine("a3,b3,c3,d3");
+ expected.AppendLine("a4,b4,c4,d4");
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ [Fact]
+ public void NullReferenceTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<AMap>();
+
+ var list = new List<A>
+ {
+ new A
+ {
+ Id = "1",
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("AId,BId,CId,DId");
+ expected.AppendLine("1,,,");
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ private class A
+ {
+ public string Id { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string Id { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string Id { get; set; }
+
+ public D D { get; set; }
+ }
+
+ private class D
+ {
+ public string Id { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id).Name("AId");
+ References<BMap>(m => m.B);
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.Id).Name("BId");
+ References<CMap>(m => m.C);
+ }
+ }
+
+ private sealed class CMap : ClassMap<C>
+ {
+ public CMap()
+ {
+ Map(m => m.Id).Name("CId");
+ References<DMap>(m => m.D);
+ }
+ }
+
+ private sealed class DMap : ClassMap<D>
+ {
+ public DMap()
+ {
+ Map(m => m.Id).Name("DId");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterSubClassingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterSubClassingTests.cs
new file mode 100644
index 0000000..fcd4241
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterSubClassingTests.cs
@@ -0,0 +1,42 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterSubClassingTests
+ {
+ [Fact]
+ public void WriteRecordTest()
+ {
+ var data = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" },
+ new Test { Id = 2, Name = "two" }
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream);
+ var csvWriter = new MyCsvWriter(writer);
+
+ csvWriter.WriteRecords(data);
+ }
+
+ private class MyCsvWriter : CsvWriter
+ {
+ public MyCsvWriter(TextWriter writer) : base(writer, CultureInfo.InvariantCulture) { }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterTests.cs
new file mode 100644
index 0000000..2309ef7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/CsvWriterTests.cs
@@ -0,0 +1,1030 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Int32Converter = CsvHelper.TypeConversion.Int32Converter;
+using System.Dynamic;
+using Xunit;
+using System.Threading;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvWriterTests
+ {
+ public CsvWriterTests()
+ {
+ Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
+ }
+
+ [Fact]
+ public void WriteFieldTest()
+ {
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+
+ var date = DateTime.Now.ToString();
+ var guid = Guid.NewGuid().ToString();
+ csv.WriteField("one");
+ csv.WriteField("one, two");
+ csv.WriteField("one \"two\" three");
+ csv.WriteField(" one ");
+ csv.WriteField(date);
+ csv.WriteField((short)1);
+ csv.WriteField(2);
+ csv.WriteField((long)3);
+ csv.WriteField((float)4);
+ csv.WriteField((double)5);
+ csv.WriteField(guid);
+ csv.NextRecord();
+
+ var reader = new StreamReader(stream);
+ stream.Position = 0;
+ var data = reader.ReadToEnd();
+
+ Assert.Equal("one,\"one, two\",\"one \"\"two\"\" three\",\" one \"," + date + ",1,2,3,4,5," + guid + "\r\n", data);
+ }
+
+ [Fact]
+ public void WriteRecordTest()
+ {
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "first column,1,string column,test\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordNoIndexesTest()
+ {
+ var record = new TestRecordNoIndexes
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream) { AutoFlush = true })
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<TestRecordNoIndexesMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+
+ var expected = "1,string column,first column,test\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsTest()
+ {
+ var records = new List<TestRecord>
+ {
+ new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ },
+ new TestRecord
+ {
+ IntColumn = 2,
+ StringColumn = "string column 2",
+ IgnoredColumn = "ignored column 2",
+ FirstColumn = "first column 2",
+ },
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecords(records);
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "FirstColumn,Int Column,StringColumn,TypeConvertedColumn\r\n";
+ expected += "first column,1,string column,test\r\n";
+ expected += "first column 2,2,string column 2,test\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteEmptyArrayTest()
+ {
+ var records = new TestRecord[] { };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecords(records);
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "FirstColumn,Int Column,StringColumn,TypeConvertedColumn\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordsCalledWithTwoParametersTest()
+ {
+ var records = new List<object>
+ {
+ new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ },
+ new TestRecord
+ {
+ IntColumn = 2,
+ StringColumn = "string column 2",
+ IgnoredColumn = "ignored column 2",
+ FirstColumn = "first column 2",
+ },
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecords(records);
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = "FirstColumn,Int Column,StringColumn,TypeConvertedColumn\r\n";
+ expected += "first column,1,string column,test\r\n";
+ expected += "first column 2,2,string column 2,test\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, config);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+ csv.WriteRecord(new TestRecord());
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+
+ Assert.Equal(",0,,test\r\n", csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordWithNullRecordTest()
+ {
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+ csv.WriteRecord((TestRecord)null);
+ csv.NextRecord();
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("first column,1,string column,test");
+ expected.AppendLine(",,,");
+ expected.AppendLine("first column,1,string column,test");
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordWithReferencesTest()
+ {
+ var record = new Person
+ {
+ FirstName = "First Name",
+ LastName = "Last Name",
+ HomeAddress = new Address
+ {
+ Street = "Home Street",
+ City = "Home City",
+ State = "Home State",
+ Zip = "Home Zip",
+ },
+ WorkAddress = new Address
+ {
+ Street = "Work Street",
+ City = "Work City",
+ State = "Work State",
+ Zip = "Work Zip",
+ }
+ };
+
+ var stream = new MemoryStream();
+ var writer = new StreamWriter(stream) { AutoFlush = true };
+ var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
+ csv.Context.RegisterClassMap<PersonMap>();
+
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ stream.Position = 0;
+ var reader = new StreamReader(stream);
+ var csvFile = reader.ReadToEnd();
+
+ var expected = "First Name,Last Name,Home Street,Home City,Home State,Home Zip,Work Street,Work City,Work State,Work Zip\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ [Fact]
+ public void WriteRecordsAllFieldsQuotedTest()
+ {
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first column",
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => true,
+ };
+
+ string csv;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ csvWriter.Context.RegisterClassMap<TestRecordMap>();
+ csvWriter.WriteRecord(record);
+ csvWriter.NextRecord();
+
+ writer.Flush();
+ stream.Position = 0;
+
+ csv = reader.ReadToEnd();
+ }
+
+ var expected = "\"first column\",\"1\",\"string column\",\"test\"\r\n";
+
+ Assert.Equal(expected, csv);
+ }
+
+ [Fact]
+ public void WriteRecordsNoFieldsQuotedTest()
+ {
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ StringColumn = "string \" column",
+ IgnoredColumn = "ignored column",
+ FirstColumn = "first, column",
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => false,
+ };
+ string csv;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ csvWriter.Context.RegisterClassMap<TestRecordMap>();
+ csvWriter.WriteRecord(record);
+ csvWriter.NextRecord();
+
+ writer.Flush();
+ stream.Position = 0;
+
+ csv = reader.ReadToEnd();
+ }
+
+ var expected = "first, column,1,string \" column,test\r\n";
+
+ Assert.Equal(expected, csv);
+ }
+
+ [Fact]
+ public void WriteHeaderTest()
+ {
+ string csv;
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csvWriter.Context.RegisterClassMap<TestRecordMap>();
+ csvWriter.WriteHeader(typeof(TestRecord));
+ csvWriter.NextRecord();
+
+ writer.Flush();
+ stream.Position = 0;
+
+ csv = reader.ReadToEnd();
+ }
+
+ const string Expected = "FirstColumn,Int Column,StringColumn,TypeConvertedColumn\r\n";
+ Assert.Equal(Expected, csv);
+ }
+
+ [Fact]
+ public void WriteRecordWithDelimiterInFieldTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var record = new TestSinglePropertyRecord
+ {
+ Name = "one,two"
+ };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("\"one,two\"\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordWithQuoteInFieldTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var record = new TestSinglePropertyRecord
+ {
+ Name = "one\"two"
+ };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("\"one\"\"two\"\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordWithQuoteAllFieldsOnAndDelimiterInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var record = new TestSinglePropertyRecord
+ {
+ Name = "one,two"
+ };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("\"one,two\"\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordWithQuoteAllFieldsOnAndQuoteInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var record = new TestSinglePropertyRecord
+ {
+ Name = "one\"two"
+ };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("\"one\"\"two\"\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsWithInvariantCultureTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<TestRecordMap>();
+
+ var record = new TestRecord
+ {
+ IntColumn = 1,
+ FirstColumn = "first column",
+ IgnoredColumn = "ignored column",
+ StringColumn = "string column",
+ };
+
+ csv.WriteRecord(record);
+ writer.Flush();
+ stream.Position = 0;
+
+ var csvString = reader.ReadToEnd();
+ }
+ }
+
+ [Fact]
+ public void WriteNoGetterTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<TestPrivateGet>
+ {
+ new TestPrivateGet
+ {
+ Id = 1,
+ Name = "one"
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecord(new { Id = 1, Name = "one" });
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ Assert.Equal("1,one\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WritePrimitivesRecordsHasHeaderTrueTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<int> { 1, 2, 3 };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("1\r\n2\r\n3\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WritePrimitivesRecordsHasHeaderFalseTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<int> { 1, 2, 3 };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("1\r\n2\r\n3\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteStructRecordsTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<TestStruct>
+ {
+ new TestStruct { Id = 1, Name = "one" },
+ new TestStruct { Id = 2, Name = "two" },
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+
+ Assert.Equal("Id,Name\r\n1,one\r\n2,two\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteStructReferenceRecordsTest()
+ {
+ var list = new List<TestStructParent>
+ {
+ new TestStructParent
+ {
+ Test = new TestStruct
+ {
+ Id = 1,
+ Name = "one",
+ },
+ },
+ };
+
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<TestStructParentMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ Assert.Equal("Id,Name\r\n1,one\r\n", data);
+ }
+ }
+
+ [Fact]
+ public void WriteNestedHeadersTest()
+ {
+ var list = new List<Person>
+ {
+ new Person
+ {
+ FirstName = "first",
+ LastName = "last",
+ HomeAddress = new Address
+ {
+ City = "home city",
+ State = "home state",
+ Street = "home street",
+ Zip = "home zip",
+ },
+ WorkAddress = new Address
+ {
+ City = "work city",
+ State = "work state",
+ Street = "work street",
+ Zip = "work zip",
+ },
+ },
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReferenceHeaderPrefix = args => $"{args.MemberName}."
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("FirstName,LastName,HomeAddress.Street,HomeAddress.City,HomeAddress.State,HomeAddress.Zip,WorkAddress.Street,WorkAddress.City,WorkAddress.State,WorkAddress.Zip");
+ expected.AppendLine("first,last,home street,home city,home state,home zip,work street,work city,work state,work zip");
+ Assert.Equal(expected.ToString(), text);
+ }
+ }
+
+ [Fact]
+ public void WriteEmptyListTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<TestRecord>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ Assert.False(string.IsNullOrWhiteSpace(data));
+ }
+ }
+
+ [Fact]
+ public void ClassWithStaticAutoMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ TestWithStatic.Name = "one";
+ var records = new List<TestWithStatic>
+ {
+ new TestWithStatic
+ {
+ Id = 1
+ },
+ };
+
+ csv.WriteRecords(records);
+ }
+ }
+
+ [Fact]
+ public void ClassWithStaticUsingMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<TestWithStaticMap>();
+
+ TestWithStatic.Name = "one";
+ var records = new List<TestWithStatic>
+ {
+ new TestWithStatic
+ {
+ Id = 1
+ },
+ };
+
+ csv.WriteRecords(records);
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicListTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<dynamic>();
+ dynamic record = new { Id = 1, Name = "one" };
+ list.Add(record);
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ Assert.Equal("Id,Name\r\n1,one\r\n", text);
+ }
+ }
+
+ [Fact]
+ public void WriteExpandoListTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<dynamic>();
+ dynamic record = new ExpandoObject();
+ record.Id = 1;
+ record.Name = "one";
+ list.Add(record);
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ Assert.Equal("Id,Name\r\n1,one\r\n", text);
+ }
+ }
+
+
+ [Fact]
+ public void WriteInternalConstructorClassTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(new List<GetOnly>());
+ writer.Flush();
+ stream.Position = 0;
+
+ var text = reader.ReadToEnd();
+ Assert.Equal("One\r\n", text);
+ }
+ }
+
+ private class GetOnly
+ {
+ internal GetOnly(string someParam)
+ {
+ }
+
+ public int One { get; }
+ }
+
+ private class TestWithStatic
+ {
+ public int Id { get; set; }
+
+ public static string Name { get; set; }
+ }
+
+ private sealed class TestWithStaticMap : ClassMap<TestWithStatic>
+ {
+ public TestWithStaticMap()
+ {
+ Map(m => m.Id);
+ }
+ }
+
+ private class TestStructParent
+ {
+ public TestStruct Test { get; set; }
+ }
+
+ private sealed class TestStructParentMap : ClassMap<TestStructParent>
+ {
+ public TestStructParentMap()
+ {
+ References<TestStructMap>(m => m.Test);
+ }
+ }
+
+ private struct TestStruct
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class TestStructMap : ClassMap<TestStruct>
+ {
+ public TestStructMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+
+ private class TestPrivateGet
+ {
+ public int Id { get; set; }
+
+ public string Name { private get; set; }
+ }
+
+ private class TestSinglePropertyRecord
+ {
+ public string Name { get; set; }
+ }
+
+ private class TestRecord
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+
+ public string IgnoredColumn { get; set; }
+
+ public string FirstColumn { get; set; }
+
+ public string TypeConvertedColumn { get; set; }
+ }
+
+ private sealed class TestRecordMap : ClassMap<TestRecord>
+ {
+ public TestRecordMap()
+ {
+ Map(m => m.IntColumn).Name("Int Column").Index(1).TypeConverter<Int32Converter>();
+ Map(m => m.StringColumn);
+ Map(m => m.FirstColumn).Index(0);
+ Map(m => m.TypeConvertedColumn).TypeConverter<TestTypeConverter>();
+ }
+ }
+
+ private class TestRecordNoIndexes
+ {
+ public int IntColumn { get; set; }
+
+ public string StringColumn { get; set; }
+
+ public string IgnoredColumn { get; set; }
+
+ public string FirstColumn { get; set; }
+
+ public string TypeConvertedColumn { get; set; }
+ }
+
+ private sealed class TestRecordNoIndexesMap : ClassMap<TestRecordNoIndexes>
+ {
+ public TestRecordNoIndexesMap()
+ {
+ Map(m => m.IntColumn).Name("Int Column").TypeConverter<Int32Converter>();
+ Map(m => m.StringColumn);
+ Map(m => m.FirstColumn);
+ Map(m => m.TypeConvertedColumn).TypeConverter<TestTypeConverter>();
+ }
+ }
+
+ private class TestTypeConverter : ITypeConverter
+ {
+ public string ConvertToString(object value, IWriterRow row, MemberMapData propertyMapData)
+ {
+ return "test";
+ }
+
+ public object ConvertFromString(string text, IReaderRow row, MemberMapData propertyMapData)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool CanConvertFrom(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool CanConvertTo(Type type)
+ {
+ return true;
+ }
+ }
+
+ private class Person
+ {
+ public string FirstName { get; set; }
+
+ public string LastName { get; set; }
+
+ public Address HomeAddress { get; set; }
+
+ public Address WorkAddress { get; set; }
+ }
+
+ private class Address
+ {
+ public string Street { get; set; }
+
+ public string City { get; set; }
+
+ public string State { get; set; }
+
+ public string Zip { get; set; }
+ }
+
+ private sealed class PersonMap : ClassMap<Person>
+ {
+ public PersonMap()
+ {
+ Map(m => m.FirstName);
+ Map(m => m.LastName);
+ References<HomeAddressMap>(m => m.HomeAddress);
+ References<WorkAddressMap>(m => m.WorkAddress);
+ }
+ }
+
+ private sealed class HomeAddressMap : ClassMap<Address>
+ {
+ public HomeAddressMap()
+ {
+ Map(m => m.Street).Name("HomeStreet");
+ Map(m => m.City).Name("HomeCity");
+ Map(m => m.State).Name("HomeState");
+ Map(m => m.Zip).Name("HomeZip");
+ }
+ }
+
+ private sealed class WorkAddressMap : ClassMap<Address>
+ {
+ public WorkAddressMap()
+ {
+ Map(m => m.Street).Name("WorkStreet");
+ Map(m => m.City).Name("WorkCity");
+ Map(m => m.State).Name("WorkState");
+ Map(m => m.Zip).Name("WorkZip");
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Culture/TypeConverterOptionsFactoryTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Culture/TypeConverterOptionsFactoryTests.cs
new file mode 100644
index 0000000..05997bc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Culture/TypeConverterOptionsFactoryTests.cs
@@ -0,0 +1,229 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.Culture
+{
+
+ public class TypeConverterOptionsFactoryTests
+ {
+ [Fact]
+ public void AddGetRemoveTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var customOptions = new TypeConverterOptions
+ {
+ Formats = new string[] { "custom" },
+ };
+ context.TypeConverterOptionsCache.AddOptions<string>(customOptions);
+ var options = context.TypeConverterOptionsCache.GetOptions<string>();
+
+ Assert.Equal(customOptions.Formats, options.Formats);
+
+ context.TypeConverterOptionsCache.RemoveOptions<string>();
+
+ options = context.TypeConverterOptionsCache.GetOptions<string>();
+
+ Assert.NotEqual(customOptions.Formats, options.Formats);
+ }
+
+ [Fact]
+ public void GetFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.Read();
+ Assert.Equal(1234, csvReader.GetField<int>(0));
+ Assert.Equal(5678, csvReader.GetField(typeof(int), 1));
+ }
+ }
+
+ [Fact]
+ public void GetFieldSwitchCulturesTest()
+ {
+ GetFieldForCultureTest("\"1234,32\",\"5678,44\"", "fr-FR", 1234.32M, 5678.44M);
+ GetFieldForCultureTest("\"9876.54\",\"3210.98\"", "en-GB", 9876.54M, 3210.98M);
+ GetFieldForCultureTest("\"4455,6677\",\"9988,77\"", "el-GR", 4455.6677M, 9988.77M);
+ }
+
+ private static void GetFieldForCultureTest(string csvText, string culture, decimal expected1, decimal expected2)
+ {
+ var config = new CsvConfiguration(new CultureInfo(culture))
+ {
+ HasHeaderRecord = false,
+ Delimiter = ",",
+ };
+ using (var reader = new StringReader(csvText))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ csvReader.Read();
+ Assert.Equal(expected1, csvReader.GetField<decimal>(0));
+ Assert.Equal(expected2, csvReader.GetField(typeof(decimal), 1));
+ }
+ }
+
+ [Fact]
+ public void GetRecordsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.GetRecords<Test>().ToList();
+ }
+ }
+
+ [Fact]
+ public void GetRecordsAppliedWhenMappedTest()
+ {
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"$5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.Context.RegisterClassMap<TestMap>();
+ csvReader.GetRecords<Test>().ToList();
+ }
+ }
+
+ [Fact]
+ public void WriteFieldTest()
+ {
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.WriteField(1234);
+ csvWriter.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\"\r\n", record);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsTest()
+ {
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Number = 1234, NumberOverridenInMap = 5678 },
+ };
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\",\"$5,678.00\"\r\n", record);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsAppliedWhenMappedTest()
+ {
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Number = 1234, NumberOverridenInMap = 5678 },
+ };
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.Context.RegisterClassMap<TestMap>();
+ csvWriter.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\",\"5,678.00\"\r\n", record);
+ }
+ }
+
+ private class Test
+ {
+ public int Number { get; set; }
+
+ public int NumberOverridenInMap { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Number);
+ Map(m => m.NumberOverridenInMap)
+ .TypeConverterOption.NumberStyles(NumberStyles.AllowThousands | NumberStyles.AllowCurrencySymbol)
+ .TypeConverterOption.Format("N2");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DataTableTests/CsvDataReaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DataTableTests/CsvDataReaderTests.cs
new file mode 100644
index 0000000..726862b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DataTableTests/CsvDataReaderTests.cs
@@ -0,0 +1,509 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.DataTableTests
+{
+
+ public class CsvDataReaderTests
+ {
+ [Fact]
+ public void GetValuesTest()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Boolean,Byte,Bytes,Char,Chars,DateTime,Decimal,Double,Float,Guid,Short,Int,Long,Null");
+ s.AppendLine("true,1,0x0102,a,ab,1/1/2019,1.23,4.56,7.89,eca0c8c6-9a2a-4e6c-8599-3561abda13f1,1,2,3,null");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("null");
+ var dataReader = new CsvDataReader(csv);
+ dataReader.Read();
+
+ Assert.True(dataReader.GetBoolean(0));
+ Assert.Equal(1, dataReader.GetByte(1));
+
+ byte[] byteBuffer = new byte[2];
+ dataReader.GetBytes(2, 0, byteBuffer, 0, byteBuffer.Length);
+ Assert.Equal(0x1, byteBuffer[0]);
+ Assert.Equal(0x2, byteBuffer[1]);
+
+ Assert.Equal('a', dataReader.GetChar(3));
+
+ char[] charBuffer = new char[2];
+ dataReader.GetChars(4, 0, charBuffer, 0, charBuffer.Length);
+ Assert.Equal('a', charBuffer[0]);
+ Assert.Equal('b', charBuffer[1]);
+
+ Assert.Throws<NotSupportedException>(() => dataReader.GetData(0));
+ Assert.Equal(DateTime.Parse("1/1/2019"), dataReader.GetDateTime(5));
+ Assert.Equal(typeof(string).Name, dataReader.GetDataTypeName(0));
+ Assert.Equal(1.23m, dataReader.GetDecimal(6));
+ Assert.Equal(4.56d, dataReader.GetDouble(7));
+ Assert.Equal(typeof(string), dataReader.GetFieldType(0));
+ Assert.Equal(7.89f, dataReader.GetFloat(8));
+ Assert.Equal(Guid.Parse("eca0c8c6-9a2a-4e6c-8599-3561abda13f1"), dataReader.GetGuid(9));
+ Assert.Equal(1, dataReader.GetInt16(10));
+ Assert.Equal(2, dataReader.GetInt32(11));
+ Assert.Equal(3, dataReader.GetInt64(12));
+ Assert.Equal("Boolean", dataReader.GetName(0));
+ Assert.Equal(0, dataReader.GetOrdinal("Boolean"));
+
+ Assert.Equal("true", dataReader.GetString(0));
+ Assert.Equal("true", dataReader.GetValue(0));
+
+ var objectBuffer = new object[14];
+ dataReader.GetValues(objectBuffer);
+ Assert.Equal("true", objectBuffer[0]);
+ Assert.Equal(DBNull.Value, objectBuffer[13]);
+ Assert.True(dataReader.IsDBNull(13));
+ }
+ }
+
+ [Fact]
+ public void GetSchemaTableTest()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one");
+ s.AppendLine("2,two");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var dataReader = new CsvDataReader(csv);
+
+ var schemaTable = dataReader.GetSchemaTable();
+ Assert.Equal(25, schemaTable.Columns.Count);
+ Assert.Equal(2, schemaTable.Rows.Count);
+ }
+ }
+
+ [Fact]
+ public void DataTableLoadTest()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one");
+ s.AppendLine("2,two");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var dataReader = new CsvDataReader(csv);
+
+ var dataTable = new DataTable();
+ dataTable.Columns.Add("Id", typeof(int));
+ dataTable.Columns.Add("Name", typeof(string));
+
+ dataTable.Load(dataReader);
+
+ Assert.Equal(2, dataTable.Rows.Count);
+ Assert.Equal(1, dataTable.Rows[0]["Id"]);
+ Assert.Equal("one", dataTable.Rows[0]["Name"]);
+ Assert.Equal(2, dataTable.Rows[1]["Id"]);
+ Assert.Equal("two", dataTable.Rows[1]["Name"]);
+ }
+ }
+
+ [Fact]
+ public void DataTableLoadHeaderAndRowsHaveDifferentLengthTest()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one,a");
+ s.AppendLine("2,two,b");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var dataReader = new CsvDataReader(csv);
+
+ var dataTable = new DataTable();
+ dataTable.Columns.Add("Id", typeof(int));
+ dataTable.Columns.Add("Name", typeof(string));
+
+ dataTable.Load(dataReader);
+
+ Assert.Equal(2, dataTable.Rows.Count);
+ Assert.Equal(1, dataTable.Rows[0]["Id"]);
+ Assert.Equal("one", dataTable.Rows[0]["Name"]);
+ Assert.Equal(2, dataTable.Rows[1]["Id"]);
+ Assert.Equal("two", dataTable.Rows[1]["Name"]);
+ }
+ }
+
+ [Fact]
+ public void DataTableLoadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var s = new StringBuilder();
+ s.AppendLine("1,one");
+ s.AppendLine("2,two");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var dataReader = new CsvDataReader(csv);
+
+ var dataTable = new DataTable();
+
+ dataTable.Load(dataReader);
+
+ Assert.Equal(0, dataTable.Rows.Count);
+ }
+ }
+
+ [Fact]
+ public void ReadWithNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var s = new StringBuilder();
+ s.AppendLine("1,one");
+ s.AppendLine("2,two");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var dataReader = new CsvDataReader(csv);
+
+ dataReader.Read();
+ Assert.Equal(1, dataReader.GetInt32(0));
+ Assert.Equal("one", dataReader.GetString(1));
+
+ dataReader.Read();
+ Assert.Equal(2, dataReader.GetInt32(0));
+ Assert.Equal("two", dataReader.GetString(1));
+ }
+ }
+
+ [Fact]
+ public void IsNullTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var s = new StringBuilder();
+ s.AppendLine(",null");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("null");
+
+ var dataReader = new CsvDataReader(csv);
+ Assert.False(dataReader.IsDBNull(0));
+ Assert.True(dataReader.IsDBNull(1));
+ }
+ }
+
+ [Fact]
+ public void DbNullTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var s = new StringBuilder();
+ s.AppendLine(",null");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("null");
+
+ var dataReader = new CsvDataReader(csv);
+ Assert.Equal(string.Empty, dataReader.GetValue(0));
+ Assert.Equal(DBNull.Value, dataReader.GetValue(1));
+
+ var values = new object[2];
+ dataReader.GetValues(values);
+ Assert.Equal(string.Empty, values[0]);
+ Assert.Equal(DBNull.Value, values[1]);
+ }
+ }
+
+ [Fact]
+ public void GetOrdinalCaseInsensitiveTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ null,
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ using (var dr = new CsvDataReader(csv))
+ {
+ var ordinal = dr.GetOrdinal("name");
+
+ Assert.Equal(1, ordinal);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetOrdinalMissingTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ null,
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ using (var dr = new CsvDataReader(csv))
+ {
+ Assert.Throws<IndexOutOfRangeException>(() =>
+ {
+ dr.GetOrdinal("Foo");
+ });
+ }
+ }
+ }
+
+ [Fact]
+ public void DataTableLoadEmptyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var reader = new StringReader(string.Empty))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var dataReader = new CsvDataReader(csv);
+ Assert.Equal(0, dataReader.FieldCount);
+ }
+ }
+
+ [Fact]
+ public void DataTableNullableValueTypeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var parser = new ParserMock(config)
+ {
+ { "Id", "Name", "DateTime" },
+ { "1", "one", DateTime.Now.ToString() },
+ };
+ using (var csv = new CsvReader(parser))
+ using (var dr = new CsvDataReader(csv))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("");
+
+ var table = new DataTable();
+ table.Columns.Add("Id", typeof(int));
+ table.Columns.Add("Name", typeof(string));
+ var column = table.Columns.Add("DateTime", typeof(DateTime));
+ column.AllowDBNull = true;
+
+ table.Load(dr);
+ }
+ }
+
+ [Theory]
+ [InlineData(true)]
+ [InlineData(false)]
+ public void GetDataTypeNameTest(bool useDefaultSchema)
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Boolean,Byte,Int,Decimal,Double,DateTime,String,Guid");
+ s.AppendLine("true,1,2,4.56,7.89,2/17/2022,foo,eca0c8c6-9a2a-4e6c-8599-3561abda13f1");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ if (useDefaultSchema)
+ {
+ var dataReader = new CsvDataReader(csv);
+ dataReader.Read();
+ for (var i = 0; i < dataReader.FieldCount; ++i)
+ {
+ Assert.Equal(typeof(string).Name, dataReader.GetDataTypeName(i));
+ }
+ }
+ else
+ {
+ var expectedDataTypeNames = new[]
+ {
+ typeof(bool).Name,
+ typeof(byte).Name,
+ typeof(int).Name,
+ typeof(decimal).Name,
+ typeof(double).Name,
+ typeof(DateTime).Name,
+ typeof(string).Name,
+ typeof(Guid).Name,
+ };
+ var dataReader = new CsvDataReader(csv, GetOverridingSchemaTable());
+ for (var i = 0; i < expectedDataTypeNames.Length; ++i)
+ {
+ Assert.Equal(expectedDataTypeNames[i], dataReader.GetDataTypeName(i));
+ }
+ }
+ }
+ }
+
+ [Fact]
+ public void GetDataTypeNameThrowsArgumentOutOfRangeExceptionWhenGivenAnEmptySchema()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Boolean,Byte,Int,Decimal,Double,DateTime,String,Guid");
+ s.AppendLine("true,1,2,4.56,7.89,2/17/2022,foo,eca0c8c6-9a2a-4e6c-8599-3561abda13f1");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var badSchema = new DataTable();
+ var dataReader = new CsvDataReader(csv, badSchema);
+ dataReader.Read();
+ Assert.Throws<IndexOutOfRangeException>(() => dataReader.GetDataTypeName(0));
+ }
+ }
+
+ [Fact]
+ public void GetDataTypeNameThrowsArgumentExceptionWhenGivenASchemaMissingDataType()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Boolean,Byte,Int,Decimal,Double,DateTime,String,Guid");
+ s.AppendLine("true,1,2,4.56,7.89,2/17/2022,foo,eca0c8c6-9a2a-4e6c-8599-3561abda13f1");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var badSchema = new DataTable();
+ badSchema.Rows.Add(badSchema.NewRow());
+ var dataReader = new CsvDataReader(csv, badSchema);
+ dataReader.Read();
+ Assert.Throws<ArgumentException>(() => dataReader.GetDataTypeName(0));
+ }
+ }
+
+ [Fact]
+ public void GetDataTypeNameThrowsInvalidCastExceptionWhenGivenASchemaWithAnUnexpectedDataTypeValue()
+ {
+ var s = new StringBuilder();
+ s.AppendLine("Boolean,Byte,Int,Decimal,Double,DateTime,String,Guid");
+ s.AppendLine("true,1,2,4.56,7.89,2/17/2022,foo,eca0c8c6-9a2a-4e6c-8599-3561abda13f1");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var badSchema = new DataTable();
+ badSchema.Columns.Add("DataType");
+ var row = badSchema.NewRow();
+ row["DataType"] = "foo";
+ badSchema.Rows.Add(row);
+ var dataReader = new CsvDataReader(csv, badSchema);
+ dataReader.Read();
+ Assert.Throws<InvalidOperationException>(() => dataReader.GetDataTypeName(0));
+ }
+ }
+
+ private DataTable GetOverridingSchemaTable()
+ {
+ var columnTypeMapping = new Tuple<string, Type, DbType>[]
+ {
+ new Tuple<string, Type, DbType>("Boolean", typeof(bool), DbType.Boolean),
+ new Tuple<string, Type, DbType>("Byte", typeof(byte), DbType.Byte),
+ new Tuple<string, Type, DbType>("Int", typeof(int), DbType.Int32),
+ new Tuple<string, Type, DbType>("Decimal", typeof(decimal), DbType.Decimal),
+ new Tuple<string, Type, DbType>("Double", typeof(double), DbType.Double),
+ new Tuple<string, Type, DbType>("DateTime", typeof(DateTime), DbType.DateTime),
+ new Tuple<string, Type, DbType>("String", typeof(string), DbType.String),
+ new Tuple<string, Type, DbType>("Guid", typeof(Guid), DbType.Guid),
+ };
+
+ // https://docs.microsoft.com/en-us/dotnet/api/system.data.datatablereader.getschematable?view=netframework-4.7.2
+ var dt = new DataTable("SchemaTable");
+ dt.Columns.Add("AllowDBNull", typeof(bool));
+ dt.Columns.Add("AutoIncrementSeed", typeof(long));
+ dt.Columns.Add("AutoIncrementStep", typeof(long));
+ dt.Columns.Add("BaseCatalogName");
+ dt.Columns.Add("BaseColumnName");
+ dt.Columns.Add("BaseColumnNamespace");
+ dt.Columns.Add("BaseSchemaName");
+ dt.Columns.Add("BaseTableName");
+ dt.Columns.Add("BaseTableNamespace");
+ dt.Columns.Add("ColumnName");
+ dt.Columns.Add("ColumnMapping", typeof(MappingType));
+ dt.Columns.Add("ColumnOrdinal", typeof(int));
+ dt.Columns.Add("ColumnSize", typeof(int));
+ dt.Columns.Add("DataType", typeof(Type));
+ dt.Columns.Add("DefaultValue", typeof(object));
+ dt.Columns.Add("Expression");
+ dt.Columns.Add("IsAutoIncrement", typeof(bool));
+ dt.Columns.Add("IsKey", typeof(bool));
+ dt.Columns.Add("IsLong", typeof(bool));
+ dt.Columns.Add("IsReadOnly", typeof(bool));
+ dt.Columns.Add("IsRowVersion", typeof(bool));
+ dt.Columns.Add("IsUnique", typeof(bool));
+ dt.Columns.Add("NumericPrecision", typeof(short));
+ dt.Columns.Add("NumericScale", typeof(short));
+ dt.Columns.Add("ProviderType", typeof(int));
+
+ for (var i = 0; i < columnTypeMapping.Length; i++)
+ {
+ var row = dt.NewRow();
+ row["AllowDBNull"] = true;
+ row["AutoIncrementSeed"] = DBNull.Value;
+ row["AutoIncrementStep"] = DBNull.Value;
+ row["BaseCatalogName"] = null;
+ row["BaseColumnName"] = columnTypeMapping[i].Item1;
+ row["BaseColumnNamespace"] = null;
+ row["BaseSchemaName"] = null;
+ row["BaseTableName"] = null;
+ row["BaseTableNamespace"] = null;
+ row["ColumnName"] = columnTypeMapping[i].Item1;
+ row["ColumnMapping"] = MappingType.Element;
+ row["ColumnOrdinal"] = i;
+ row["ColumnSize"] = int.MaxValue;
+ row["DataType"] = columnTypeMapping[i].Item2;
+ row["DefaultValue"] = null;
+ row["Expression"] = null;
+ row["IsAutoIncrement"] = false;
+ row["IsKey"] = false;
+ row["IsLong"] = false;
+ row["IsReadOnly"] = true;
+ row["IsRowVersion"] = false;
+ row["IsUnique"] = false;
+ row["NumericPrecision"] = columnTypeMapping[i].Item3 == DbType.Decimal ? 10 : DBNull.Value;
+ row["NumericScale"] = columnTypeMapping[i].Item3 == DbType.Decimal ? 2 : DBNull.Value;
+ row["ProviderType"] = columnTypeMapping[i].Item3;
+
+ dt.Rows.Add(row);
+ }
+
+ return dt;
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Defaults/WritingDefaultsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Defaults/WritingDefaultsTests.cs
new file mode 100644
index 0000000..85ab8ea
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Defaults/WritingDefaultsTests.cs
@@ -0,0 +1,118 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Defaults
+{
+
+ public class WritingDefaultsTests
+ {
+ [Fact]
+ public void EmptyFieldsOnNullReferencePropertyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ UseNewObjectForNullReferenceMembers = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<A>
+ {
+ new A
+ {
+ AId = 1,
+ },
+ new A
+ {
+ AId = 2,
+ B = new B
+ {
+ BId = 3,
+ },
+ },
+ };
+
+ csv.Context.RegisterClassMap<AMap>();
+ csv.WriteRecords(records);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ var expected = "AId,BId,CId\r\n" +
+ "1,,\r\n" +
+ "2,3,0\r\n";
+ Assert.Equal(expected, data);
+ }
+ }
+
+ [Fact]
+ public void DefaultFieldsOnNullReferencePropertyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<A>
+ {
+ new A
+ {
+ AId = 1,
+ },
+ new A
+ {
+ AId = 2,
+ B = new B
+ {
+ BId = 3,
+ },
+ },
+ };
+
+ csv.Context.RegisterClassMap<AMap>();
+ csv.WriteRecords(records);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ var expected = "AId,BId,CId\r\n" +
+ "1,0,0\r\n" +
+ "2,3,0\r\n";
+ Assert.Equal(expected, data);
+ }
+ }
+
+ private class A
+ {
+ public int AId { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ AutoMap(CultureInfo.InvariantCulture);
+ Map(m => m.AId).Default(1);
+ }
+ }
+
+ public class B
+ {
+ public int BId { get; set; }
+ public int CId { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DisposeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DisposeTests.cs
new file mode 100644
index 0000000..b9d1f63
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DisposeTests.cs
@@ -0,0 +1,55 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+
+namespace CsvHelper.Tests
+{
+
+ public class DisposeTests
+ {
+ [Fact]
+ public void WriterFlushOnDisposeTest()
+ {
+ using (var writer = new StringWriter())
+ {
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("A");
+ }
+
+ Assert.Equal("A", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriterFlushOnDisposeWithFlushTest()
+ {
+ using (var writer = new StringWriter())
+ {
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("A");
+ csv.Flush();
+ }
+
+ Assert.Equal("A", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void DisposeShouldBeCallableMultipleTimes()
+ {
+ var parserMock = new ParserMock();
+ var reader = new CsvReader(parserMock);
+
+ reader.Dispose();
+ reader.Dispose();
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DynamicProxyTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DynamicProxyTests.cs
new file mode 100644
index 0000000..aa501f2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/DynamicProxyTests.cs
@@ -0,0 +1,65 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class DynamicProxyTests
+ {
+ [Fact]
+ public void WriteDynamicProxyObjectTest()
+ {
+ var list = new List<TestClass>();
+ var proxyGenerator = new Castle.DynamicProxy.ProxyGenerator();
+ for (var i = 0; i < 1; i++)
+ {
+ var proxy = proxyGenerator.CreateClassProxy<TestClass>();
+ proxy.Id = i + 1;
+ proxy.Name = "name" + proxy.Id;
+ list.Add(proxy);
+ }
+
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<TestClassMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var data = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("id,name");
+ expected.AppendLine("1,name1");
+
+ Assert.Equal(expected.ToString(), data);
+ }
+ }
+
+ public class TestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class TestClassMap : ClassMap<TestClass>
+ {
+ public TestClassMap()
+ {
+ Map(m => m.Id).Name("id");
+ Map(m => m.Name).Name("name");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/EnumerateRecordsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/EnumerateRecordsTests.cs
new file mode 100644
index 0000000..5afdd52
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/EnumerateRecordsTests.cs
@@ -0,0 +1,181 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+
+namespace CsvHelper.Tests
+{
+
+ public class EnumerateRecordsTests
+ {
+ [Fact]
+ public void BasicTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var record = new Basic
+ {
+ Id = -1,
+ Name = "-one"
+ };
+
+ var count = 1;
+ foreach (var r in csv.EnumerateRecords(record))
+ {
+ if (count == 1)
+ {
+ Assert.Equal(1, r.Id);
+ Assert.Equal("one", r.Name);
+ }
+ else if (count == 2)
+ {
+ Assert.Equal(2, r.Id);
+ Assert.Equal("two", r.Name);
+ }
+
+ count++;
+ }
+ }
+ }
+
+ [Fact]
+ public void UnUsedPropertyTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var record = new UnUsedProperty
+ {
+ Id = -1,
+ Name = "-one",
+ UnUsed = "nothing",
+ };
+
+ var count = 1;
+ foreach (var r in csv.EnumerateRecords(record))
+ {
+ if (count == 1)
+ {
+ Assert.Equal(1, r.Id);
+ Assert.Equal("one", r.Name);
+ Assert.Equal("nothing", r.UnUsed);
+ }
+ else if (count == 2)
+ {
+ Assert.Equal(2, r.Id);
+ Assert.Equal("two", r.Name);
+ Assert.Equal("nothing", r.UnUsed);
+ }
+
+ count++;
+ }
+ }
+ }
+
+ [Fact]
+ public void ReferenceTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var record = new HasReferences
+ {
+ Id = -1,
+ Reference = new Reference
+ {
+ Name = "one"
+ }
+ };
+
+ var count = 1;
+ foreach (var r in csv.EnumerateRecords(record))
+ {
+ if (count == 1)
+ {
+ Assert.Equal(1, r.Id);
+ Assert.Equal("one", r.Reference.Name);
+ }
+ else if (count == 2)
+ {
+ Assert.Equal(2, r.Id);
+ Assert.Equal("two", r.Reference.Name);
+ }
+
+ count++;
+ }
+ }
+ }
+
+ private class Basic
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private class UnUsedProperty
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public string UnUsed { get; set; }
+ }
+
+ public class HasReferences
+ {
+ public int Id { get; set; }
+
+ public Reference Reference { get; set; }
+ }
+
+ public class Reference
+ {
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionMessageTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionMessageTests.cs
new file mode 100644
index 0000000..acf3c25
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionMessageTests.cs
@@ -0,0 +1,208 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.Exceptions
+{
+
+ public class ExceptionMessageTests
+ {
+ [Fact]
+ public void GetMissingFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+ var reader = new CsvReader(parser);
+ reader.Read();
+ reader.Read();
+ try
+ {
+ reader.GetField(2);
+ throw new XUnitException();
+ }
+ catch (MissingFieldException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(2, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetGenericMissingFieldWithTypeTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ reader.Read();
+ reader.Read();
+ try
+ {
+ reader.GetField<int>(2);
+ throw new XUnitException();
+ }
+ catch (MissingFieldException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(2, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetRecordGenericTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ reader.Read();
+ try
+ {
+ reader.GetRecord<Simple>();
+ throw new XUnitException();
+ }
+ catch (TypeConverterException ex)
+ {
+ //var expected = "Row: '2' (1 based)\r\n" +
+ // "Type: 'CsvHelper.Tests.Exceptions.ExceptionMessageTests+Simple'\r\n" +
+ // "Field Index: '0' (0 based)\r\n" +
+ // "Field Name: 'Id'\r\n" +
+ // "Field Value: 'a'\r\n";
+ //Assert.Equal( expected, ex.Data["CsvHelper"] );
+
+ Assert.Equal(2, ex.Context.Parser.Row);
+ //Assert.Equal( typeof( Simple ), ex.Type );
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetRecordTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ reader.Read();
+ try
+ {
+ reader.GetRecord(typeof(Simple));
+ throw new XUnitException();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetRecordsGenericTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ try
+ {
+ reader.GetRecords<Simple>().ToList();
+ throw new XUnitException();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetRecordsTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ try
+ {
+ reader.GetRecords(typeof(Simple)).ToList();
+ throw new XUnitException();
+ }
+ catch (TypeConverterException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ //Assert.Equal( typeof( Simple ), ex.Type );
+ Assert.Equal(0, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ [Fact]
+ public void GetFieldIndexTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "a", "b" },
+ null
+ };
+
+ var reader = new CsvReader(parser);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ try
+ {
+ reader.GetField("c");
+ throw new XUnitException();
+ }
+ catch (MissingFieldException ex)
+ {
+ Assert.Equal(2, ex.Context.Parser.Row);
+ Assert.Equal(-1, ex.Context.Reader.CurrentIndex);
+ }
+ }
+
+ private class Simple
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionTests.cs
new file mode 100644
index 0000000..bec1ee5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Exceptions/ExceptionTests.cs
@@ -0,0 +1,52 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Exceptions
+{
+
+ public class ExceptionTests
+ {
+ [Fact]
+ public void NoDefaultConstructorTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,2");
+ writer.WriteLine("3,4");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.Throws<MissingFieldException>(() => csv.GetRecords<NoDefaultConstructor>().ToList());
+ }
+ }
+
+ private class NoDefaultConstructor
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ public NoDefaultConstructor(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/HeaderValidationTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/HeaderValidationTests.cs
new file mode 100644
index 0000000..a1775ac
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/HeaderValidationTests.cs
@@ -0,0 +1,280 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace CsvHelper.Tests
+{
+
+ public class HeaderValidationTests
+ {
+ [Fact]
+ public void ValidateHeader_ValidHeaders_NoException()
+ {
+ using (var csv = new CsvReader(new StringReader("Id,Name"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ csv.ValidateHeader<Test>();
+ }
+ }
+
+ [Fact]
+ public void ValidateHeader_PropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ try
+ {
+ csv.ValidateHeader<Test>();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void ValidateHeader_ReferencePropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ try
+ {
+ csv.ValidateHeader<HasReference>();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void ValidateHeader_ConstructorParametersDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ try
+ {
+ csv.ValidateHeader<HasConstructor>();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetRecord_PropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ try
+ {
+ csv.GetRecord(typeof(Test));
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetRecordGeneric_PropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ try
+ {
+ csv.GetRecord<Test>();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetRecords_PropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ try
+ {
+ csv.GetRecords(typeof(Test)).ToList();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetRecordsGeneric_PropertiesDontMatch_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("bad data"), CultureInfo.InvariantCulture))
+ {
+ try
+ {
+ csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Equal(2, ex.InvalidHeaders.Length);
+ }
+ }
+ }
+
+ [Fact]
+ public void GetRecordsGeneric_PrivateSetter_NoException()
+ {
+ var data = new StringBuilder();
+ data.AppendLine("Number");
+ data.AppendLine("1");
+ using (var csv = new CsvReader(new StringReader(data.ToString()), CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<HasPrivateSetter>().ToList();
+ var record = records[0];
+ Assert.Equal(1, record.Number);
+ Assert.Equal(2, record.Double);
+ }
+ }
+
+ [Fact]
+ public void GetRecordsGeneric_IgnoreProperty_NoException()
+ {
+ var data = new StringBuilder();
+ data.AppendLine("Id");
+ data.AppendLine("1");
+ using (var csv = new CsvReader(new StringReader(data.ToString()), CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<HasIgnoredPropertyMap>();
+ var records = csv.GetRecords<Test>().ToList();
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Null(record.Name);
+ }
+ }
+
+ [Fact]
+ public void ValidateHeader_NoNamesMapped_NoException()
+ {
+ using (var csv = new CsvReader(new StringReader("Id"), CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<HasIndexNoNameMap>();
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.ValidateHeader<Test>();
+ }
+ }
+
+ [Fact]
+ public void ValidateHeader_HasIndexAndName_ThrowsHeaderValidationException()
+ {
+ using (var csv = new CsvReader(new StringReader("Id"), CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<HasIndexAndNameMap>();
+
+ csv.Read();
+ csv.ReadHeader();
+ try
+ {
+ csv.ValidateHeader<Test>();
+ throw new XUnitException();
+ }
+ catch (HeaderValidationException ex)
+ {
+ Assert.Single(ex.InvalidHeaders);
+ Assert.Equal("Name", ex.InvalidHeaders[0].Names[0]);
+ }
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private class HasReference
+ {
+ public Test Reference { get; set; }
+ }
+
+ private class HasConstructor
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public HasConstructor(int Id, string Name)
+ {
+ this.Id = Id;
+ this.Name = Name;
+ }
+ }
+
+ private class HasPrivateSetter
+ {
+ public int Number { get; set; }
+
+ public int Double => Number * 2;
+ }
+
+ private sealed class HasIgnoredPropertyMap : ClassMap<Test>
+ {
+ public HasIgnoredPropertyMap()
+ {
+ AutoMap(CultureInfo.InvariantCulture);
+ Map(m => m.Name).Ignore();
+ }
+ }
+
+ private sealed class HasIndexNoNameMap : ClassMap<Test>
+ {
+ public HasIndexNoNameMap()
+ {
+ Map(m => m.Id).Index(0);
+ Map(m => m.Name).Index(1);
+ }
+ }
+
+ private sealed class HasIndexAndNameMap : ClassMap<Test>
+ {
+ public HasIndexAndNameMap()
+ {
+ Map(m => m.Id).Index(0).Name("Id");
+ Map(m => m.Name).Index(1).Name("Name");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue1954.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue1954.cs
new file mode 100644
index 0000000..0fc4b55
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue1954.cs
@@ -0,0 +1,178 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.Issues
+{
+ public class Issue1954
+ {
+ [Fact]
+ public void Test1()
+ {
+ var data = @"field1, field2, field3
+1, 2, ""test""
+3, 4, ""TEST""";
+
+ var opts = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ TrimOptions = TrimOptions.Trim,
+ BufferSize = 44
+ };
+
+ using (var sr = new StringReader(data))
+ using (var csv = new CsvReader(sr, opts))
+ {
+ var records = csv.GetRecords<Row>().ToArray();
+
+ Assert.Equal(2, records.Length);
+
+ Assert.Equal(1, records[0].Field1);
+ Assert.Equal(2, records[0].Field2);
+ Assert.Equal("test", records[0].Field3);
+
+ Assert.Equal(3, records[1].Field1);
+ Assert.Equal(4, records[1].Field2);
+ Assert.Equal("TEST", records[1].Field3);
+ }
+ }
+
+ [Fact]
+ public void Test2()
+ {
+ var data = @"field1, field2, field3
+1, 2, ""test""
+3, 4, ""TEST""";
+
+ var opts = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ TrimOptions = TrimOptions.Trim,
+ BufferSize = 45
+ };
+
+ using (var sr = new StringReader(data))
+ using (var csv = new CsvReader(sr, opts))
+ {
+ var records = csv.GetRecords<Row>().ToArray();
+
+ Assert.Equal(2, records.Length);
+
+ Assert.Equal(1, records[0].Field1);
+ Assert.Equal(2, records[0].Field2);
+ Assert.Equal("test", records[0].Field3);
+
+ Assert.Equal(3, records[1].Field1);
+ Assert.Equal(4, records[1].Field2);
+ Assert.Equal("TEST", records[1].Field3);
+ }
+ }
+
+ [Fact]
+ public void Test3()
+ {
+ var data = @"field1, field2, field3
+1, 2, ""test""
+3, 4, ""TEST""";
+
+ var opts = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ TrimOptions = TrimOptions.Trim,
+ BufferSize = 44
+ };
+
+ using (var sr = new StringReader(data))
+ using (var csv = new CsvReader(sr, opts))
+ {
+ var records = csv.GetRecords<Row>().ToArray();
+
+ Assert.Equal(2, records.Length);
+
+ Assert.Equal(1, records[0].Field1);
+ Assert.Equal(2, records[0].Field2);
+ Assert.Equal("test", records[0].Field3);
+
+ Assert.Equal(3, records[1].Field1);
+ Assert.Equal(4, records[1].Field2);
+ Assert.Equal("TEST", records[1].Field3);
+ }
+ }
+
+ [Fact]
+ public void Test4()
+ {
+ var data = @"field1, field2, field3
+1, 2, ""test""
+3, 4,""TEST""";
+
+ var opts = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ TrimOptions = TrimOptions.Trim,
+ BufferSize = 44
+ };
+
+ using (var sr = new StringReader(data))
+ using (var csv = new CsvReader(sr, opts))
+ {
+ var records = csv.GetRecords<Row>().ToArray();
+
+ Assert.Equal(2, records.Length);
+
+ Assert.Equal(1, records[0].Field1);
+ Assert.Equal(2, records[0].Field2);
+ Assert.Equal("test", records[0].Field3);
+
+ Assert.Equal(3, records[1].Field1);
+ Assert.Equal(4, records[1].Field2);
+ Assert.Equal("TEST", records[1].Field3);
+ }
+ }
+
+ [Fact]
+ public void Test5()
+ {
+ var data = @"field1, field2, field3
+1, 2, ""test""
+3, 4, TEST";
+
+ var opts = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ",",
+ TrimOptions = TrimOptions.Trim,
+ BufferSize = 44
+ };
+
+ using (var sr = new StringReader(data))
+ using (var csv = new CsvReader(sr, opts))
+ {
+ var records = csv.GetRecords<Row>().ToArray();
+
+ Assert.Equal(2, records.Length);
+
+ Assert.Equal(1, records[0].Field1);
+ Assert.Equal(2, records[0].Field2);
+ Assert.Equal("test", records[0].Field3);
+
+ Assert.Equal(3, records[1].Field1);
+ Assert.Equal(4, records[1].Field2);
+ Assert.Equal("TEST", records[1].Field3);
+ }
+ }
+
+ private class Row
+ {
+ [Name("field1")] public int Field1 { get; set; }
+ [Name("field2")] public int Field2 { get; set; }
+ [Name("field3")] public string Field3 { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue920.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue920.cs
new file mode 100644
index 0000000..1ae38db
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Issues/Issue920.cs
@@ -0,0 +1,59 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+
+namespace CsvHelper.Tests.Issues
+{
+
+ public class Issue920
+ {
+ [Fact]
+ public void Test1()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ GetConstructor = args =>
+ args.ClassType.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)
+ .OrderBy(c => c.GetParameters().Length)
+ .First(),
+ IncludePrivateMembers = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("A,B");
+ writer.WriteLine("1,one");
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<Sample>().ToList();
+
+ Assert.Equal(2, records.Count);
+ }
+ }
+
+ private class Sample
+ {
+ public int A { get; private set; }
+ public string B { get; private set; }
+
+ private Sample() { }
+
+ public Sample(int a, string b)
+ {
+ A = a;
+ B = b;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/LocalCultureTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/LocalCultureTests.cs
new file mode 100644
index 0000000..f99540e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/LocalCultureTests.cs
@@ -0,0 +1,72 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class LocalCultureTests
+ {
+ // In 'uk-UA' decimal separator is the ','
+ // For 'Invariant' and many other cultures decimal separator is '.'
+
+ [Fact]
+ public void ReadRecordsTest()
+ {
+ const string source = "DateTimeColumn;DecimalColumn\r\n" +
+ "11.11.2010;12,0\r\n";
+
+ var configuration = new CsvHelper.Configuration.CsvConfiguration(new CultureInfo("uk-UA"))
+ {
+ Delimiter = ";",
+ };
+ var reader = new CsvReader(new CsvParser(new StringReader(source), configuration));
+
+ var records = reader.GetRecords<TestRecordWithDecimal>().ToList();
+
+ Assert.Single(records);
+ var record = records.First();
+ Assert.Equal(12.0m, record.DecimalColumn);
+ Assert.Equal(new DateTime(2010, 11, 11), record.DateTimeColumn);
+ }
+
+ [Fact]
+ public void WriteRecordsTest()
+ {
+ var records = new List<TestRecordWithDecimal>
+ {
+ new TestRecordWithDecimal
+ {
+ DecimalColumn = 12.0m,
+ DateTimeColumn = new DateTime( 2003, 1, 4, 15, 9, 26 )
+ }
+ };
+
+ var writer = new StringWriter();
+ var culture = new CultureInfo("uk-UA");
+ var csv = new CsvWriter(writer, new CsvHelper.Configuration.CsvConfiguration(culture) { Delimiter = ";" });
+
+ csv.WriteRecords(records);
+
+ var csvFile = writer.ToString();
+
+ const string expected = "DecimalColumn;DateTimeColumn\r\n" +
+ "12,0;04.01.2003 15:09:26\r\n";
+
+ Assert.Equal(expected, csvFile);
+ }
+
+ private class TestRecordWithDecimal
+ {
+ public decimal DecimalColumn { get; set; }
+ public DateTime DateTimeColumn { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MapPropertyMultipleTimesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MapPropertyMultipleTimesTests.cs
new file mode 100644
index 0000000..b330cd0
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MapPropertyMultipleTimesTests.cs
@@ -0,0 +1,87 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class MapPropertyMultipleTimesTests
+ {
+ [Fact]
+ public void MapPropertiesToMultipleFieldsWhenWritingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" }
+ };
+
+ csv.Context.RegisterClassMap<TestMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id1,Name1,Id2,Name2");
+ expected.AppendLine("1,one,1,one");
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void MapPropertiesToMultipleFieldsWhenReadingTest()
+ {
+ // This is not something that anyone should do, but this
+ // is the expected behavior if they do.
+
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id1,Name1,Id2,Name2");
+ writer.WriteLine("1,one,2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(2, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Id).Name("Id1");
+ Map(m => m.Name).Name("Name1");
+ Map(m => m.Id, false).Name("Id2");
+ Map(m => m.Name, false).Name("Name2");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MappingInheritedClassTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MappingInheritedClassTests.cs
new file mode 100644
index 0000000..82c5ef5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/MappingInheritedClassTests.cs
@@ -0,0 +1,42 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+
+namespace CsvHelper.Tests
+{
+
+ public class MappingInheritedClassTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var map = new AMap<A>();
+ Assert.Equal( 2, map.MemberMaps.Count );
+ }
+
+ private interface IA
+ {
+ int Id { get; set; }
+ }
+
+ private class A : IA
+ {
+ public int Id { get; set; }
+
+ public int Name { get; set; }
+ }
+
+ private sealed class AMap<T> : ClassMap<T> where T : IA
+ {
+ public AMap()
+ {
+ AutoMap(CultureInfo.InvariantCulture);
+ Map( m => m.Id );
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs
new file mode 100644
index 0000000..e5fb1eb
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/AllowCommentsTests.cs
@@ -0,0 +1,29 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class AllowCommentsTests
+ {
+ [Fact]
+ public void AllowCommentsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(AllowCommentsTestClass));
+ Assert.True(config.AllowComments);
+ }
+
+ [AllowComments(true)]
+ private class AllowCommentsTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BooleanValuesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BooleanValuesTests.cs
new file mode 100644
index 0000000..b2eefde
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BooleanValuesTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class BooleanValuesTests
+ {
+ [Fact]
+ public void BooleanValuesTest()
+ {
+ using (var reader = new StringReader("IsTrue,IsFalse\r\ntrue,false\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<BooleanValuesTestClass>().ToList();
+ Assert.Equal(true, records[0].IsTrue);
+ Assert.Equal(false, records[0].IsFalse);
+ }
+ }
+
+ private class BooleanValuesTestClass
+ {
+ [BooleanTrueValues("true")]
+ public bool? IsTrue { get; set; }
+
+ [BooleanFalseValues("false")]
+ public bool? IsFalse { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs
new file mode 100644
index 0000000..dd35498
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/BufferSizeTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class BufferSizeTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(2, config.BufferSize);
+ }
+
+ [BufferSize(2)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs
new file mode 100644
index 0000000..bfc1c52
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CacheFieldsTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class CacheFieldsTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.CacheFields);
+ }
+
+ [CacheFields(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs
new file mode 100644
index 0000000..64baf14
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CommentTests.cs
@@ -0,0 +1,28 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class CommentTests
+ {
+ [Fact]
+ public void CommentTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(CommentTestClass));
+ Assert.Equal('x', config.Comment);
+ }
+
+ [Comment('x')]
+ private class CommentTestClass
+ {
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ConstantTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ConstantTests.cs
new file mode 100644
index 0000000..5ab6381
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ConstantTests.cs
@@ -0,0 +1,50 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class ConstantTests
+ {
+ [Fact]
+ public void ConstantTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<ConstantTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void ConstantOnMissingFieldTest()
+ {
+ using (var reader = new StringReader("Id\r\n1\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<ConstantTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+ }
+ }
+
+ private class ConstantTestClass
+ {
+ public int Id { get; set; }
+
+ [Constant("two")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs
new file mode 100644
index 0000000..c4847cd
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/CountBytesTest.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class CountBytesTest
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.CountBytes);
+ }
+
+ [CountBytes(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DateTimeStylesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DateTimeStylesTests.cs
new file mode 100644
index 0000000..3e5a25d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DateTimeStylesTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class DateTimeStylesTests
+ {
+ [Fact]
+ public void DateTimeStylesTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<DateTimeStylesTestClass>().ToList();
+ var actual = csv.Context.Maps.Find<DateTimeStylesTestClass>().MemberMaps[1].Data.TypeConverterOptions.DateTimeStyle;
+
+ Assert.Equal(DateTimeStyles.AdjustToUniversal, actual);
+ }
+ }
+
+ private class DateTimeStylesTestClass
+ {
+ public int Id { get; set; }
+
+ [DateTimeStyles(DateTimeStyles.AdjustToUniversal)]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DefaultTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DefaultTests.cs
new file mode 100644
index 0000000..4718c66
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DefaultTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class DefaultTests
+ {
+ [Fact]
+ public void DefaultTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<DefaultTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class DefaultTestClass
+ {
+ public int Id { get; set; }
+
+ [Default("one")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs
new file mode 100644
index 0000000..3315126
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DelimiterTests.cs
@@ -0,0 +1,32 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class DelimiterTests
+ {
+ [Fact]
+ public void DelimiterReaderTest()
+ {
+ var configuration = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(DelimiterTestClass));
+
+ Assert.Equal("§", configuration.Delimiter);
+ }
+
+ [Delimiter("§")]
+ private class DelimiterTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs
new file mode 100644
index 0000000..4fad816
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectColumnCountChangesTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class DetectColumnCountChangesTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.DetectColumnCountChanges);
+ }
+
+ [DetectColumnCountChanges(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs
new file mode 100644
index 0000000..1ccc0fb
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class DetectDelimiterTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.DetectDelimiter);
+ }
+
+ [DetectDelimiter(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs
new file mode 100644
index 0000000..a160001
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/DetectDelimiterValuesTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class DetectDelimiterValuesTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(new[] { "a", "b" }, config.DetectDelimiterValues);
+ }
+
+ [DetectDelimiterValues("a b")]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs
new file mode 100644
index 0000000..557775b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EncodingTests.cs
@@ -0,0 +1,33 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class EncodingTests
+ {
+ [Fact]
+ public void EncodingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(EncodingTestClass));
+
+ Assert.Equal(Encoding.ASCII, config.Encoding);
+ }
+
+ [Encoding("ASCII")]
+ private class EncodingTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EnumIgnoreCaseTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EnumIgnoreCaseTests.cs
new file mode 100644
index 0000000..e12f3cd
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EnumIgnoreCaseTests.cs
@@ -0,0 +1,91 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class EnumIgnoreCaseTests
+ {
+ [Fact]
+ public void GetRecords_UsingEnumIgnoreCaseFromClassMap_ReadsEnumValueWithDifferentCasing()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Enum\r\n");
+ s.Append("1,one");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+ }
+ }
+
+ [Fact]
+ public void GetRecords_UsingEnumIgnoreCaseFromAttribute_ReadsEnumValueWithDifferentCasing()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Enum\r\n");
+ s.Append("1,one");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<Bar>().ToList();
+ }
+ }
+
+ [Fact]
+ public void GetRecords_UsingEnumIgnoreCaseFromGlobal_ReadsEnumValueWithDifferentCasing()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Enum\r\n");
+ s.Append("1,one");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Context.TypeConverterOptionsCache.AddOptions<TestEnum>(new TypeConverterOptions { EnumIgnoreCase = true });
+ var records = csv.GetRecords<Foo>().ToList();
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+ public TestEnum Enum { get; set; }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Enum).TypeConverterOption.EnumIgnoreCase();
+ }
+ }
+
+ private class Bar
+ {
+ public int Id { get; set; }
+ [EnumIgnoreCase]
+ public TestEnum Enum { get; set; }
+ }
+
+ private enum TestEnum
+ {
+ None = 0,
+ One = 1
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs
new file mode 100644
index 0000000..b3c3e7f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/EscapeTests.cs
@@ -0,0 +1,32 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class EscapeTests
+ {
+ [Fact]
+ public void EscapeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(EscapeTestClass));
+
+ Assert.Equal('x', config.Escape);
+ }
+
+ [Escape('x')]
+ private class EscapeTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs
new file mode 100644
index 0000000..ce3688e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ExceptionMessagesContainRawDataTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class ExceptionMessagesContainRawDataTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.False(config.ExceptionMessagesContainRawData);
+ }
+
+ [ExceptionMessagesContainRawData(false)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/FormatTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/FormatTests.cs
new file mode 100644
index 0000000..c2e2b5f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/FormatTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class FormatTests
+ {
+ [Fact]
+ public void FormatTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<FormatTestClass>().ToList();
+ var actual = csv.Context.Maps.Find<FormatTestClass>().MemberMaps[1].Data.TypeConverterOptions.Formats[0];
+
+ Assert.Equal("abc", actual);
+ }
+ }
+
+ private class FormatTestClass
+ {
+ public int Id { get; set; }
+
+ [Format("abc")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs
new file mode 100644
index 0000000..9fae872
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HasHeaderRecordTests.cs
@@ -0,0 +1,30 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class HasHeaderRecordTests
+ {
+ [Fact]
+ public void HasHeaderRecordTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(HasHeaderRecordTestClass));
+
+ Assert.False(config.HasHeaderRecord);
+ }
+
+ [HasHeaderRecord(false)]
+ private class HasHeaderRecordTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HeaderPrefixTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HeaderPrefixTests.cs
new file mode 100644
index 0000000..fe5cb61
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/HeaderPrefixTests.cs
@@ -0,0 +1,205 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class HeaderPrefixTests
+ {
+ [Fact]
+ public void WriteHeader_PrefixCustom_WritesCustomPrefixesOwnLevelOnly()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteHeader<ACustom>();
+ csv.Flush();
+
+ Assert.Equal("AId,b_BId,c_CId", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteHeader_PrefixInherit_WritesPrefixesForEachLevel()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteHeader<AInherit>();
+ csv.Flush();
+
+ Assert.Equal("AId,B.BId,B.C.CId", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteHeader_PrefixNoInherit_WritesPrefixesOwnLevelOnly()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteHeader<ANoInherit>();
+ csv.Flush();
+
+ Assert.Equal("AId,B.BId,C.CId", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteHeader_PrefixDefaultInherit_WritesPrefixesOwnLevelOnly()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteHeader<ADefaultInherit>();
+ csv.Flush();
+
+ Assert.Equal("AId,B.BId,C.CId", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void GetRecords_PrefixCustom_ReadsCustomHeader()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("AId,b_BId,c_CId");
+ s.AppendLine("aid,bid,cid");
+ using (var reader = new StringReader(s))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<ACustom>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal("aid", records[0].AId);
+ Assert.Equal("bid", records[0].B.BId);
+ Assert.Equal("cid", records[0].B.C.CId);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_PrefixInherit_ReadsInheritedHeader()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("AId,B.BId,B.C.CId");
+ s.AppendLine("aid,bid,cid");
+ using (var reader = new StringReader(s))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<AInherit>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal("aid", records[0].AId);
+ Assert.Equal("bid", records[0].B.BId);
+ Assert.Equal("cid", records[0].B.C.CId);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_PrefixNoInherit_ReadsNonInheritedHeader()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("AId,B.BId,C.CId");
+ s.AppendLine("aid,bid,cid");
+ using (var reader = new StringReader(s))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<ANoInherit>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal("bid", records[0].B.BId);
+ Assert.Equal("aid", records[0].AId);
+ Assert.Equal("cid", records[0].B.C.CId);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_PrefixDefaultInherit_ReadsNonInheritedHeader()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("AId,B.BId,C.CId");
+ s.AppendLine("aid,bid,cid");
+ using (var reader = new StringReader(s))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<ADefaultInherit>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal("aid", records[0].AId);
+ Assert.Equal("bid", records[0].B.BId);
+ Assert.Equal("cid", records[0].B.C.CId);
+ }
+ }
+
+ private class ACustom
+ {
+ public string AId { get; set; }
+ [HeaderPrefix("b_")]
+ public BCustom B { get; set; }
+ }
+
+ private class BCustom
+ {
+ public string BId { get; set; }
+ [HeaderPrefix("c_")]
+ public C C { get; set; }
+ }
+
+ private class AInherit
+ {
+ public string AId { get; set; }
+ [HeaderPrefix(true)]
+ public BInherit B { get; set; }
+ }
+
+ private class BInherit
+ {
+ public string BId { get; set; }
+ [HeaderPrefix(true)]
+ public C C { get; set; }
+ }
+
+ private class ANoInherit
+ {
+ public string AId { get; set; }
+ [HeaderPrefix(false)]
+ public BInherit B { get; set; }
+ }
+
+ private class BNoInherit
+ {
+ public string BId { get; set; }
+ [HeaderPrefix(false)]
+ public C C { get; set; }
+ }
+
+ private class ADefaultInherit
+ {
+ public string AId { get; set; }
+ [HeaderPrefix]
+ public BInherit B { get; set; }
+ }
+
+ private class BDefaultInherit
+ {
+ public string BId { get; set; }
+ [HeaderPrefix]
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string CId { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBaseTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBaseTests.cs
new file mode 100644
index 0000000..9f49082
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBaseTests.cs
@@ -0,0 +1,71 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class IgnoreBaseTests
+ {
+ [Fact]
+ public void GetRecordsWithProperties_IgnoreBaseAttribute_DoesNotMapBaseClass()
+ {
+ var map = new DefaultClassMap<ChildProperties>();
+ map.AutoMap(CultureInfo.InvariantCulture);
+
+ Assert.Single(map.MemberMaps);
+ Assert.Null(map.MemberMaps.Find<ChildProperties>(m => m.Id));
+ Assert.NotNull(map.MemberMaps.Find<ChildProperties>(m => m.Name));
+ }
+
+ [Fact]
+ public void GetRecordsWithFields_IgnoreBaseAttribute_DoesNotMapBaseClass()
+ {
+ var map = new DefaultClassMap<ChildFields>();
+ map.AutoMap(new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Fields,
+ });
+
+ Assert.Single(map.MemberMaps);
+ Assert.Null(map.MemberMaps.Find<ChildFields>(m => m.Id));
+ Assert.NotNull(map.MemberMaps.Find<ChildFields>(m => m.Name));
+ }
+
+ private class ParentProperties
+ {
+ public int Id { get; set; }
+ }
+
+ [IgnoreBase]
+ private class ChildProperties : ParentProperties
+ {
+ public string Name { get; set; }
+ }
+
+ private class ParentFields
+ {
+#pragma warning disable CS0649
+ public int Id;
+#pragma warning restore CS0649
+ }
+
+ [IgnoreBase]
+ private class ChildFields: ParentFields
+ {
+#pragma warning disable CS0649
+ public string Name;
+#pragma warning restore CS0649
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs
new file mode 100644
index 0000000..b2ec8e0
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreBlankLinesTests.cs
@@ -0,0 +1,36 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class IgnoreBlankLinesTests
+ {
+ [Fact]
+ public void IgnoreBlankLinesTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<IgnoreBlankLinesTestClass>().ToList();
+ var actual = csv.Configuration.IgnoreBlankLines;
+
+ Assert.True(actual);
+ }
+ }
+
+ [IgnoreBlankLines(true)]
+ private class IgnoreBlankLinesTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs
new file mode 100644
index 0000000..f2839b6
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreReferencesTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class IgnoreReferencesTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.IgnoreReferences);
+ }
+
+ [IgnoreReferences(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreTests.cs
new file mode 100644
index 0000000..4849ad1
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IgnoreTests.cs
@@ -0,0 +1,93 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class IgnoreTests
+ {
+ [Fact]
+ public void IgnoreTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void IgnoreReferenceTest()
+ {
+ var records = new List<Parent>
+ {
+ new Parent
+ {
+ Id = 1,
+ Child = new Child
+ {
+ Name = "one",
+ GrandChild = new GrandChild
+ {
+ Date = DateTimeOffset.Now
+ }
+ }
+ }
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+
+ [CsvHelper.Configuration.Attributes.Ignore]
+ public DateTime Date { get; set; }
+ }
+
+ private class Parent
+ {
+ public int Id { get; set; }
+
+ [CsvHelper.Configuration.Attributes.Ignore]
+ public Child Child { get; set; }
+ }
+
+ private class Child
+ {
+ public string Name { get; set; }
+
+ public GrandChild GrandChild { get; set; }
+ }
+
+ private class GrandChild
+ {
+ public DateTimeOffset Date { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs
new file mode 100644
index 0000000..2b219dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IncludePrivateMembersTests.cs
@@ -0,0 +1,29 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class IncludePrivateMembersTests
+ {
+ [Fact]
+ public void TrimOptionsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(IncludePrivateMembersTestClass));
+ Assert.True(config.IncludePrivateMembers);
+ }
+
+ [IncludePrivateMembers(true)]
+ private class IncludePrivateMembersTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IndexTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IndexTests.cs
new file mode 100644
index 0000000..1dc9112
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/IndexTests.cs
@@ -0,0 +1,42 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class IndexTests
+ {
+ [Fact]
+ public void IndexTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var reader = new StringReader("a,1,b,one,c\r\n"))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<IndexTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class IndexTestClass
+ {
+ [Index(1)]
+ public int Id { get; set; }
+
+ [Index(3)]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs
new file mode 100644
index 0000000..b4fc82c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionCharactersTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class InjectionCharactersTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(new[] { 'a', 'b' }, config.InjectionCharacters);
+ }
+
+ [InjectionCharacters("a b")]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs
new file mode 100644
index 0000000..e118ea2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionEscapeCharacterTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class InjectionEscapeCharacterTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal('a', config.InjectionEscapeCharacter);
+ }
+
+ [InjectionEscapeCharacter('a')]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs
new file mode 100644
index 0000000..7a03003
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/InjectionOptionsTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class InjectionOptionsTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(InjectionOptions.Escape, config.InjectionOptions);
+ }
+
+ [InjectionOptions(InjectionOptions.Escape)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs
new file mode 100644
index 0000000..b939780
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/LineBreakInQuotedFieldIsBadDataTests.cs
@@ -0,0 +1,25 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class LineBreakInQuotedFieldIsBadDataTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.True(config.LineBreakInQuotedFieldIsBadData);
+ }
+
+ [LineBreakInQuotedFieldIsBadData(true)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs
new file mode 100644
index 0000000..b0a9231
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MaxFieldSizeTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class MaxFieldSizeTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(2, config.MaxFieldSize);
+ }
+
+ [MaxFieldSize(2)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs
new file mode 100644
index 0000000..be21b32
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/MemberTypesTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class MemberTypesTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(MemberTypes.Fields, config.MemberTypes);
+ }
+
+ [MemberTypes(MemberTypes.Fields)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs
new file mode 100644
index 0000000..ca35863
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ModeTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class ModeTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(CsvMode.Escape, config.Mode);
+ }
+
+ [Mode(CsvMode.Escape)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameIndexTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameIndexTests.cs
new file mode 100644
index 0000000..07cda20
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameIndexTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class NameIndexTests
+ {
+ [Fact]
+ public void NameIndexTest()
+ {
+ using (var reader = new StringReader("Id,Name,Name\r\n1,one,two\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<NameIndexClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+ }
+ }
+
+ private class NameIndexClass
+ {
+ public int Id { get; set; }
+
+ [NameIndex(1)]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameTests.cs
new file mode 100644
index 0000000..3957442
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NameTests.cs
@@ -0,0 +1,38 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class NameTests
+ {
+ [Fact]
+ public void NameTest()
+ {
+ using (var reader = new StringReader("id,name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<NameTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class NameTestClass
+ {
+ [Name("id")]
+ public int Id { get; set; }
+
+ [Name("name")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs
new file mode 100644
index 0000000..5d9ba80
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NewLineTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class NewLineTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal("a", config.NewLine);
+ }
+
+ [NewLine("a")]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NullValuesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NullValuesTests.cs
new file mode 100644
index 0000000..8694172
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NullValuesTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class NullValuesTests
+ {
+ [Fact]
+ public void NullValuesTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\nNULL,null\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<NullValuesTestClass>().ToList();
+ Assert.Null(records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ private class NullValuesTestClass
+ {
+ [NullValues("NULL")]
+ public int? Id { get; set; }
+
+ [NullValues("null")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NumberStylesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NumberStylesTests.cs
new file mode 100644
index 0000000..3740f54
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/NumberStylesTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class NumberStylesTests
+ {
+ [Fact]
+ public void DateTimeStylesTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<NumberStylesTestClass>().ToList();
+ var actual = csv.Context.Maps.Find<NumberStylesTestClass>().MemberMaps[1].Data.TypeConverterOptions.NumberStyles;
+
+ Assert.Equal(NumberStyles.AllowCurrencySymbol, actual);
+ }
+ }
+
+ private class NumberStylesTestClass
+ {
+ public int Id { get; set; }
+
+ [NumberStyles(NumberStyles.AllowCurrencySymbol)]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/OptionalTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/OptionalTests.cs
new file mode 100644
index 0000000..466e6b5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/OptionalTests.cs
@@ -0,0 +1,41 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class OptionalTests
+ {
+ [Fact]
+ public void OptionalTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<OptionalTestClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ private class OptionalTestClass
+ {
+ public int Id { get; set; }
+
+ [Optional]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs
new file mode 100644
index 0000000..63ea433
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ProcessFieldBufferSizeTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class ProcessFieldBufferSizeTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(2, config.ProcessFieldBufferSize);
+ }
+
+ [ProcessFieldBufferSize(2)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs
new file mode 100644
index 0000000..3b6fb41
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/QuoteTests.cs
@@ -0,0 +1,29 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class QuoteTests
+ {
+ [Fact]
+ public void QuoteTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(QuoteTestClass));
+ Assert.Equal('x', config.Quote);
+ }
+
+ [Quote('x')]
+ private class QuoteTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ReferenceTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ReferenceTests.cs
new file mode 100644
index 0000000..97c64a0
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/ReferenceTests.cs
@@ -0,0 +1,43 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration.Attributes;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class ReferenceTests
+ {
+ [Fact]
+ public void ReferenceTest()
+ {
+ using (var reader = new StringReader("id,name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<ReferenceTestClassA>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].B.Name);
+ }
+ }
+
+ private class ReferenceTestClassA
+ {
+ [Name("id")]
+ public int Id { get; set; }
+
+ public ReferenceTestClassB B { get; set; }
+ }
+
+ private class ReferenceTestClassB
+ {
+ [Name("name")]
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs
new file mode 100644
index 0000000..6e7595f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TrimOptionsTests.cs
@@ -0,0 +1,31 @@
+// Copyright 2009-2015 Josh Close and Contributors
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// http://csvhelper.com
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.AttributeMapping
+{
+ public class TrimOptionsTests
+ {
+ [Fact]
+ public void TrimOptionsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(TrimOptionsTestClass));
+ Assert.Equal(TrimOptions.InsideQuotes, config.TrimOptions);
+ }
+
+ [TrimOptions(TrimOptions.InsideQuotes)]
+ private class TrimOptionsTestClass
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TypeConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TypeConverterTests.cs
new file mode 100644
index 0000000..afa2cd9
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/TypeConverterTests.cs
@@ -0,0 +1,125 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+
+ public class TypeConverterTests
+ {
+ [Fact]
+ public void TypeConverterTest()
+ {
+ using (var reader = new StringReader("Id,Name\r\n1,one\r\n"))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ var records = csv.GetRecords<TypeConverterClass>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void TypeConverterOnClassReferenceTest()
+ {
+ var records = new List<AClass>
+ {
+ new AClass { Id = 1, Name = new BClass() },
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = "Id,Name\r\n1,two\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void TypeConverterOnStructReferenceTest()
+ {
+ var records = new List<AStruct>
+ {
+ new AStruct { Id = 1, Name = new BStruct() },
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = "Id,Name\r\n1,two\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void Constructor_TypeConverterWithConstructorArgs_Creates()
+ {
+ var attribute = new TypeConverterAttribute(typeof(TypeConverterWithConstructorArgs), 2);
+ Assert.IsType<TypeConverterWithConstructorArgs>(attribute.TypeConverter);
+ Assert.Equal(2, ((TypeConverterWithConstructorArgs)attribute.TypeConverter).Value);
+ }
+
+ private class TypeConverterClass
+ {
+ public int Id { get; set; }
+
+ [TypeConverter(typeof(StringTypeConverter))]
+ public string Name { get; set; }
+ }
+
+ private class StringTypeConverter : ITypeConverter
+ {
+ public object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
+ {
+ return "two";
+ }
+
+ public string ConvertToString(object value, IWriterRow row, MemberMapData memberMapData)
+ {
+ return "two";
+ }
+ }
+
+ private class AClass
+ {
+ public int Id { get; set; }
+ [TypeConverter(typeof(StringTypeConverter))]
+ public BClass Name { get; set; }
+ }
+
+ private class BClass { }
+
+ private class AStruct
+ {
+ public int Id { get; set; }
+ [TypeConverter(typeof(StringTypeConverter))]
+ public BStruct Name { get; set; }
+ }
+
+ private class BStruct { }
+
+ private class TypeConverterWithConstructorArgs : DefaultTypeConverter
+ {
+ public int Value { get; private set; }
+
+ public TypeConverterWithConstructorArgs(int value)
+ {
+ Value = value;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs
new file mode 100644
index 0000000..d560872
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/UseNewObjectForNullReferenceMembersTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class UseNewObjectForNullReferenceMembersTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.False(config.UseNewObjectForNullReferenceMembers);
+ }
+
+ [UseNewObjectForNullReferenceMembers(false)]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs
new file mode 100644
index 0000000..3abb027
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Attribute/WhiteSpaceCharsTests.cs
@@ -0,0 +1,20 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings.Attribute
+{
+ public class WhiteSpaceCharsTests
+ {
+ [Fact]
+ public void ConstructorAttributeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture, typeof(Foo));
+ Assert.Equal(new[] { 'a', 'b' }, config.WhiteSpaceChars);
+ }
+
+ [WhiteSpaceChars("a b")]
+ private class Foo { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesAttributeTests.cs
new file mode 100644
index 0000000..d05b601
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesAttributeTests.cs
@@ -0,0 +1,110 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class BooleanFalseValuesAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanFalseValuesAttribute_CreatesParameterMaps()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Empty(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "boolean" },
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.False(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.False(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanFalseValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, false),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Boolean\r\n");
+ expected.Append("1,False\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public bool Boolean { get; private set; }
+
+ public Foo(int id, [BooleanFalseValues("Bar")] bool boolean)
+ {
+ Id = id;
+ Boolean = boolean;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesMapTests.cs
new file mode 100644
index 0000000..c477a17
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanFalseValuesMapTests.cs
@@ -0,0 +1,125 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class BooleanFalseValuesMapTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanFalseValuesAttribute_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("boolean").TypeConverterOption.BooleanValues(false, true, "Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Empty(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "boolean" },
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.False(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.False(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanFalseValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, false),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Boolean\r\n");
+ expected.Append("1,False\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public bool Boolean { get; private set; }
+
+ public Foo(int id, bool boolean)
+ {
+ Id = id;
+ Boolean = boolean;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Boolean);
+ Parameter("id");
+ Parameter("boolean").TypeConverterOption.BooleanValues(false, true, "Bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesAttributeTests.cs
new file mode 100644
index 0000000..4149e9d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesAttributeTests.cs
@@ -0,0 +1,110 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class BooleanTrueValuesAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanTrueValuesAttribute_CreatesParameterMaps()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanTrueValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "boolean" },
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.True(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanTrueValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.True(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanTrueValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, true),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Boolean\r\n");
+ expected.Append("1,True\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public bool Boolean { get; private set; }
+
+ public Foo(int id, [BooleanTrueValues("Bar")]bool boolean)
+ {
+ Id = id;
+ Boolean = boolean;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesMapTests.cs
new file mode 100644
index 0000000..318b439
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/BooleanTrueValuesMapTests.cs
@@ -0,0 +1,125 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class BooleanTrueValuesMapTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanFalseValuesAttribute_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("boolean").TypeConverterOption.BooleanValues(true, true, "Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues);
+ Assert.Empty(map.ParameterMaps[1].Data.TypeConverterOptions.BooleanFalseValues);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.TypeConverterOptions.BooleanTrueValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "boolean" },
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.True(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "Bar" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.True(records[0].Boolean);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanFalseValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, true),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Boolean\r\n");
+ expected.Append("1,True\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public bool Boolean { get; private set; }
+
+ public Foo(int id, bool boolean)
+ {
+ Id = id;
+ Boolean = boolean;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Boolean);
+ Parameter("id");
+ Parameter("boolean").TypeConverterOption.BooleanValues(true, true, "Bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantAttributeTests.cs
new file mode 100644
index 0000000..bf42bdc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantAttributeTests.cs
@@ -0,0 +1,109 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class ConstantAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithConstantAttributes_ConfiguresParameterMaps()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsConstantSet);
+ Assert.Null(map.ParameterMaps[0].Data.Constant);
+ Assert.True(map.ParameterMaps[1].Data.IsConstantSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Constant);
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithConstantAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [Constant("Bar")] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantMapTests.cs
new file mode 100644
index 0000000..523f383
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/ConstantMapTests.cs
@@ -0,0 +1,193 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class ConstantMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").Constant("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsConstantSet);
+ Assert.True(map.ParameterMaps[1].Data.IsConstantSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Constant);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Constant("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsConstantSet);
+ Assert.True(map.ParameterMaps[1].Data.IsConstantSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Constant);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).Constant("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsConstantSet);
+ Assert.True(map.ParameterMaps[1].Data.IsConstantSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Constant);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_FieldMissing_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_FieldMissing_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").Constant("Bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs
new file mode 100644
index 0000000..a76883d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoAttributeTests.cs
@@ -0,0 +1,119 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Threading;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class CultureInfoAttributeTests
+ {
+ private const decimal AMOUNT = 123_456.789M;
+ private const string CULTURE = "fr-FR";
+ private readonly string amount = AMOUNT.ToString(new CultureInfo(CULTURE));
+
+ [Fact]
+ public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.CultureInfo);
+ Assert.Equal(new CultureInfo(CULTURE), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "amount" },
+ { "1", amount },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(AMOUNT, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", amount },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(AMOUNT, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, AMOUNT),
+ };
+
+ var prevCulture = Thread.CurrentThread.CurrentCulture;
+ try {
+ Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Amount\r\n");
+ expected.Append($"1,{AMOUNT}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ } finally {
+ Thread.CurrentThread.CurrentCulture = prevCulture;
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public decimal Amount { get; private set; }
+
+ public Foo(int id, [CultureInfo(CULTURE)] decimal amount)
+ {
+ Id = id;
+ Amount = amount;
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoMapTests.cs
new file mode 100644
index 0000000..71ae189
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/CultureInfoMapTests.cs
@@ -0,0 +1,160 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Threading;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class CultureInfoMapTests
+ {
+ private const decimal AMOUNT = 123_456.789M;
+ private const string CULTURE = "fr-FR";
+ private readonly string amount = AMOUNT.ToString(new CultureInfo(CULTURE));
+
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("amount").TypeConverterOption.CultureInfo(new CultureInfo(CULTURE));
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.CultureInfo);
+ Assert.Equal(new CultureInfo(CULTURE), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "amount").TypeConverterOption.CultureInfo(new CultureInfo(CULTURE));
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.CultureInfo);
+ Assert.Equal(new CultureInfo(CULTURE), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).TypeConverterOption.CultureInfo(new CultureInfo(CULTURE));
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.CultureInfo);
+ Assert.Equal(new CultureInfo(CULTURE), map.ParameterMaps[1].Data.TypeConverterOptions.CultureInfo);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "amount" },
+ { "1", amount },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(AMOUNT, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", amount },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(AMOUNT, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, AMOUNT),
+ };
+
+ var prevCulture = Thread.CurrentThread.CurrentCulture;
+ try {
+ Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Amount\r\n");
+ expected.Append($"1,{AMOUNT}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ } finally {
+ Thread.CurrentThread.CurrentCulture = prevCulture;
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public decimal Amount { get; private set; }
+
+ public Foo(int id, decimal amount)
+ {
+ Id = id;
+ Amount = amount;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Amount);
+ Parameter("id");
+ Parameter("amount").TypeConverterOption.CultureInfo(new CultureInfo(CULTURE));
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesAttributeTests.cs
new file mode 100644
index 0000000..7207853
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesAttributeTests.cs
@@ -0,0 +1,109 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class DateTimeStylesAttributeTests
+ {
+ private const string DATE = "12/25/2020";
+ private readonly DateTimeOffset date = DateTimeOffset.Parse(DATE, CultureInfo.InvariantCulture);
+
+ [Fact]
+ public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.DateTimeStyle);
+ Assert.Equal(DateTimeStyles.AllowLeadingWhite, map.ParameterMaps[1].Data.TypeConverterOptions.DateTimeStyle);
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "date" },
+ { "1", $" {DATE}" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", $" {DATE}" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, date),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Date\r\n");
+ expected.Append($"1,{date.ToString(null, CultureInfo.InvariantCulture)}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public DateTimeOffset Date { get; private set; }
+
+ public Foo(int id, [DateTimeStyles(DateTimeStyles.AllowLeadingWhite)] DateTimeOffset date)
+ {
+ Id = id;
+ Date = date;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesMapTests.cs
new file mode 100644
index 0000000..d94b75f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DateTimeStylesMapTests.cs
@@ -0,0 +1,152 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class DateTimeStylesMapTests
+ {
+ private const string DATE = "12/25/2020";
+ private readonly DateTimeOffset date = DateTimeOffset.Parse(DATE, CultureInfo.InvariantCulture);
+
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("date").TypeConverterOption.DateTimeStyles(DateTimeStyles.AllowLeadingWhite);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.DateTimeStyle);
+ Assert.Equal(DateTimeStyles.AllowLeadingWhite, map.ParameterMaps[1].Data.TypeConverterOptions.DateTimeStyle);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "date").TypeConverterOption.DateTimeStyles(DateTimeStyles.AllowLeadingWhite);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.DateTimeStyle);
+ Assert.Equal(DateTimeStyles.AllowLeadingWhite, map.ParameterMaps[1].Data.TypeConverterOptions.DateTimeStyle);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).TypeConverterOption.DateTimeStyles(DateTimeStyles.AllowLeadingWhite);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.DateTimeStyle);
+ Assert.Equal(DateTimeStyles.AllowLeadingWhite, map.ParameterMaps[1].Data.TypeConverterOptions.DateTimeStyle);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "date" },
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, date),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Date\r\n");
+ expected.Append($"1,{date.ToString(null, CultureInfo.InvariantCulture)}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public DateTimeOffset Date { get; private set; }
+
+ public Foo(int id, DateTimeOffset date)
+ {
+ Id = id;
+ Date = date;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Date);
+ Parameter("id");
+ Parameter("date").TypeConverterOption.DateTimeStyles(DateTimeStyles.AllowLeadingWhite);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultAttributeTests.cs
new file mode 100644
index 0000000..226878d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultAttributeTests.cs
@@ -0,0 +1,108 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class DefaultAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithDefaultAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsDefaultSet);
+ Assert.Null(map.ParameterMaps[0].Data.Default);
+ Assert.True(map.ParameterMaps[1].Data.IsDefaultSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Default);
+ }
+
+ [Fact]
+ public void GetRecords_WithDefaultAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithDefaultAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithDefaultAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [Default("Bar")] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultMapTests.cs
new file mode 100644
index 0000000..3b6f76d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/DefaultMapTests.cs
@@ -0,0 +1,152 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class DefaultMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").Default("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsDefaultSet);
+ Assert.True(map.ParameterMaps[1].Data.IsDefaultSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Default);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Default("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsDefaultSet);
+ Assert.True(map.ParameterMaps[1].Data.IsDefaultSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Default);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).Default("Bar");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsDefaultSet);
+ Assert.True(map.ParameterMaps[1].Data.IsDefaultSet);
+ Assert.Equal("Bar", map.ParameterMaps[1].Data.Default);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").Default("Bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/EnumIgnoreCaseTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/EnumIgnoreCaseTests.cs
new file mode 100644
index 0000000..af23233
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/EnumIgnoreCaseTests.cs
@@ -0,0 +1,113 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class EnumIgnoreCaseTests
+ {
+ [Fact]
+ public void AutoMap_WithEnumIgnoreCaseAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("id", map.ParameterMaps[0].Data.Names.First());
+ Assert.Equal("bar", map.ParameterMaps[1].Data.Names.First());
+ Assert.True(map.ParameterMaps[1].Data.TypeConverterOptions.EnumIgnoreCase.GetValueOrDefault());
+ }
+
+ [Fact]
+ public void GetRecords_WithEnumIgnoreCaseAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "bar" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(Bar.One, records[0].Bar);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithEnumIgnoreCaseAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(Bar.One, records[0].Bar);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithIgnoreAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, Bar.None),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Bar\r\n");
+ expected.Append("1,None\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public Bar Bar { get; private set; }
+
+ public Foo(int id, [EnumIgnoreCase] Bar bar)
+ {
+ Id = id;
+ Bar = bar;
+ }
+ }
+
+ private enum Bar
+ {
+ None = 0,
+ One = 1
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatAttributeTests.cs
new file mode 100644
index 0000000..b3fa1ac
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatAttributeTests.cs
@@ -0,0 +1,111 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class FormatAttributeTests
+ {
+ private const string FORMAT = "MM|dd|yyyy";
+ private const string DATE = "12|25|2020";
+ private readonly DateTimeOffset date = DateTimeOffset.ParseExact(DATE, FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None);
+
+ [Fact]
+ public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.Formats);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.Formats);
+ Assert.Equal(FORMAT, map.ParameterMaps[1].Data.TypeConverterOptions.Formats[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "date" },
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, date),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Date\r\n");
+ expected.Append($"1,{date.ToString(null, CultureInfo.InvariantCulture)}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public DateTimeOffset Date { get; private set; }
+
+ public Foo(int id, [Format(FORMAT)] DateTimeOffset date)
+ {
+ Id = id;
+ Date = date;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatMapTests.cs
new file mode 100644
index 0000000..673a1f7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/FormatMapTests.cs
@@ -0,0 +1,156 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class FormatMapTests
+ {
+ private const string FORMAT = "MM|dd|yyyy";
+ private const string DATE = "12|25|2020";
+ private readonly DateTimeOffset date = DateTimeOffset.ParseExact(DATE, FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None);
+
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("date").TypeConverterOption.Format(FORMAT);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.Formats);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.Formats);
+ Assert.Equal(FORMAT, map.ParameterMaps[1].Data.TypeConverterOptions.Formats[0]);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "date").TypeConverterOption.Format(FORMAT);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.Formats);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.Formats);
+ Assert.Equal(FORMAT, map.ParameterMaps[1].Data.TypeConverterOptions.Formats[0]);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).TypeConverterOption.Format(FORMAT);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.Formats);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.Formats);
+ Assert.Equal(FORMAT, map.ParameterMaps[1].Data.TypeConverterOptions.Formats[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "date" },
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", DATE },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(date, records[0].Date);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, date),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Date\r\n");
+ expected.Append($"1,{date.ToString(null, CultureInfo.InvariantCulture)}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public DateTimeOffset Date { get; private set; }
+
+ public Foo(int id, DateTimeOffset date)
+ {
+ Id = id;
+ Date = date;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Date);
+ Parameter("id");
+ Parameter("date").TypeConverterOption.Format(FORMAT);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixAttributeTests.cs
new file mode 100644
index 0000000..051f9f5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixAttributeTests.cs
@@ -0,0 +1,111 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class HeaderPrefixAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].ReferenceMap);
+ Assert.Equal("Bar_", map.ParameterMaps[1].ReferenceMap.Data.Prefix);
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "Bar_Name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Bar.Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Bar.Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, new Bar { Name = "one" }),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public Bar Bar { get; private set; }
+
+ public Foo(int id, [HeaderPrefix("Bar_")]Bar bar)
+ {
+ Id = id;
+ Bar = bar;
+ }
+ }
+
+ private class Bar
+ {
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixMapTests.cs
new file mode 100644
index 0000000..4c5e0be
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/HeaderPrefixMapTests.cs
@@ -0,0 +1,6 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+
+// It doesn't make sense to map a prefix as you would just set the header name you want including the prefix.
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreAttributeTests.cs
new file mode 100644
index 0000000..3ee4cd9
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreAttributeTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class IgnoreAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithIgnoreAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("id", map.ParameterMaps[0].Data.Names.First());
+ Assert.Equal("name", map.ParameterMaps[1].Data.Names.First());
+ Assert.True(map.ParameterMaps[1].Data.Ignore);
+ }
+
+ [Fact]
+ public void GetRecords_WithIgnoreAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithIgnoreAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithIgnoreAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [CsvHelper.Configuration.Attributes.Ignore] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreMapTests.cs
new file mode 100644
index 0000000..247f4ab
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IgnoreMapTests.cs
@@ -0,0 +1,150 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class IgnoreMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").Ignore();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.Ignore);
+ Assert.True(map.ParameterMaps[1].Data.Ignore);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Ignore();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.Ignore);
+ Assert.True(map.ParameterMaps[1].Data.Ignore);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).Ignore();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.Ignore);
+ Assert.True(map.ParameterMaps[1].Data.Ignore);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").Ignore();
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexAttributeTests.cs
new file mode 100644
index 0000000..b2a236c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexAttributeTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class IndexAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithIndexAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.Index);
+ Assert.Equal(1, map.ParameterMaps[1].Data.Index);
+ }
+
+ [Fact]
+ public void GetRecords_WithIndexAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithIndexAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithIndexAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo([Index(0)] int id, [Index(1)] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexMapTests.cs
new file mode 100644
index 0000000..fcb4c6e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/IndexMapTests.cs
@@ -0,0 +1,149 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class IndexMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id").Index(0);
+ map.Parameter("name").Index(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.Index);
+ Assert.Equal(1, map.ParameterMaps[1].Data.Index);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id").Index(0);
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Index(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.Index);
+ Assert.Equal(1, map.ParameterMaps[1].Data.Index);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]).Index(0);
+ map.Parameter(constructor, parameters[1]).Index(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.Index);
+ Assert.Equal(1, map.ParameterMaps[1].Data.Index);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id").Index(0);
+ Parameter("name").Index(1);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameAttributeTests.cs
new file mode 100644
index 0000000..25c3586
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameAttributeTests.cs
@@ -0,0 +1,85 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NameAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithNameAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("Id", map.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ParameterMaps[1].Data.Names[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithNameAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithNameAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo([Name("Id")] int id, [Name("Name")] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexAttributeTests.cs
new file mode 100644
index 0000000..55f009f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexAttributeTests.cs
@@ -0,0 +1,85 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NameIndexAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithNameAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.NameIndex);
+ Assert.Equal(1, map.ParameterMaps[1].Data.NameIndex);
+ }
+
+ [Fact]
+ public void GetRecords_WithNameAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name", "Name" },
+ { "1", "", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithNameAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo([Name("Id")]int id, [Name("Name")][NameIndex(1)] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexMapTests.cs
new file mode 100644
index 0000000..5c8ed87
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameIndexMapTests.cs
@@ -0,0 +1,126 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NameIndexMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id").NameIndex(0);
+ map.Parameter("name").NameIndex(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.NameIndex);
+ Assert.Equal(1, map.ParameterMaps[1].Data.NameIndex);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id").NameIndex(0);
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").NameIndex(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.NameIndex);
+ Assert.Equal(1, map.ParameterMaps[1].Data.NameIndex);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]).NameIndex(0);
+ map.Parameter(constructor, parameters[1]).NameIndex(1);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal(0, map.ParameterMaps[0].Data.NameIndex);
+ Assert.Equal(1, map.ParameterMaps[1].Data.NameIndex);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name", "Name" },
+ { "1", "", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id").Name("Id");
+ Parameter("name").Name("Name").NameIndex(1);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameMapTests.cs
new file mode 100644
index 0000000..0413be7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NameMapTests.cs
@@ -0,0 +1,126 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NameMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id").Name("Id");
+ map.Parameter("name").Name("Name");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("Id", map.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ParameterMaps[1].Data.Names[0]);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id").Name("Id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Name("Name");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("Id", map.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ParameterMaps[1].Data.Names[0]);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]).Name("Id");
+ map.Parameter(constructor, parameters[1]).Name("Name");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Equal("Id", map.ParameterMaps[0].Data.Names[0]);
+ Assert.Equal("Name", map.ParameterMaps[1].Data.Names[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id").Name("Id");
+ Parameter("name").Name("Name");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesAttributeTests.cs
new file mode 100644
index 0000000..0f9dd76
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesAttributeTests.cs
@@ -0,0 +1,107 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NullValuesAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanFalseValuesAttribute_CreatesParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.NullValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.NullValues);
+ Assert.Equal("NULL", map.ParameterMaps[1].Data.TypeConverterOptions.NullValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "NULL" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "NULL" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanFalseValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [NullValues("NULL")] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesMapTests.cs
new file mode 100644
index 0000000..2362248
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NullValuesMapTests.cs
@@ -0,0 +1,122 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NullValuesMapTests
+ {
+ [Fact]
+ public void AutoMap_WithBooleanFalseValuesAttribute_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").TypeConverterOption.NullValues("NULL");
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Empty(map.ParameterMaps[0].Data.TypeConverterOptions.NullValues);
+ Assert.Single(map.ParameterMaps[1].Data.TypeConverterOptions.NullValues);
+ Assert.Equal("NULL", map.ParameterMaps[1].Data.TypeConverterOptions.NullValues[0]);
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ new [] { "id", "name" },
+ new [] { "1", "NULL" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithBooleanFalseValuesAttribute_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "NULL" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithBooleanFalseValuesAttribute_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").TypeConverterOption.NullValues("NULL");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesAttributeTests.cs
new file mode 100644
index 0000000..c805b41
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesAttributeTests.cs
@@ -0,0 +1,108 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NumberStylesAttributeTests
+ {
+ private const decimal amount = 123;
+
+ [Fact]
+ public void AutoMap_WithCultureInfoAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.NumberStyles);
+ Assert.Equal(NumberStyles.AllowParentheses, map.ParameterMaps[1].Data.TypeConverterOptions.NumberStyles);
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "amount" },
+ { "1", $"({amount})" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(-amount, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithCultureInfoAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", $"({amount})" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(-amount, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithCultureInfoAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, amount),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Amount\r\n");
+ expected.Append($"1,{amount}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public decimal Amount { get; private set; }
+
+ public Foo(int id, [NumberStyles(NumberStyles.AllowParentheses)] decimal amount)
+ {
+ Id = id;
+ Amount = amount;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesMapTests.cs
new file mode 100644
index 0000000..19fdae8
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/NumberStylesMapTests.cs
@@ -0,0 +1,151 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class NumberStylesMapTests
+ {
+ private const decimal amount = 123;
+
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("amount").TypeConverterOption.NumberStyles(NumberStyles.AllowParentheses);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.NumberStyles);
+ Assert.Equal(NumberStyles.AllowParentheses, map.ParameterMaps[1].Data.TypeConverterOptions.NumberStyles);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "amount").TypeConverterOption.NumberStyles(NumberStyles.AllowParentheses);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.NumberStyles);
+ Assert.Equal(NumberStyles.AllowParentheses, map.ParameterMaps[1].Data.TypeConverterOptions.NumberStyles);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).TypeConverterOption.NumberStyles(NumberStyles.AllowParentheses);
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverterOptions.NumberStyles);
+ Assert.Equal(NumberStyles.AllowParentheses, map.ParameterMaps[1].Data.TypeConverterOptions.NumberStyles);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "amount" },
+ { "1", $"({amount})" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(-amount, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", $"({amount})" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(-amount, records[0].Amount);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, amount),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Amount\r\n");
+ expected.Append($"1,{amount}\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public decimal Amount { get; private set; }
+
+ public Foo(int id, decimal amount)
+ {
+ Id = id;
+ Amount = amount;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Amount);
+ Parameter("id");
+ Parameter("amount").TypeConverterOption.NumberStyles(NumberStyles.AllowParentheses);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalAttributeTests.cs
new file mode 100644
index 0000000..2e7b8b4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalAttributeTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class OptionalAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithConstantAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsOptional);
+ Assert.True(map.ParameterMaps[1].Data.IsOptional);
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithConstantAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [Optional] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalMapTests.cs
new file mode 100644
index 0000000..bae94d1
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/OptionalMapTests.cs
@@ -0,0 +1,150 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class OptionalMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").Optional();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsOptional);
+ Assert.True(map.ParameterMaps[1].Data.IsOptional);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").Optional();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsOptional);
+ Assert.True(map.ParameterMaps[1].Data.IsOptional);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).Optional();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.False(map.ParameterMaps[0].Data.IsOptional);
+ Assert.True(map.ParameterMaps[1].Data.IsOptional);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").Optional();
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterAttributeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterAttributeTests.cs
new file mode 100644
index 0000000..4d6cd2a
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterAttributeTests.cs
@@ -0,0 +1,115 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class TypeConverterAttributeTests
+ {
+ [Fact]
+ public void AutoMap_WithConstantAttributes_ConfiguresParameterMaps()
+ {
+ var context = new CsvContext(new CsvConfiguration(CultureInfo.InvariantCulture));
+ var map = context.AutoMap<Foo>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.IsType<Int32Converter>(map.ParameterMaps[0].Data.TypeConverter);
+ Assert.IsType<CustomConverter>(map.ParameterMaps[1].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithConstantAttributes_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithConstantAttributes_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, null),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, [TypeConverter(typeof(CustomConverter))] string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class CustomConverter : DefaultTypeConverter
+ {
+ public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
+ {
+ return "Bar";
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterMapTests.cs
new file mode 100644
index 0000000..98bc4dd
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ConstructorParameter/TypeConverterMapTests.cs
@@ -0,0 +1,158 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.ConstructorParameter
+{
+
+ public class TypeConverterMapTests
+ {
+ [Fact]
+ public void Parameter_WithName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter("id");
+ map.Parameter("name").TypeConverter<CustomConverter>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverter);
+ Assert.IsType<CustomConverter>(map.ParameterMaps[1].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorFunctionAndName_CreatesParameterMaps()
+ {
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "id");
+ map.Parameter(() => ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo))), "name").TypeConverter<CustomConverter>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverter);
+ Assert.IsType<CustomConverter>(map.ParameterMaps[1].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void Parameter_WithConstructorAndProperty_CreatesParameterMaps()
+ {
+ var constructor = ConfigurationFunctions.GetConstructor(new GetConstructorArgs(typeof(Foo)));
+ var parameters = constructor.GetParameters();
+
+ var map = new DefaultClassMap<Foo>();
+ map.Parameter(constructor, parameters[0]);
+ map.Parameter(constructor, parameters[1]).TypeConverter<CustomConverter>();
+
+ Assert.Equal(2, map.ParameterMaps.Count);
+ Assert.Null(map.ParameterMaps[0].Data.TypeConverter);
+ Assert.IsType<CustomConverter>(map.ParameterMaps[1].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_HasHeader_CreatesRecords()
+ {
+ var parser = new ParserMock
+ {
+ { "id", "name" },
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var map = csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_WithParameterMap_NoHeader_CreatesRecords()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_WithParameterMap_DoesntUseParameterMaps()
+ {
+ var records = new List<Foo>
+ {
+ new Foo(1, "one"),
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+
+ csv.WriteRecords(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Parameter("id");
+ Parameter("name").TypeConverter<CustomConverter>();
+ }
+ }
+
+ private class CustomConverter : DefaultTypeConverter
+ {
+ public override object ConvertFromString(string text, IReaderRow row, MemberMapData memberMapData)
+ {
+ return "Bar";
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/CsvClassMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/CsvClassMappingTests.cs
new file mode 100644
index 0000000..dc10243
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/CsvClassMappingTests.cs
@@ -0,0 +1,239 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class CsvClassMappingTests
+ {
+ [Fact]
+ public void MapTest()
+ {
+ var map = new TestMappingDefaultClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.Equal(0, map.MemberMaps[0].Data.Names.Count);
+ Assert.Equal(0, map.MemberMaps[0].Data.Index);
+ Assert.Null(map.MemberMaps[0].Data.TypeConverter);
+
+ Assert.Equal(0, map.MemberMaps[1].Data.Names.Count);
+ Assert.Equal(1, map.MemberMaps[1].Data.Index);
+ Assert.Null(map.MemberMaps[1].Data.TypeConverter);
+
+ Assert.Equal(0, map.MemberMaps[2].Data.Names.Count);
+ Assert.Equal(2, map.MemberMaps[2].Data.Index);
+ Assert.Null(map.MemberMaps[2].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void MapNameTest()
+ {
+ var map = new TestMappingNameClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.Equal("Guid Column", map.MemberMaps[0].Data.Names.FirstOrDefault());
+ Assert.Equal("Int Column", map.MemberMaps[1].Data.Names.FirstOrDefault());
+ Assert.Equal("String Column", map.MemberMaps[2].Data.Names.FirstOrDefault());
+ }
+
+ [Fact]
+ public void MapIndexTest()
+ {
+ var map = new TestMappingIndexClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.Equal(2, map.MemberMaps[0].Data.Index);
+ Assert.Equal(3, map.MemberMaps[1].Data.Index);
+ Assert.Equal(1, map.MemberMaps[2].Data.Index);
+ }
+
+ [Fact]
+ public void MapIgnoreTest()
+ {
+ var map = new TestMappingIgnoreClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.True(map.MemberMaps[0].Data.Ignore);
+ Assert.False(map.MemberMaps[1].Data.Ignore);
+ Assert.True(map.MemberMaps[2].Data.Ignore);
+ }
+
+ [Fact]
+ public void MapTypeConverterTest()
+ {
+ var map = new TestMappingTypeConverterClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.IsType<Int16Converter>(map.MemberMaps[0].Data.TypeConverter);
+ Assert.IsType<StringConverter>(map.MemberMaps[1].Data.TypeConverter);
+ Assert.IsType<Int64Converter>(map.MemberMaps[2].Data.TypeConverter);
+ }
+
+ [Fact]
+ public void MapMultipleNamesTest()
+ {
+ var map = new TestMappingMultipleNamesClass();
+ //map.CreateMap();
+
+ Assert.Equal(3, map.MemberMaps.Count);
+
+ Assert.Equal(3, map.MemberMaps[0].Data.Names.Count);
+ Assert.Equal(3, map.MemberMaps[1].Data.Names.Count);
+ Assert.Equal(3, map.MemberMaps[2].Data.Names.Count);
+
+ Assert.Equal("guid1", map.MemberMaps[0].Data.Names[0]);
+ Assert.Equal("guid2", map.MemberMaps[0].Data.Names[1]);
+ Assert.Equal("guid3", map.MemberMaps[0].Data.Names[2]);
+
+ Assert.Equal("int1", map.MemberMaps[1].Data.Names[0]);
+ Assert.Equal("int2", map.MemberMaps[1].Data.Names[1]);
+ Assert.Equal("int3", map.MemberMaps[1].Data.Names[2]);
+
+ Assert.Equal("string1", map.MemberMaps[2].Data.Names[0]);
+ Assert.Equal("string2", map.MemberMaps[2].Data.Names[1]);
+ Assert.Equal("string3", map.MemberMaps[2].Data.Names[2]);
+ }
+
+ [Fact]
+ public void MapMultipleTypesTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap<AMap>();
+ context.RegisterClassMap<BMap>();
+
+ Assert.NotNull(context.Maps[typeof(A)]);
+ Assert.NotNull(context.Maps[typeof(B)]);
+ }
+
+ [Fact]
+ public void PropertyMapAccessTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ context.RegisterClassMap<AMap>();
+ context.Maps.Find<A>().Map(m => m.AId).Ignore();
+
+ Assert.True(context.Maps[typeof(A)].MemberMaps[0].Data.Ignore);
+ }
+
+ private class A
+ {
+ public int AId { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.AId);
+ }
+ }
+
+ private class B
+ {
+ public int BId { get; set; }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.BId);
+ }
+ }
+
+ private class TestClass
+ {
+ public string StringColumn { get; set; }
+ public int IntColumn { get; set; }
+ public Guid GuidColumn { get; set; }
+ public string NotUsedColumn { get; set; }
+
+ public TestClass() { }
+
+ public TestClass(string stringColumn)
+ {
+ StringColumn = stringColumn;
+ }
+ }
+
+ private sealed class TestMappingDefaultClass : ClassMap<TestClass>
+ {
+ public TestMappingDefaultClass()
+ {
+ Map(m => m.GuidColumn);
+ Map(m => m.IntColumn);
+ Map(m => m.StringColumn);
+ }
+ }
+
+ private sealed class TestMappingNameClass : ClassMap<TestClass>
+ {
+ public TestMappingNameClass()
+ {
+ Map(m => m.GuidColumn).Name("Guid Column");
+ Map(m => m.IntColumn).Name("Int Column");
+ Map(m => m.StringColumn).Name("String Column");
+ }
+ }
+
+ private sealed class TestMappingIndexClass : ClassMap<TestClass>
+ {
+ public TestMappingIndexClass()
+ {
+ Map(m => m.GuidColumn).Index(3);
+ Map(m => m.IntColumn).Index(2);
+ Map(m => m.StringColumn).Index(1);
+ }
+ }
+
+ private sealed class TestMappingIgnoreClass : ClassMap<TestClass>
+ {
+ public TestMappingIgnoreClass()
+ {
+ Map(m => m.GuidColumn).Ignore();
+ Map(m => m.IntColumn);
+ Map(m => m.StringColumn).Ignore();
+ }
+ }
+
+ private sealed class TestMappingTypeConverterClass : ClassMap<TestClass>
+ {
+ public TestMappingTypeConverterClass()
+ {
+ Map(m => m.GuidColumn).TypeConverter<Int16Converter>();
+ Map(m => m.IntColumn).TypeConverter<StringConverter>();
+ Map(m => m.StringColumn).TypeConverter(new Int64Converter());
+ }
+ }
+
+ private sealed class TestMappingMultipleNamesClass : ClassMap<TestClass>
+ {
+ public TestMappingMultipleNamesClass()
+ {
+ Map(m => m.GuidColumn).Name("guid1", "guid2", "guid3");
+ Map(m => m.IntColumn).Name("int1", "int2", "int3");
+ Map(m => m.StringColumn).Name("string1", "string2", "string3");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/FieldMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/FieldMappingTests.cs
new file mode 100644
index 0000000..3d52839
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/FieldMappingTests.cs
@@ -0,0 +1,397 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+#pragma warning disable 649
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class FieldMappingTests
+ {
+ [Fact]
+ public void ReadPublicFieldsWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Fields,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("IdField,NameField");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<APublic>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].IdField);
+ Assert.Equal("one", records[0].BField.NameField);
+ }
+ }
+
+ [Fact]
+ public void WritePublicFieldsWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Fields,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<APublic>
+ {
+ new APublic
+ {
+ IdField = 1,
+ BField = new BPublic
+ {
+ NameField = "one"
+ }
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("IdField,NameField");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void ReadPublicFieldsWithMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("IdField,NameField");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<APublicMap>();
+ var records = csv.GetRecords<APublic>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].IdField);
+ Assert.Equal("one", records[0].BField.NameField);
+ }
+ }
+
+ [Fact]
+ public void WritePublicFieldsWithMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<APublic>
+ {
+ new APublic
+ {
+ IdField = 1,
+ BField = new BPublic
+ {
+ NameField = "one"
+ }
+ }
+ };
+ csv.Context.RegisterClassMap<APublicMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("IdField,NameField");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void ReadPrivateFieldsWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Fields,
+ IncludePrivateMembers = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("idField,nameField");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<APrivate>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].GetId());
+ Assert.Equal("one", records[0].GetB().GetName());
+ }
+ }
+
+ [Fact]
+ public void WritePrivateFieldsWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Fields,
+ IncludePrivateMembers = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<APrivate>
+ {
+ new APrivate( 1, "one" )
+ };
+
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("idField,nameField");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void ReadPrivateFieldsWithMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("idField,nameField");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<APrivateMap>();
+ var records = csv.GetRecords<APrivate>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].GetId());
+ Assert.Equal("one", records[0].GetB().GetName());
+ }
+ }
+
+ [Fact]
+ public void WritePrivateFieldsWithMappingTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<APrivate>
+ {
+ new APrivate( 1, "one" )
+ };
+ csv.Context.RegisterClassMap<APrivateMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("idField,nameField");
+ expected.AppendLine("1,one");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void ReadPublicFieldsAndPropertiesWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Properties | MemberTypes.Fields,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("IdField,NameField,IdProp,NameProp");
+ writer.WriteLine("1,one,2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<APublic>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].IdField);
+ Assert.Equal("one", records[0].BField.NameField);
+ }
+ }
+
+ [Fact]
+ public void WritePublicFieldsAndPropertiesWithAutoMapTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MemberTypes = MemberTypes.Properties | MemberTypes.Fields,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<APublic>
+ {
+ new APublic
+ {
+ IdField = 1,
+ BField = new BPublic
+ {
+ NameField = "one",
+ NameProp = "two"
+ },
+ IdProp = 2
+ }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("IdProp,IdField,NameProp,NameField");
+ expected.AppendLine("2,1,two,one");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ private class APublic
+ {
+ public int IdField;
+ public BPublic BField;
+
+ public int IdProp { get; set; }
+ }
+
+ private class BPublic
+ {
+ public string NameField;
+
+ public string NameProp { get; set; }
+ }
+
+ private sealed class APublicMap : ClassMap<APublic>
+ {
+ public APublicMap()
+ {
+ Map(m => m.IdField);
+ References<BPublicMap>(m => m.BField);
+ }
+ }
+
+ private sealed class BPublicMap : ClassMap<BPublic>
+ {
+ public BPublicMap()
+ {
+ Map(m => m.NameField);
+ }
+ }
+
+ private class APrivate
+ {
+ private int idField;
+ private BPrivate bField;
+
+ private int IdProp { get; set; }
+ private BPrivate BProp { get; set; }
+
+ public int GetId()
+ {
+ return idField;
+ }
+
+ public BPrivate GetB()
+ {
+ return bField;
+ }
+
+ public APrivate() { }
+
+ public APrivate(int id, string name)
+ {
+ this.idField = id;
+ bField = new BPrivate(name);
+ }
+ }
+
+ private class BPrivate
+ {
+ private string nameField;
+
+ public string GetName()
+ {
+ return nameField;
+ }
+
+ public BPrivate() { }
+
+ public BPrivate(string name)
+ {
+ this.nameField = name;
+ }
+ }
+
+ private sealed class APrivateMap : ClassMap<APrivate>
+ {
+ public APrivateMap()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IncludePrivateMembers = true,
+ MemberTypes = MemberTypes.Fields
+ };
+ AutoMap(config);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/HiddenBaseMembersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/HiddenBaseMembersTests.cs
new file mode 100644
index 0000000..518bcd4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/HiddenBaseMembersTests.cs
@@ -0,0 +1,117 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class HiddenBaseMembersTests
+ {
+ [Fact]
+ public void ReadWithAutoMapTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parserMock))
+ {
+ var records = csv.GetRecords<Bar>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ }
+ }
+
+ [Fact]
+ public void ReadWithClassMapTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ };
+ using (var csv = new CsvReader(parserMock))
+ {
+ csv.Context.RegisterClassMap<BarMap>();
+ var records = csv.GetRecords<Bar>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ }
+ }
+
+ [Fact]
+ public void WriteWithAutoMapTest()
+ {
+ var records = new List<Bar>
+ {
+ new Bar { Id = 1 },
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteWithClassMapTest()
+ {
+ var records = new List<Bar>
+ {
+ new Bar { Id = 1 },
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<BarMap>();
+ csv.WriteRecords(records);
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private abstract class Foo
+ {
+ public string Id { get; set; }
+ }
+
+ private class Bar : Foo
+ {
+ public new int Id { get; set; }
+ }
+
+ private class BarMap : ClassMap<Bar>
+ {
+ public BarMap()
+ {
+ Map(m => m.Id);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/IgnoreHeaderWhiteSpaceTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/IgnoreHeaderWhiteSpaceTests.cs
new file mode 100644
index 0000000..330ace9
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/IgnoreHeaderWhiteSpaceTests.cs
@@ -0,0 +1,52 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class IgnoreHeaderWhiteSpaceTests
+ {
+ [Fact]
+ public void Blah()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("The Id,The Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Id).Name("The Id");
+ Map(m => m.Name).Name("The Name");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MapConstructorTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MapConstructorTests.cs
new file mode 100644
index 0000000..4429f1d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MapConstructorTests.cs
@@ -0,0 +1,42 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class MapConstructorTests
+ {
+ [Fact]
+ public void NoConstructor()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ Assert.Throws<MissingMethodException>(() => csv.Context.RegisterClassMap<TestMap>());
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ private TestMap(string test)
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MappingWithNoHeaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MappingWithNoHeaderTests.cs
new file mode 100644
index 0000000..0b97af6
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/MappingWithNoHeaderTests.cs
@@ -0,0 +1,243 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+ public class MappingWithNoHeaderTests
+ {
+ [Fact]
+ public void Read_NoHeader_HasNameAttribute_Reads()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" }
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<FooAttribute>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void Read_NoHeader_HasNameMap_Reads()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" }
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void Read_NoHeader_HasParameterAttribute_Reads()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" }
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<FooParameterAttribute>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void Read_NoHeader_HasParameterMap_Reads()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "1", "one" }
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.RegisterClassMap<FooParameterMap>();
+ var records = csv.GetRecords<FooParameter>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void Write_HasHeader_HasNameAttribute_Writes()
+ {
+ var records = new List<FooAttribute>
+ {
+ new FooAttribute { Id = 1, Name = "one" },
+ };
+
+ var writer = new StringWriter();
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = "New Id,New Name\r\n1,one\r\n";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void Write_HasHeader_HasNameMap_Writes()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ };
+
+ var writer = new StringWriter();
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ csv.WriteRecords(records);
+
+ var expected = "New Id,New Name\r\n1,one\r\n";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void Write_HasHeader_HasParameterAttribute_Writes()
+ {
+ var records = new List<FooParameterAttribute>
+ {
+ new FooParameterAttribute(1, "one"),
+ };
+
+ var writer = new StringWriter();
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteRecords(records);
+
+ var expected = "Id,Name\r\n1,one\r\n";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void Write_HasHeader_HasParameterMap_Writes()
+ {
+ var records = new List<FooParameterAttribute>
+ {
+ new FooParameterAttribute(1, "one"),
+ };
+
+ var writer = new StringWriter();
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooParameterMap>();
+ csv.WriteRecords(records);
+
+ var expected = "Id,Name\r\n1,one\r\n";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ private class FooAttribute
+ {
+ [Index(0)]
+ [Name("New Id")]
+ public int Id { get; set; }
+
+ [Index(1)]
+ [Name("New Name")]
+ public string Name { get; set; }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(x => x.Id).Name("New Id").Index(0);
+ Map(x => x.Name).Name("New Name").Index(1);
+ }
+ }
+
+ private class FooParameterAttribute
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public FooParameterAttribute([Name("New Id")]int id, [Name("New Name")]string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooParameter
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public FooParameter(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class FooParameterMap : ClassMap<FooParameter>
+ {
+ public FooParameterMap()
+ {
+ Parameter("id").Name("New Id").Index(0);
+ Parameter("name").Name("New Name").Index(1);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/OptionalTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/OptionalTests.cs
new file mode 100644
index 0000000..66ea742
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/OptionalTests.cs
@@ -0,0 +1,220 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CsvHelper;
+using CsvHelper.Configuration;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class OptionalTests
+ {
+ [Fact]
+ public void OptionalWithExistingColumnTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalIntMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ Assert.Equal(2, records[1].Id);
+ Assert.Equal("two", records[1].Name);
+ }
+
+ [Fact]
+ public void OptionalIntTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Name" },
+ { "one" },
+ { "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalIntMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+
+ Assert.Equal(0, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+
+ Assert.Equal(0, records[1].Id);
+ Assert.Equal("two", records[1].Name);
+ }
+
+ [Fact]
+ public void OptionalIntDefaultTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Name" },
+ { "one" },
+ { "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalIntDefaultMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+
+ Assert.Equal(int.MinValue, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+
+ Assert.Equal(int.MinValue, records[1].Id);
+ Assert.Equal("two", records[1].Name);
+ }
+
+ [Fact]
+ public void OptionalStringIntDefaultTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Name" },
+ { "one" },
+ { "two" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalStringIntDefaultMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+
+ Assert.Equal(int.MinValue, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+
+ Assert.Equal(int.MinValue, records[1].Id);
+ Assert.Equal("two", records[1].Name);
+ }
+
+ [Fact]
+ public void OptionalStringTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ { "2" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalStringMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+
+ Assert.Equal(2, records[1].Id);
+ Assert.Null(records[1].Name);
+ }
+
+ [Fact]
+ public void OptionalStringDefaultTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id" },
+ { "1" },
+ { "2" },
+ };
+
+ var csvReader = new CsvReader(parserMock);
+ csvReader.Context.RegisterClassMap<FooOptionalStringDefaultMap>();
+
+ var records = csvReader.GetRecords<Foo>().ToList();
+
+ Assert.NotNull(records);
+ Assert.Equal(2, records.Count);
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("bar", records[0].Name);
+
+ Assert.Equal(2, records[1].Id);
+ Assert.Equal("bar", records[1].Name);
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class FooOptionalIntMap : ClassMap<Foo>
+ {
+ public FooOptionalIntMap()
+ {
+ Map(m => m.Id).Optional();
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class FooOptionalIntDefaultMap : ClassMap<Foo>
+ {
+ public FooOptionalIntDefaultMap()
+ {
+ Map(m => m.Id).Optional().Default(int.MinValue);
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class FooOptionalStringIntDefaultMap : ClassMap<Foo>
+ {
+ public FooOptionalStringIntDefaultMap()
+ {
+ Map(m => m.Id).Optional().Default(int.MinValue.ToString());
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class FooOptionalStringMap : ClassMap<Foo>
+ {
+ public FooOptionalStringMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Optional();
+ }
+ }
+
+ private sealed class FooOptionalStringDefaultMap : ClassMap<Foo>
+ {
+ public FooOptionalStringDefaultMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Optional().Default("bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Property/ConstantTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Property/ConstantTests.cs
new file mode 100644
index 0000000..9aab105
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/Property/ConstantTests.cs
@@ -0,0 +1,74 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mappings.Property
+{
+
+ public class ConstantTests
+ {
+ [Fact]
+ public void GetRecords_ConstantSet_FieldExists_ReturnsRecordsWithConstant()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_ConstantSet_FieldMissing_ReturnsRecordsWithConstant()
+ {
+ var s = new StringBuilder();
+ s.Append("Id\r\n");
+ s.Append("1\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Equal("Bar", records[0].Name);
+ }
+ }
+
+ private class Foo
+ {
+ public string Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id).Index(0);
+ Map(m => m.Name).Index(1).Constant("Bar");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ReferenceConstructorArgsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ReferenceConstructorArgsTests.cs
new file mode 100644
index 0000000..6bd33f7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/ReferenceConstructorArgsTests.cs
@@ -0,0 +1,50 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class ReferenceConstructorArgsTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var map = new AMap( "A Field" );
+ var name = map.ReferenceMaps[0].Data.Mapping.MemberMaps.Find<B>( m => m.Name ).Data.Names[0];
+ Assert.Equal( "B Field", name );
+ }
+
+ private class A
+ {
+ public string Name { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string Name { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap( string name )
+ {
+ Map( m => m.Name ).Name( name );
+ References<BMap>( m => m.B, "B Field" );
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap( string name )
+ {
+ Map( m => m.Name ).Name( name );
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/RuntimeMapping.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/RuntimeMapping.cs
new file mode 100644
index 0000000..41f0714
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/RuntimeMapping.cs
@@ -0,0 +1,199 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class RuntimeMapping
+ {
+ [Fact]
+ public void ConstantTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("AId,BId,CId");
+ writer.WriteLine("1,2,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ var map = new DefaultClassMap<A>();
+ var type = typeof(A);
+ var member = type.GetProperty("AId");
+ map.Map(type, member).Constant(4);
+
+ csv.Context.RegisterClassMap(map);
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal(4, records[0].AId);
+ }
+ }
+
+ [Fact]
+ public void DefaultTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("AId,BId,CId");
+ writer.WriteLine(",2,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ var map = new DefaultClassMap<A>();
+ var type = typeof(A);
+ var member = type.GetProperty("AId");
+ map.Map(type, member).Default(4);
+
+ csv.Context.RegisterClassMap(map);
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal(4, records[0].AId);
+ }
+ }
+
+ [Fact]
+ public void ConstantNullableTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("AId,BId,CId,NullableNum");
+ writer.WriteLine("1,2,3,1");
+ writer.Flush();
+ stream.Position = 0;
+
+ var map = new DefaultClassMap<A>();
+ var type = typeof(A);
+ var member = type.GetProperty("NullableNum");
+ map.Map(type, member).Constant(4);
+
+ csv.Context.RegisterClassMap(map);
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal(4, records[0].NullableNum);
+ }
+ }
+
+ [Fact]
+ public void DefaultNullableTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("AId,BId,CId,NullableNum");
+ writer.WriteLine("1,2,3,");
+ writer.Flush();
+ stream.Position = 0;
+
+ var map = new DefaultClassMap<A>();
+ var type = typeof(A);
+ var member = type.GetProperty("NullableNum");
+ map.Map(type, member).Default(4);
+
+ csv.Context.RegisterClassMap(map);
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal(4, records[0].NullableNum);
+ }
+ }
+
+ [Fact]
+ public void ConstantValueTypeNullTest()
+ {
+ Assert.Throws<ArgumentException>(() => new ConstantValueTypeNullMap());
+ }
+
+ [Fact]
+ public void ConstantTypeMismatchTest()
+ {
+ Assert.Throws<ArgumentException>(() => new ConstantTypeMismatchMap());
+ }
+
+ [Fact]
+ public void DefaultValueTypeNullTest()
+ {
+ Assert.Throws<ArgumentException>(() => new DefaultValueTypeNullMap());
+ }
+
+ [Fact]
+ public void DefaultTypeMismatchTest()
+ {
+ Assert.Throws<ArgumentException>(() => new DefaultTypeMismatchMap());
+ }
+
+ private class A
+ {
+ public int AId { get; set; }
+
+ public int? NullableNum { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public int BId { get; set; }
+
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public int CId { get; set; }
+ }
+
+ private class ObjectProperty
+ {
+ public object O { get; set; }
+ }
+
+ private class ConstantValueTypeNullMap : ClassMap<A>
+ {
+ public ConstantValueTypeNullMap()
+ {
+ Map(m => m.AId).Constant(null);
+ }
+ }
+
+ private class ConstantTypeMismatchMap : ClassMap<A>
+ {
+ public ConstantTypeMismatchMap()
+ {
+ Map(m => m.AId).Constant((uint)1);
+ }
+ }
+
+ private class DefaultValueTypeNullMap : ClassMap<A>
+ {
+ public DefaultValueTypeNullMap()
+ {
+ Map(m => m.AId).Constant(null);
+ }
+ }
+
+ private class DefaultTypeMismatchMap : ClassMap<A>
+ {
+ public DefaultTypeMismatchMap()
+ {
+ Map(m => m.AId).Constant((uint)1);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/SubPropertyMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/SubPropertyMappingTests.cs
new file mode 100644
index 0000000..d1c3f8c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mappings/SubPropertyMappingTests.cs
@@ -0,0 +1,127 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Mappings
+{
+
+ public class SubPropertyMappingTests
+ {
+ [Fact]
+ public void ReadTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("P3,P1,P2");
+ writer.WriteLine("p3,p1,p2");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<AMap>();
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Equal("p1", records[0].P1);
+ Assert.Equal("p2", records[0].B.P2);
+ Assert.Equal("p3", records[0].B.C.P3);
+ }
+ }
+
+ [Fact]
+ public void WriteTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<A>()
+ {
+ new A
+ {
+ P1 = "p1",
+ B = new B
+ {
+ P2 = "p2",
+ C = new C
+ {
+ P3 = "p3"
+ }
+ }
+ }
+ };
+
+ csv.Context.RegisterClassMap<AMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = "P3,P1,P2\r\n";
+ expected += "p3,p1,p2\r\n";
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(expected, result);
+ }
+ }
+
+ [Fact]
+ public void ChangeMemberMapTest()
+ {
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture);
+ var context = new CsvContext(config);
+ var map = context.AutoMap<A>();
+ map.Map(m => m.B.C.P3).Index(3);
+ }
+
+ [Fact]
+ public void AutoMapInClassMapTest()
+ {
+ var map = new AAutoMap();
+ }
+
+ private class A
+ {
+ public string P1 { get; set; }
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string P2 { get; set; }
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string P3 { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.B.C.P3).Index(0);
+ Map(m => m.P1).Index(1);
+ Map(m => m.B.P2).Index(2);
+ }
+ }
+
+ private sealed class AAutoMap : ClassMap<A>
+ {
+ public AAutoMap()
+ {
+ AutoMap(CultureInfo.InvariantCulture);
+ Map(m => m.B.C.P3).Index(3);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/DynamicObjectMock.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/DynamicObjectMock.cs
new file mode 100644
index 0000000..c54a1f3
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/DynamicObjectMock.cs
@@ -0,0 +1,31 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Dynamic;
+
+namespace CsvHelper.Tests.Mocks
+{
+ public class DynamicObjectMock : DynamicObject
+ {
+ private Dictionary<string, object> dictionary = new Dictionary<string, object>();
+
+ public override bool TryGetMember(GetMemberBinder binder, out object result)
+ {
+ return dictionary.TryGetValue(binder.Name, out result);
+ }
+
+ public override bool TrySetMember(SetMemberBinder binder, object value)
+ {
+ dictionary[binder.Name] = value;
+
+ return true;
+ }
+
+ public override IEnumerable<string> GetDynamicMemberNames()
+ {
+ return dictionary.Keys;
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMock.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMock.cs
new file mode 100644
index 0000000..3dba8b2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMock.cs
@@ -0,0 +1,96 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.IO;
+using CsvHelper.Configuration;
+using System.Threading.Tasks;
+using System.Globalization;
+using System.Linq;
+
+namespace CsvHelper.Tests.Mocks
+{
+ public class ParserMock : IParser, IEnumerable<string[]>
+ {
+ private readonly Queue<string[]> records = new Queue<string[]>();
+ private string[] record;
+ private int row;
+
+ public CsvContext Context { get; private set; }
+
+ public IParserConfiguration Configuration { get; private set; }
+
+ public int Count => record?.Length ?? 0;
+
+ public string[] Record => record;
+
+ public string RawRecord => string.Empty;
+
+ public int Row => row;
+
+ public int RawRow => row;
+
+ public long ByteCount => 0;
+
+ public long CharCount => 0;
+
+ public string Delimiter => Configuration.Delimiter;
+
+ public string this[int index] => record[index];
+
+ public ParserMock() : this(new CsvConfiguration(CultureInfo.InvariantCulture)) { }
+
+ public ParserMock(CsvConfiguration configuration)
+ {
+ Configuration = configuration;
+ Context = new CsvContext(this);
+ }
+
+ public bool Read()
+ {
+ if (records.Count == 0)
+ {
+ return false;
+ }
+
+ row++;
+ record = records.Dequeue();
+
+ return true;
+ }
+
+ public Task<bool> ReadAsync()
+ {
+ row++;
+ record = records.Dequeue();
+
+ return Task.FromResult(records.Count > 0);
+ }
+
+ public void Dispose()
+ {
+ }
+
+ #region Mock Methods
+
+ public void Add(params string[] record)
+ {
+ records.Enqueue(record);
+ }
+
+ public IEnumerator<string[]> GetEnumerator()
+ {
+ return records.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ #endregion Mock Methods
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMockTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMockTests.cs
new file mode 100644
index 0000000..3b779c9
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ParserMockTests.cs
@@ -0,0 +1,37 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mocks
+{
+
+ public class ParserMockTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ Assert.False(parser.Read());
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ReaderRowMock.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ReaderRowMock.cs
new file mode 100644
index 0000000..b73c81e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Mocks/ReaderRowMock.cs
@@ -0,0 +1,226 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Mocks
+{
+ public class ReaderRowMock : IReaderRow
+ {
+ public string this[int index] => throw new NotImplementedException();
+
+ public string this[string name] => throw new NotImplementedException();
+
+ public string this[string name, int index] => throw new NotImplementedException();
+
+ public int ColumnCount => throw new NotImplementedException();
+
+ public int CurrentIndex => throw new NotImplementedException();
+
+ public string[] HeaderRecord => throw new NotImplementedException();
+
+ public IParser Parser => throw new NotImplementedException();
+
+ public CsvContext Context => throw new NotImplementedException();
+
+ public IReaderConfiguration Configuration { get; private set; }
+
+ public ReaderRowMock()
+ {
+ Configuration = new CsvConfiguration(CultureInfo.InvariantCulture);
+ }
+
+ public ReaderRowMock(CsvConfiguration configuration)
+ {
+ Configuration = configuration;
+ }
+
+ public string GetField(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetField(string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public string GetField(string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetField(Type type, string name, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, int index)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T>(string name, int index, ITypeConverter converter)
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(int index) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(string name) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetField<T, TConverter>(string name, int index) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetRecord<T>()
+ {
+ throw new NotImplementedException();
+ }
+
+ public T GetRecord<T>(T anonymousTypeDefinition)
+ {
+ throw new NotImplementedException();
+ }
+
+ public object GetRecord(Type type)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, int index, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, int index, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, int index, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField(Type type, string name, int index, ITypeConverter converter, out object field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(int index, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, int index, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(int index, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T>(string name, int index, ITypeConverter converter, out T field)
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(int index, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(string name, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+
+ public bool TryGetField<T, TConverter>(string name, int index, out T field) where TConverter : ITypeConverter
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectCreatorTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectCreatorTests.cs
new file mode 100644
index 0000000..add5a72
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectCreatorTests.cs
@@ -0,0 +1,351 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.ObjectCreatorTests
+{
+
+ public class CreateInstance_ValueType
+ {
+ [Fact]
+ public void CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var value = creator.CreateInstance<int>();
+
+ Assert.Equal(default(int), value);
+ }
+
+ [Fact]
+ public void ParameterSupplied_ThrowsMissingMethodExcepetion()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<int>(1));
+ }
+ }
+
+
+ public class CreateInstance_DefaultConstructor
+ {
+ [Fact]
+ public void CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>();
+ creator.CreateInstance<Foo>();
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(default(int), foo.Id);
+ }
+
+ [Fact]
+ public void ParameterSupplied_ThrowsMissingMethodExcepetion()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<Foo>(1));
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public Foo() { }
+ }
+ }
+
+
+ public class CreateInstance_OneParameterConstructor
+ {
+ [Fact]
+ public void OneParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(1);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ }
+
+ [Fact]
+ public void NoParameter_ThrowsMissingMethodException()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<Foo>());
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public Foo(int id)
+ {
+ Id = id;
+ }
+ }
+ }
+
+
+ public class CreateInstance_DefaultConstructorAndOneParameterConstructor
+ {
+ [Fact]
+ public void NoParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>();
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(default(int), foo.Id);
+ }
+
+ [Fact]
+ public void OneParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(1);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ }
+
+ [Fact]
+ public void OneParameterWrongType_ThrowsMissingMethodException()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<Foo>(string.Empty));
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public Foo() { }
+
+ public Foo(int id)
+ {
+ Id = id;
+ }
+ }
+ }
+
+
+ public class CreateInstance_ValueTypeAndReferenceTypeParameters
+ {
+ [Fact]
+ public void FirstSignature_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(1, "one");
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ Assert.Equal("one", foo.Name);
+ }
+
+ [Fact]
+ public void SecondSignature_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>("one", 1);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ Assert.Equal("one", foo.Name);
+ }
+
+ [Fact]
+ public void FirstSignature_NullReferenceType_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(1, null);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ Assert.Null(foo.Name);
+ }
+
+ [Fact]
+ public void SecondSignature_NullReferenceType_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(null, 1);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(1, foo.Id);
+ Assert.Null(foo.Name);
+ }
+
+ [Fact]
+ public void FirstSignature_NullValueType_ThrowsMissingMethodException()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<Foo>(null, "one"));
+ }
+
+ [Fact]
+ public void SecondSignature_NullValueType_ThrowsMissingMethodException()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<MissingMethodException>(() => creator.CreateInstance<Foo>("one", null));
+ }
+
+ private class Foo
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public Foo(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+
+ public Foo(string name, int id)
+ {
+ Name = name;
+ Id = id;
+ }
+ }
+ }
+
+
+ public class CreateInstance_TwoReferenceTypeParameters
+ {
+ [Fact]
+ public void FirstSignature_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var bar = new Bar();
+ var foo = creator.CreateInstance<Foo>("one", bar);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal("one", foo.Name);
+ Assert.Equal(bar, foo.Bar);
+ }
+
+ [Fact]
+ public void SecondSignature_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var bar = new Bar();
+ var foo = creator.CreateInstance<Foo>(bar, "one");
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal("one", foo.Name);
+ Assert.Equal(bar, foo.Bar);
+ }
+
+ [Fact]
+ public void FirstSignature_NullFirstParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var bar = new Bar();
+ var foo = creator.CreateInstance<Foo>(null, bar);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Null(foo.Name);
+ Assert.Equal(bar, foo.Bar);
+ }
+
+ [Fact]
+ public void FirstSignature_NullSecondParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>("one", null);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal("one", foo.Name);
+ Assert.Null(foo.Bar);
+ }
+
+ [Fact]
+ public void SecondSignature_NullFirstParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var foo = creator.CreateInstance<Foo>(null, "one");
+
+ Assert.IsType<Foo>(foo);
+ Assert.Null(foo.Bar);
+ Assert.Equal("one", foo.Name);
+ }
+
+ [Fact]
+ public void SecondSignature_NullSecondParameter_CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+ var bar = new Bar();
+ var foo = creator.CreateInstance<Foo>(bar, null);
+
+ Assert.IsType<Foo>(foo);
+ Assert.Equal(bar, foo.Bar);
+ Assert.Null(foo.Name);
+ }
+
+ [Fact]
+ public void FirstSignature_BothNullParameters_ThrowsAmbiguousMatchException()
+ {
+ var creator = new ObjectCreator();
+
+ Assert.Throws<AmbiguousMatchException>(() => creator.CreateInstance<Foo>(null, null));
+ }
+
+ private class Foo
+ {
+ public string Name { get; set; }
+
+ public Bar Bar { get; set; }
+
+ public Foo(string name, Bar bar)
+ {
+ Name = name;
+ Bar = bar;
+ }
+
+ public Foo(Bar bar, string name)
+ {
+ Bar = bar;
+ Name = name;
+ }
+ }
+
+ private class Bar { }
+ }
+
+
+ public class CreateInstance_PrivateConstructor
+ {
+ [Fact]
+ public void CreatesInstance()
+ {
+ var creator = new ObjectCreator();
+
+ var foo = creator.CreateInstance<Foo>();
+
+ Assert.IsType<Foo>(foo);
+ }
+
+ private class Foo
+ {
+ private Foo() { }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/Issue1073.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/Issue1073.cs
new file mode 100644
index 0000000..cf4cec4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/Issue1073.cs
@@ -0,0 +1,72 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests.Issues
+{
+
+ public class Issue1073
+ {
+ [Fact]
+ public void GetFieldTest()
+ {
+ var originalResolver = ObjectResolver.Current;
+ try
+ {
+ ObjectResolver.Current = new ObjectResolver(type => true, (type, args) =>
+ {
+ throw new XUnitException();
+ });
+
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ while (csv.Read())
+ {
+ csv.GetField<int>("Id");
+ csv.GetField<string>("Name");
+ }
+ }
+ }
+ finally
+ {
+ ObjectResolver.Current = originalResolver;
+ }
+ }
+
+ [Fact]
+ public void WriteFieldTest()
+ {
+ var originalResolver = ObjectResolver.Current;
+ try
+ {
+ ObjectResolver.Current = new ObjectResolver(type => true, (type, args) =>
+ {
+ throw new XUnitException();
+ });
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField(1);
+ csv.WriteField("one");
+ csv.NextRecord();
+ }
+ }
+ finally
+ {
+ ObjectResolver.Current = originalResolver;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/ResolveSingleTypeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/ResolveSingleTypeTests.cs
new file mode 100644
index 0000000..4413c3f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ObjectResolverTests/ResolveSingleTypeTests.cs
@@ -0,0 +1,59 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Linq;
+
+namespace CsvHelper.Tests.ObjectResolverTests
+{
+
+ public class ResolverSingleTypeTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ };
+
+ var originalResolver = ObjectResolver.Current;
+
+ try
+ {
+ using (var csv = new CsvReader(parser))
+ {
+ ObjectResolver.Current = new ObjectResolver(CanResolve, Resolve);
+ var records = csv.GetRecords<A>().ToList();
+
+ Assert.Single(records);
+ }
+ }
+ finally
+ {
+ ObjectResolver.Current = originalResolver;
+ }
+ }
+
+ private bool CanResolve(Type type)
+ {
+ return type == typeof(A);
+ }
+
+ private object Resolve(Type type, object[] args)
+ {
+ return new A();
+ }
+
+ private class A
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BadDataTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BadDataTests.cs
new file mode 100644
index 0000000..8f6ccb4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BadDataTests.cs
@@ -0,0 +1,153 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class BadDataTests
+ {
+ [Fact]
+ public void CallbackTest()
+ {
+ string rawRecord = null;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = args => rawRecord = args.Context.Parser.RawRecord.ToString(),
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write(" a\"bc\",d\r\n"); // a"bc",d\r\n
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ var record = parser.Record;
+ Assert.Equal(" a\"bc\",d\r\n", rawRecord);
+
+ rawRecord = null;
+ parser.Read();
+ record = parser.Record;
+ Assert.Null(rawRecord);
+ }
+ }
+
+ [Fact]
+ public void ThrowExceptionTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("1,2");
+ writer.WriteLine(" a\"bc\",d");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ try
+ {
+ parser.Read();
+ var record = parser.Record;
+ throw new XUnitException("Failed to throw exception on bad data.");
+ }
+ catch (BadDataException) { }
+ }
+ }
+
+ [Fact]
+ public void IgnoreQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("one,2\"two,three\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("2\"two", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void LineBreakInQuotedFieldIsBadDataCrTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ LineBreakInQuotedFieldIsBadData = true,
+ };
+ using (var reader = new StringReader("\"a\rb\""))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Throws<BadDataException>(() => parser.Record);
+ }
+ }
+
+ [Fact]
+ public void LineBreakInQuotedFieldIsBadDataLfTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ LineBreakInQuotedFieldIsBadData = true,
+ };
+ using (var reader = new StringReader("\"a\nb\""))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Throws<BadDataException>(() => parser.Record);
+ }
+ }
+
+ [Fact]
+ public void LineBreakInQuotedFieldIsBadDataCrLfTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ LineBreakInQuotedFieldIsBadData = true,
+ };
+ using (var reader = new StringReader("\"a\r\nb\""))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Throws<BadDataException>(() => parser.Record);
+ }
+ }
+
+ [Fact]
+ public void Read_AccessingParserRecordInBadDataFound_ThrowsParserException()
+ {
+ var badstring = new StringReader("Fish,\"DDDD");
+
+ string[] record = new string[0];
+ var cfg = new CsvConfiguration(CultureInfo.CurrentCulture)
+ {
+ BadDataFound = args => record = args.Context.Parser.Record
+ };
+ var parser = new CsvParser(badstring, cfg);
+
+ parser.Read();
+
+ Assert.Throws<ParserException>(() => parser[1]);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingEscapeAndQuoteTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingEscapeAndQuoteTests.cs
new file mode 100644
index 0000000..007df34
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingEscapeAndQuoteTests.cs
@@ -0,0 +1,38 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class BufferSplittingEscapeAndQuoteTests
+ {
+ [Fact]
+ public void Read_BufferEndsAtEscape_FieldIsNotBadData()
+ {
+ var s = new StringBuilder();
+ s.Append("a,\"bcdefghijklm\"\"nopqrstuvwxyz\"\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("a", parser[0]);
+ Assert.Equal("bcdefghijklm\"nopqrstuvwxyz", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingLineEndingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingLineEndingTests.cs
new file mode 100644
index 0000000..c4457f4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingLineEndingTests.cs
@@ -0,0 +1,98 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class BufferSplittingLineEndingTests
+ {
+ [Fact]
+ public void Read_BufferSplitsCrLf_BufferNeedsResize_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("1,0000000000321\r\n");
+ s.Append("3,4\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("0000000000321", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferSplitsCrLf_NoBufferResize_DoesntAddExtraField()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,400000\r\n");
+ s.Append("5,600\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal(2, parser.Count);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferSplitsCrLf_NoBufferResize_RawRecordIsCorrect()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,400000\r\n");
+ s.Append("5,600\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal("5,600\r\n", parser.RawRecord);
+ }
+ }
+
+ [Fact]
+ public void BufferSplitsCrLfWithLastFieldQuotedTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,4000\r\n");
+ s.Append("5,\"600\"\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("5,\"600\"\r\n", parser.RawRecord);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingNewLineEndingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingNewLineEndingTests.cs
new file mode 100644
index 0000000..a3d40b4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/BufferSplittingNewLineEndingTests.cs
@@ -0,0 +1,102 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Text;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class BufferSplittingCrLnTests
+ {
+ [Fact]
+ public void Read_BufferSplitsCrLf_BufferNeedsResize_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("1,0000000000321\r\n");
+ s.Append("3,4\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ NewLine = "\r\n",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("0000000000321", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferSplitsCrLf_NoBufferResize_DoesntAddExtraField()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,400000\r\n");
+ s.Append("5,600\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ NewLine = "\r\n",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal(2, parser.Count);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferSplitsCrLf_NoBufferResize_RawRecordIsCorrect()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,400000\r\n");
+ s.Append("5,600\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ NewLine = "\r\n",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal("5,600\r\n", parser.RawRecord);
+ }
+ }
+
+ [Fact]
+ public void BufferSplitsCrLfWithLastFieldQuotedTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,200000\r\n");
+ s.Append("3,4000\r\n");
+ s.Append("5,\"600\"\r\n");
+ var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ NewLine = "\r\n",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ parser.Read();
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("5,\"600\"\r\n", parser.RawRecord);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ByteCountTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ByteCountTests.cs
new file mode 100644
index 0000000..dc3bd8d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ByteCountTests.cs
@@ -0,0 +1,137 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class ByteCountTests
+ {
+ [Fact]
+ public void Read_CRLF_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ [Fact]
+ public void Read_CR_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ [Fact]
+ public void Read_LF_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ [Fact]
+ public void Read_NoLineEnding_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ };
+ var s = new StringBuilder();
+ s.Append("1,2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ [Fact]
+ public void CharCountFirstCharOfDelimiterNextToDelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ Delimiter = "!#",
+ };
+ var s = new StringBuilder();
+ s.Append("1!!#2\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ [Fact]
+ public void Read_Trimmed_WhiteSpaceCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Encoding = Encoding.Unicode,
+ CountBytes = true,
+ TrimOptions = TrimOptions.Trim
+ };
+ var s = new StringBuilder();
+ s.Append("1, 2\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(config.Encoding.GetByteCount(s.ToString()), parser.ByteCount);
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CharCountTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CharCountTests.cs
new file mode 100644
index 0000000..06b469e
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CharCountTests.cs
@@ -0,0 +1,124 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class CharCountTests
+ {
+ [Fact]
+ public void Read_CRLF_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(5, parser.CharCount);
+ }
+ }
+
+ [Fact]
+ public void Read_CR_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(4, parser.CharCount);
+ }
+ }
+
+ [Fact]
+ public void Read_LF_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var s = new StringBuilder();
+ s.Append("1,2\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(4, parser.CharCount);
+ }
+ }
+
+ [Fact]
+ public void Read_NoLineEnding_CharCountCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var s = new StringBuilder();
+ s.Append("1,2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.CharCount);
+ }
+ }
+
+ [Fact]
+ public void CharCountFirstCharOfDelimiterNextToDelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "!#",
+ };
+ var s = new StringBuilder();
+ s.Append("1!!#2\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(7, parser.CharCount);
+ }
+ }
+
+ [Fact]
+ public void Read_Trimmed_WhiteSpaceCorrect()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim
+ };
+ var s = new StringBuilder();
+ s.Append("1, 2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(4, parser.CharCount);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CommentTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CommentTests.cs
new file mode 100644
index 0000000..cd4db53
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CommentTests.cs
@@ -0,0 +1,125 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class CommentTests
+ {
+ [Fact]
+ public void CommentThatCrossesBuffersShouldNotAddToFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ BufferSize = 16
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1,2\r\n");
+ writer.Write("#abcdefghijklmnop\r\n");
+ writer.Write("3,4");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void WriteCommentCharInFieldWithCommentsOffTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("#no comment");
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal("#no comment\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void WriteCommentCharInFieldWithCommentsOnTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("#no comment");
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal("#no comment\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void WriteCommentWithCommentsOffTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteComment("comment\"has\" quote");
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal("#comment\"has\" quote\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void WriteCommentWithCommentsOnTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ AllowComments = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteComment("comment\"has\" quote");
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal("#comment\"has\" quote\r\n", result);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CrTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CrTests.cs
new file mode 100644
index 0000000..e14d619
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CrTests.cs
@@ -0,0 +1,235 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class CrTests
+ {
+ [Fact]
+ public void SingleFieldAndSingleRowTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndSingleRowAndFieldIsQuotedTest()
+ {
+ var s = new StringBuilder();
+ s.Append("\"1\"\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndMultipleRowsAndFirstFieldInFirstRowIsQuotedAndNoLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("\"1\"\r");
+ s.Append("2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndMultipleRowsAndFirstFieldInFirstRowIsQuotedAndHasLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("\"1\"\r");
+ s.Append("2\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndMultipleRowsTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1\r");
+ s.Append("2\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndMultipleRowsAndLastRowHasNoLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1\r");
+ s.Append("2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void SingleFieldAndSecondRowIsQuotedAndLastRowHasNoLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1\r");
+ s.Append("\"2\"");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+
+ parser.Read();
+ Assert.Equal("2", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndSingleRowAndLastRowHasNoLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndMultipleRowsAndLastRowHasNoLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ s.Append("3,4");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndMultipleRowsAndLastRowHasLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ s.Append("3,4\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndMultipleRowsAndLastFieldInFirstRowIsQuotedAndLastRowHasLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,\"2\"\r");
+ s.Append("3,4\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndMultipleRowsAndSecondRowFirstFieldIsQuotedAndLastRowHasLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r");
+ s.Append("\"3\",4\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void MultipleFieldsAndMultipleRowsAndAllFieldsQuotedAndHasLineEndingTest()
+ {
+ var s = new StringBuilder();
+ s.Append("\"1\",\"2\"\r");
+ s.Append("\"3\",\"4\"\r");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ parser.Read();
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+
+ parser.Read();
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CsvModeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CsvModeTests.cs
new file mode 100644
index 0000000..f561f68
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/CsvModeTests.cs
@@ -0,0 +1,109 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class CsvModeTests
+ {
+ [Fact]
+ public void Read_HasEscapedDelimiter_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("a\\,b,c\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("a,b", parser[0]);
+ Assert.Equal("c", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_HasEscapedLineEnding_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("a\\\nb,c\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("a\nb", parser[0]);
+ Assert.Equal("c", parser[1]);
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_NoEscapeMode_HasRFC4180Format_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("a,\"b,\"\"c\r\nd\",e");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.NoEscape,
+ Escape = '"',
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("a", parser[0]);
+ Assert.Equal("\"b", parser[1]);
+ Assert.Equal("\"\"c", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("d\"", parser[0]);
+ Assert.Equal("e", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void Read_NoEscapeMode_HasEscapeFormat_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("a,\\b\\,c\\\nd,e");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.NoEscape,
+ Escape = '\\',
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("a", parser[0]);
+ Assert.Equal("\\b\\", parser[1]);
+ Assert.Equal("c\\", parser[2]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("d", parser[0]);
+ Assert.Equal("e", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DelimiterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DelimiterTests.cs
new file mode 100644
index 0000000..66f599b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DelimiterTests.cs
@@ -0,0 +1,81 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class DelimiterTests
+ {
+ [Fact]
+ public void MultipleCharDelimiterWithPartOfDelimiterInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "<|>",
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ writer.Write("1<|>2<3<|>4\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2<3", parser[1]);
+ Assert.Equal("4", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void NullDelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "\0",
+ };
+ var s = new StringBuilder();
+ s.Append("1\02\03\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.Equal("3", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void FirstCharOfDelimiterNextToDelimiterTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "!#",
+ };
+ var s = new StringBuilder();
+ s.AppendLine("1!!#2");
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("1!", parser[0]);
+ Assert.Equal("2", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DetectDelimiterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DetectDelimiterTests.cs
new file mode 100644
index 0000000..facc030
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/DetectDelimiterTests.cs
@@ -0,0 +1,286 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+ public class DetectDelimiterTests
+ {
+ [Fact]
+ public void GetDelimiter_TextHasCommas_DetectsComma()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ };
+ Assert.Equal(",", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHasSemicolons_DetectsSemicolon()
+ {
+ var s = new StringBuilder();
+ s.Append("Id;Name\r\n");
+ s.Append("1;one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(";", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHasPipes_DetectsPipe()
+ {
+ var s = new StringBuilder();
+ s.Append("Id|Name\r\n");
+ s.Append("1|one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("|", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHasTabs_DetectsTab()
+ {
+ var s = new StringBuilder();
+ s.Append("Id\tName\r\n");
+ s.Append("1\tone\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("\t", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+ }
+
+ [Fact]
+ public void GetDelimiter_EqualAmountOfDelimiters_DetectsFirstInDelimiterValuesList()
+ {
+ var s = new StringBuilder();
+ s.Append(";;,,\t\t||\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiter = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(",", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHas2CharDelimiter_DetectsDelimiter()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,,Name\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiter = true,
+ DetectDelimiterValues = new[] { ",," },
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(",,", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHasRegularCharDelimiter_DetectsDelimiter()
+ {
+ var s = new StringBuilder();
+ s.Append("IdþName\r\n");
+ s.Append("1þone\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiterValues = new[] { "þ" }
+ };
+ Assert.Equal("þ", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_MultipleLines_DetectsDelimiterThatIsOnEveryLine()
+ {
+ var s = new StringBuilder();
+ s.Append("Id;Name\r\n");
+ s.Append("1,2,3,4;5,6,7,8\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiterValues = new[] { ",", ";" }
+ };
+ Assert.Equal(";", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_NoDelimiter_DoesNotDetect()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiterValues = new[] { ";" }
+ };
+ Assert.Equal("`", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_CulturesSeparatorOccursLessButIsOnEveryLine_CulturesSeparatorIsDetected()
+ {
+ var s = new StringBuilder();
+ s.Append("1;2,3;4\r\n");
+ s.Append("5;6,7;8\r\n");
+ s.Append("9;10,11;12\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ Assert.Equal(CultureInfo.InvariantCulture.TextInfo.ListSeparator, ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_CulturesSeparatorOccursLessAndIsOnFirstLine_CulturesSeparatorIsNotDetected()
+ {
+ var s = new StringBuilder();
+ s.Append("1;2,3;4\r\n");
+ s.Append("5;6;7;8\r\n");
+ s.Append("9;10,11;12\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ Assert.NotEqual(CultureInfo.InvariantCulture.TextInfo.ListSeparator, ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_CulturesSeparatorOccursLessAndHasSingleLine_CulturesSeparatorIsNotDetected()
+ {
+ var s = new StringBuilder();
+ s.Append("1;2,3;4\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ Assert.NotEqual(CultureInfo.InvariantCulture.TextInfo.ListSeparator, ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_CulturesSeparatorOccursLessAndHas2LinesAndIsOnEveryLine_CulturesSeparatorIsNotDetected()
+ {
+ var s = new StringBuilder();
+ s.Append("1;2,3;4\r\n");
+ s.Append("5;6,7;8\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ Assert.NotEqual(CultureInfo.InvariantCulture.TextInfo.ListSeparator, ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_CulturesSeparatorOccursLessAndIsOnSecondLine_CulturesSeparatorIsDetected()
+ {
+ var s = new StringBuilder();
+ s.Append("1;2;3;4\r\n");
+ s.Append("5;6,7;8\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ Assert.Equal(";", ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config)));
+ }
+
+ [Fact]
+ public void GetDelimiter_TextHasLF_NewLineIsCRLF_DetectsDelimiter()
+ {
+ var s = new StringBuilder();
+ s.Append("name;num;date\nLily;1,005.25;2021-02-03\nJack;3.5;2021-02-04");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var delimeter = ConfigurationFunctions.GetDelimiter(new Delegates.GetDelimiterArgs(s.ToString(), config));
+ Assert.Equal(";", delimeter);
+ }
+
+ [Fact]
+ public void CsvParserConstructor_DelimiterValuesEmpty_ThrowsException()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectDelimiter = true,
+ DetectDelimiterValues = new string[0],
+ };
+ using (var reader = new StringReader(s.ToString()))
+ {
+ Assert.Throws<ConfigurationException>(() => new CsvParser(reader, config));
+ }
+ }
+
+ [Fact]
+ public void Read_TextHasCommas_ParsesRows()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\r\n");
+ s.Append("1,one\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = "`",
+ DetectDelimiter = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var row = parser.Read();
+
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ row = parser.Read();
+
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EndBufferTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EndBufferTests.cs
new file mode 100644
index 0000000..9b1e2dd
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EndBufferTests.cs
@@ -0,0 +1,79 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class EndBufferTests
+ {
+ [Fact]
+ public void Read_BufferEndsInOneCharDelimiter_ParsesFieldCorrectly()
+ {
+ var s = new StringBuilder();
+ s.Append("abcdefghijklmno,pqrs\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("abcdefghijklmno", parser[0]);
+ Assert.Equal("pqrs", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferEndsInFirstCharOfTwoCharDelimiter_ParsesFieldCorrectly()
+ {
+ var s = new StringBuilder();
+ s.Append("abcdefghijklmnop;;qrs\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ Delimiter = ";;",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("abcdefghijklmnop", parser[0]);
+ Assert.Equal("qrs", parser[1]);
+ }
+ }
+
+ [Fact]
+ public void Read_BufferEndsInSecondCharOfTwoCharDelimiter_ParsesFieldCorrectly()
+ {
+ var s = new StringBuilder();
+ s.Append("abcdefghijklmno;;pqrs\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16,
+ Delimiter = ";;",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal(2, parser.Count);
+ Assert.Equal("abcdefghijklmno", parser[0]);
+ Assert.Equal("pqrs", parser[1]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EscapeCharacterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EscapeCharacterTests.cs
new file mode 100644
index 0000000..bf0b801
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/EscapeCharacterTests.cs
@@ -0,0 +1,110 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class EscapeCharacterTests
+ {
+ [Fact]
+ public void EscapeTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ };
+ using (var reader = new StringReader("\"|\"a|\"\"\r\n"))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("\"a\"", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void EscapeNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ };
+ using (var reader = new StringReader("\"|\"a|\"\""))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("\"a\"", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void EscapeTrimOutsideTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var reader = new StringReader(" \"|\"a|\"\" \r\n")) // ` "|"a|"" \r\n`
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("\"a\"", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void EscapeTrimInsideTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var reader = new StringReader("\" |\"a|\" \"\r\n"))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("\"a\"", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void EscapeTrimBothTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ TrimOptions = TrimOptions.Trim | TrimOptions.InsideQuotes,
+ };
+ using (var reader = new StringReader(" \" |\"a|\" \" \r\n"))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ Assert.Equal("\"a\"", parser[0]);
+ }
+ }
+
+ [Fact]
+ public void EscapeWriteTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Escape = '|',
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("\"a\"");
+ csv.Flush();
+
+ Assert.Equal("\"|\"a|\"\"", writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ExcelCompatibilityTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ExcelCompatibilityTests.cs
new file mode 100644
index 0000000..801443d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/ExcelCompatibilityTests.cs
@@ -0,0 +1,123 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class ExcelCompatibilityTests
+ {
+ [Fact]
+ public void Parse_EscapedFieldHasSpaceAfterLastQuote_FieldProcessedLeavingSpaceAtEnd()
+ {
+ var s = new StringBuilder();
+ s.Append("one,\"two\" ,three\r\n"); // one,"two" ,three
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal("two ", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void Parse_EscapedFieldHasSpaceBeforeFirstQuote_FieldIsNotProcessed()
+ {
+ var s = new StringBuilder();
+ s.Append("one, \"two\",three\r\n"); // one, "two",three
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("one", parser[0]);
+ Assert.Equal(" \"two\"", parser[1]);
+ Assert.Equal("three", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void Parse_EscapedFieldHasExtraQuoteAfterLastQuote_CharsAfterLastQuoteAreNotProcessed()
+ {
+ var s = new StringBuilder();
+ s.Append("1,\"two\" \"2,3\r\n"); // 1,"two" "2,3
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("two \"2", parser[1]);
+ Assert.Equal("3", parser[2]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Parse_EscapedFieldHasNoEndingQuote_GoesToEndOfFile()
+ {
+ var s = new StringBuilder();
+ s.Append("a,b,\"c\r\n"); // a,b,"c\r\nd,e,f\r\n
+ s.Append("d,e,f\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal("b", parser[1]);
+ Assert.Equal("c\r\nd,e,f\r\n", parser[2]);
+ }
+ }
+
+ [Fact]
+ public void Parse_NonEscapedFieldHasQuotesInIt_IgnoresQuotes()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\"3\"4,5\r\n"); // 1,2"3"4,5
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BadDataFound = null,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal(3, parser.Count);
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2\"3\"4", parser[1]);
+ Assert.Equal("5", parser[2]);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/FieldCacheTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/FieldCacheTests.cs
new file mode 100644
index 0000000..38bea21
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/FieldCacheTests.cs
@@ -0,0 +1,94 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class FieldCacheTests
+ {
+ [Fact]
+ public void Read_WithFieldCacheEnabled_ReturnsSameFieldInstance()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r\n");
+ s.Append("2,1\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CacheFields = true,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ var a = parser[0];
+ parser.Read();
+ var b = parser[1];
+
+ Assert.Same(a, b);
+ }
+ }
+
+ [Fact]
+ public void Read_WithFieldCacheDisabled_ReturnsDifferentFieldInstance()
+ {
+ var s = new StringBuilder();
+ s.Append("1,2\r\n");
+ s.Append("2,1\r\n");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ CacheFields = false,
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ var a = parser[0];
+ parser.Read();
+ var b = parser[1];
+
+ Assert.NotSame(a, b);
+ }
+ }
+
+ [Fact]
+ public void Test1()
+ {
+ // "542008", "27721116", "98000820" have hash code 3769566006
+
+ var value1 = "542008";
+ var value2 = "27721116";
+ var value3 = "98000820";
+ var value4 = "542008";
+
+ var cache = new FieldCache(1);
+
+ var field1 = cache.GetField(value1.ToCharArray(), 0, value1.Length);
+ var field2 = cache.GetField(value2.ToCharArray(), 0, value2.Length);
+ var field3 = cache.GetField(value3.ToCharArray(), 0, value3.Length);
+ var field4 = cache.GetField(value4.ToCharArray(), 0, value4.Length);
+
+ Assert.Equal(value1, field1);
+ Assert.Equal(value2, field2);
+ Assert.Equal(value3, field3);
+ Assert.Equal(value4, field4);
+
+ Assert.NotSame(value1, field1);
+ Assert.NotSame(value2, field2);
+ Assert.NotSame(value3, field3);
+ Assert.NotSame(value4, field4);
+
+ Assert.Same(field1, field4);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/MaxFieldSizeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/MaxFieldSizeTests.cs
new file mode 100644
index 0000000..98567c6
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/MaxFieldSizeTests.cs
@@ -0,0 +1,50 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests.Parsing
+{
+ public class MaxFieldSizeTests
+ {
+ [Fact]
+ public void LargeRecordFieldThrowsMaxFieldSizeExceptionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MaxFieldSize = 10
+ };
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("1,2,3");
+ s.AppendLine("ok,1234567890,x");
+ s.AppendLine("nok,12345678901,y");
+ using (var reader = new StringReader(s))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+ parser.Read();
+ Assert.Throws<MaxFieldSizeException>(() => parser.Read());
+ }
+ }
+
+ [Fact]
+ public void LargeHeaderFieldThrowsMaxFieldSizeExceptionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MaxFieldSize = 10
+ };
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("1,very long header name");
+ using (var reader = new StringReader(s))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.Throws<MaxFieldSizeException>(() => parser.Read());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/NewLineTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/NewLineTests.cs
new file mode 100644
index 0000000..b943450
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/NewLineTests.cs
@@ -0,0 +1,176 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class NewLineTests
+ {
+ [Fact]
+ public void Read_RfcMode_2CharNewLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a\b");
+ s.Append("1,one\a\b");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.RFC4180,
+ NewLine = "\a\b",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_RfcMode_1CharNewLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a");
+ s.Append("1,one\a");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.RFC4180,
+ NewLine = "\a",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_RfcMode_2CharNewLine_NoneOnLastLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a\b");
+ s.Append("1,one");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.RFC4180,
+ NewLine = "\a\b",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_EscapeMode_2CharNewLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a\b");
+ s.Append("1,one\a\b");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ NewLine = "\a\b",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_EscapeMode_1CharNewLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a");
+ s.Append("1,one\a");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ NewLine = "\a",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+
+ [Fact]
+ public void Read_EscapeMode_2CharNewLine_NoneOnLastLine_Parses()
+ {
+ var s = new StringBuilder();
+ s.Append("Id,Name\a\b");
+ s.Append("1,one");
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ NewLine = "\a\b",
+ };
+ using (var reader = new StringReader(s.ToString()))
+ using (var parser = new CsvParser(reader, config))
+ {
+ Assert.True(parser.Read());
+ Assert.Equal("Id", parser[0]);
+ Assert.Equal("Name", parser[1]);
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("one", parser[1]);
+
+ Assert.False(parser.Read());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/RefillingTextReaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/RefillingTextReaderTests.cs
new file mode 100644
index 0000000..9ad8c6f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/RefillingTextReaderTests.cs
@@ -0,0 +1,59 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class RefillingTextReaderTests
+ {
+ [Fact]
+ public void RefillTextReaderMultipleTimesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var parser = new CsvParser(reader, CultureInfo.InvariantCulture))
+ {
+ writer.Write("1,2\r\n");
+ writer.Flush();
+ stream.Position = 0;
+
+ Assert.True(parser.Read());
+ Assert.Equal("1", parser[0]);
+ Assert.Equal("2", parser[1]);
+ Assert.False(parser.Read());
+
+ var position = stream.Position;
+ writer.Write("3,4\r\n");
+ writer.Flush();
+ stream.Position = position;
+
+ Assert.True(parser.Read());
+ Assert.Equal("3", parser[0]);
+ Assert.Equal("4", parser[1]);
+ Assert.False(parser.Read());
+
+ position = stream.Position;
+ writer.Write("5,6\r\n");
+ writer.Flush();
+ stream.Position = position;
+
+ Assert.True(parser.Read());
+ Assert.Equal("5", parser[0]);
+ Assert.Equal("6", parser[1]);
+ Assert.False(parser.Read());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/TrimTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/TrimTests.cs
new file mode 100644
index 0000000..a4a4370
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Parsing/TrimTests.cs
@@ -0,0 +1,1206 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Parsing
+{
+
+ public class TrimTests
+ {
+ [Fact]
+ public void OutsideStartTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a,b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideStartNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideStartSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c,d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideStartSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c,d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideEndTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "a ,b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideEndNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "a ,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideEndSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "a b c ,d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideEndSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "a b c ,d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideBothTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a ,b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideBothNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a ,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideBothSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c ,d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideBothSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c ,d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesStartTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a\",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesStartNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a\",b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesStartSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a b c\",d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesStartSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a b c\",d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesEndTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a\" ,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesEndNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a\" ,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesEndSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a b c\" ,d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesEndSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a b c\" ,d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a\" ,b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a\" ,b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a b c\" ,d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \"a b c\" ,d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothSpacesInFieldMultipleRecordsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c , d e f \r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesBothSpacesInFieldMultipleRecordsNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " a b c , d e f ";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a\",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a\",b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c\",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c\",b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartSpacesInFieldDelimiterInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a ,b c\",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a ,b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesStartSpacesInFieldDelimiterInFieldSmallBufferNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ BufferSize = 1,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a ,b c\",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a ,b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesEndTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a \",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesEndNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a \",b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesEndSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a b c \",d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesEndSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\"a b c \",d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a \",b\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a \",b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesInFieldTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c \",d\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c \",d";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesInFieldMultipleRecordsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c \",\" d e f \"\r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesInFieldMultipleRecordsNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "\" a b c \",\" d e f \"";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideAndInsideQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim | TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \" a b c \" , \" d e f \" \r\n";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideAndInsideQuotesNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim | TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = " \" a b c \" , \" d e f \" ";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b c", parser[0]);
+ Assert.Equal("d e f", parser[1]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesNoSpacesNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "abc";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("abc", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void OutsideQuotesNoSpacesHasSpaceInFieldNoNewlineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var parser = new CsvParser(reader, config))
+ {
+ var line = "a b";
+ writer.Write(line);
+ writer.Flush();
+ stream.Position = 0;
+
+ parser.Read();
+
+ Assert.Equal("a b", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideNoSpacesQuotesFieldHasEscapedQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ var line = "\"a \"\"b\"\" c\"";
+ using (var reader = new StringReader(line))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("a \"b\" c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesFieldHasEscapedQuotesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ var line = "\" a \"\"b\"\" c \"\r\n";
+ using (var reader = new StringReader(line))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("a \"b\" c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void InsideQuotesBothSpacesFieldHasEscapedQuotesNoNewLineTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.InsideQuotes,
+ };
+ var line = "\" a \"\"b\"\" c \"";
+ using (var reader = new StringReader(line))
+ using (var parser = new CsvParser(reader, config))
+ {
+ parser.Read();
+
+ Assert.Equal("a \"b\" c", parser[0]);
+ Assert.Equal(line, parser.RawRecord.ToString());
+ }
+ }
+
+ [Fact]
+ public void ReadingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim | TrimOptions.InsideQuotes,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("A,B");
+ writer.WriteLine(" \" a b c \" , \" d e f \" ");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<dynamic>().ToList();
+
+ var record = records[0];
+ Assert.Equal("a b c", record.A);
+ Assert.Equal("d e f", record.B);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/AnonymousTypesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/AnonymousTypesTests.cs
new file mode 100644
index 0000000..79e537c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/AnonymousTypesTests.cs
@@ -0,0 +1,707 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class AnonymousTypesTests
+ {
+ [Fact]
+ public void ValueTypeSingleRecordTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ Name = string.Empty
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueTypeAllRecordsTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ Name = string.Empty
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueTypeAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ Name = string.Empty
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+
+ }
+
+ [Fact]
+ public void ReferenceTypeSingleRecordTest()
+ {
+ var definition = new
+ {
+ Reference = new Test()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ReferenceTypeAllRecordsTest()
+ {
+ var definition = new
+ {
+ Reference = new Test()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ReferenceTypeAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ Reference = new Test()
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueAndReferenceTypeSingleRecordTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ B = string.Empty,
+ Reference = new Test()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("A,Id,Name,B");
+ writer.WriteLine("-1,1,one,b");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(-1, record.A);
+ Assert.Equal("b", record.B);
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueAndReferenceTypeAllRecordsTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ B = string.Empty,
+ Reference = new Test()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("A,Id,Name,B");
+ writer.WriteLine("-1,1,one,b");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(-1, record.A);
+ Assert.Equal("b", record.B);
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueAndReferenceTypeAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ B = string.Empty,
+ Reference = new Test()
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("-1,b,1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(-1, record.A);
+ Assert.Equal("b", record.B);
+ Assert.Equal(1, record.Reference.Id);
+ Assert.Equal("one", record.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceSingleRecordTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ Name = string.Empty
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceAllRecordsTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ Name = string.Empty
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ Name = string.Empty
+ }
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasAnonymousReferenceSingleRecordTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ AnonymousReference2 = new
+ {
+ Name = string.Empty
+ }
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.AnonymousReference2.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasAnonymousReferenceAllRecordsTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ AnonymousReference2 = new
+ {
+ Name = string.Empty
+ }
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.AnonymousReference2.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasAnonymousReferenceAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ Id = 0,
+ AnonymousReference = new
+ {
+ AnonymousReference2 = new
+ {
+ Name = string.Empty
+ }
+ }
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.AnonymousReference.AnonymousReference2.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasReferenceSingleRecordTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ AnonymousReference = new
+ {
+ Reference = new Test()
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name,A");
+ writer.WriteLine("1,one,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(2, record.A);
+ Assert.Equal(1, record.AnonymousReference.Reference.Id);
+ Assert.Equal("one", record.AnonymousReference.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasReferenceAllRecordsTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ AnonymousReference = new
+ {
+ Reference = new Test()
+ }
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name,A");
+ writer.WriteLine("1,one,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(2, record.A);
+ Assert.Equal(1, record.AnonymousReference.Reference.Id);
+ Assert.Equal("one", record.AnonymousReference.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void AnonymousReferenceHasReferenceAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ A = 0,
+ AnonymousReference = new
+ {
+ Reference = new Test()
+ }
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("2,1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(2, record.A);
+ Assert.Equal(1, record.AnonymousReference.Reference.Id);
+ Assert.Equal("one", record.AnonymousReference.Reference.Name);
+ }
+ }
+
+ [Fact]
+ public void ParentChildReferenceSingleRecordTest()
+ {
+ var definition = new
+ {
+ Reference = new Child()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("ParentId,ChildId,ParentName,ChildName");
+ writer.WriteLine("1,2,one,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ var record = csv.GetRecord(definition);
+
+ Assert.Equal(1, record.Reference.ParentId);
+ Assert.Equal("one", record.Reference.ParentName);
+ Assert.Equal(2, record.Reference.ChildId);
+ Assert.Equal("two", record.Reference.ChildName);
+ }
+ }
+
+ [Fact]
+ public void ParentChildReferenceAllRecordsTest()
+ {
+ var definition = new
+ {
+ Reference = new Child()
+ };
+
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("ParentId,ChildId,ParentName,ChildName");
+ writer.WriteLine("1,2,one,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Reference.ParentId);
+ Assert.Equal("one", record.Reference.ParentName);
+ Assert.Equal(2, record.Reference.ChildId);
+ Assert.Equal("two", record.Reference.ChildName);
+ }
+ }
+
+ [Fact]
+ public void ParentChildReferenceAllRecordsNoHeaderTest()
+ {
+ var definition = new
+ {
+ Reference = new Child()
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,one,2,two");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords(definition).ToList();
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Reference.ChildId);
+ Assert.Equal("one", record.Reference.ChildName);
+ Assert.Equal(2, record.Reference.ParentId);
+ Assert.Equal("two", record.Reference.ParentName);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private class ContainsReference
+ {
+ public Test Test { get; set; }
+ }
+
+ private class Parent
+ {
+ public int ParentId { get; set; }
+
+ public string ParentName { get; set; }
+ }
+
+ private class Child : Parent
+ {
+ public int ChildId { get; set; }
+
+ public string ChildName { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/BadDataTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/BadDataTests.cs
new file mode 100644
index 0000000..b127478
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/BadDataTests.cs
@@ -0,0 +1,64 @@
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+ public class BadDataTests
+ {
+ [Fact]
+ public void GetRecord_BadDataCountNotDuplicted()
+ {
+ var errorCount = 0;
+ var csvConfiguration = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ReadingExceptionOccurred = args => false,
+ BadDataFound = args =>
+ {
+ ++errorCount;
+ },
+ Delimiter = ";",
+ };
+ var csv = "SKU;Min quantity;List price;Sale price\r\nTestSku1;2;10.99;9.99\r\nTestSku2;2;10.99;9\r\nXXX;\"9;10.9;9";
+ var stream = new MemoryStream();
+ using (var writer = new StreamWriter(stream, leaveOpen: true))
+ {
+ writer.Write(csv);
+ writer.Flush();
+ stream.Position = 0;
+ }
+ var textReader = new StreamReader(stream, leaveOpen: true);
+
+ var csvReader = new CsvReader(textReader, csvConfiguration);
+
+ while (csvReader.Read())
+ {
+ csvReader.GetRecord<CsvPrice>();
+ }
+
+ Assert.Equal(1, errorCount);
+ }
+
+ public sealed class CsvPrice
+ {
+ [Name("SKU")]
+ public string Sku { get; set; }
+
+ [Name("Min quantity")]
+ public int MinQuantity { get; set; }
+
+ [Name("List price")]
+ public decimal ListPrice { get; set; }
+
+ [Name("Sale price")]
+ public decimal? SalePrice { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstantTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstantTests.cs
new file mode 100644
index 0000000..9a9d3ac
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstantTests.cs
@@ -0,0 +1,114 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.IO;
+using System.Globalization;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class ConstantTests
+ {
+ [Fact]
+ public void ConstantAlwaysReturnsSameValueTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csv = new CsvReader(parser);
+ csv.Context.RegisterClassMap<TestStringMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("constant", records[0].Name);
+ Assert.Equal(2, records[1].Id);
+ Assert.Equal("constant", records[1].Name);
+ }
+
+ [Fact]
+ public void ConstantIsNullTest()
+ {
+ var rows = new Queue<string[]>();
+ rows.Enqueue(new[] { "Id", "Name" });
+ rows.Enqueue(new[] { "1", "one" });
+ rows.Enqueue(new[] { "2", "two" });
+ rows.Enqueue(null);
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "one" },
+ { "2", "two" },
+ };
+
+ var csv = new CsvReader(parser);
+ csv.Context.RegisterClassMap<TestNullMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(1, records[0].Id);
+ Assert.Null(records[0].Name);
+ Assert.Equal(2, records[1].Id);
+ Assert.Null(records[1].Name);
+ }
+
+ [Fact]
+ public void IntConstantTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var reader = new StringReader("1,one\r\n"))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.RegisterClassMap<TestIntMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(-1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestStringMap : ClassMap<Test>
+ {
+ public TestStringMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Constant("constant");
+ }
+ }
+
+ private sealed class TestNullMap : ClassMap<Test>
+ {
+ public TestNullMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Constant(null);
+ }
+ }
+
+ private sealed class TestIntMap : ClassMap<Test>
+ {
+ public TestIntMap()
+ {
+ Map(m => m.Id).Constant(-1);
+ Map(m => m.Name);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstructorParametersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstructorParametersTests.cs
new file mode 100644
index 0000000..a96df82
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ConstructorParametersTests.cs
@@ -0,0 +1,220 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class ConstructorParametersTests
+ {
+ [Fact]
+ public void ValueTypesParamsMatchPropsTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<ValueTypesParamsMatchProps>().ToList();
+
+ Assert.Single(records);
+
+ var record = records[0];
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ [Fact]
+ public void ValueTypesParamsDontMatchPropsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(args.Header)
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<ValueTypesParamsDontMatchProps>().ToList();
+
+ Assert.Single(records);
+
+ var record = records[0];
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ [Fact]
+ public void MultipleConstructorsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(args.Header)
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<MultipleConstructors>().ToList();
+
+ Assert.Single(records);
+
+ var record = records[0];
+
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ [Fact]
+ public void UseDifferentConstructorTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(args.Header),
+ GetConstructor = args => args.ClassType.GetConstructors().First(),
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<MultipleConstructors>().ToList();
+
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Null(record.Name);
+ }
+ }
+
+ [Fact]
+ public void UseDifferentConstructorWhenDefaultIsAvailableTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => CultureInfo.CurrentCulture.TextInfo.ToTitleCase(args.Header),
+ ShouldUseConstructorParameters = args =>
+ !args.ParameterType.IsUserDefinedStruct()
+ && !args.ParameterType.IsInterface
+ && Type.GetTypeCode(args.ParameterType) == TypeCode.Object,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<MultipleConstructorsWithDefault>().ToList();
+
+ Assert.Single(records);
+
+ var record = records[0];
+ Assert.Equal(1, record.Id);
+ Assert.Equal("one", record.Name);
+ }
+ }
+
+ private class ValueTypesParamsMatchProps
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public ValueTypesParamsMatchProps(int Id, string Name)
+ {
+ this.Id = Id;
+ this.Name = Name;
+ }
+ }
+
+ private class ValueTypesParamsDontMatchProps
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public ValueTypesParamsDontMatchProps(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class MultipleConstructors
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public MultipleConstructors(int id)
+ {
+ Id = id;
+ }
+
+ public MultipleConstructors(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+
+ public MultipleConstructors(string name)
+ {
+ Name = name;
+ }
+ }
+
+ private class MultipleConstructorsWithDefault
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; private set; }
+
+ public MultipleConstructorsWithDefault() { }
+
+ public MultipleConstructorsWithDefault(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DetectColumnCountChangesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DetectColumnCountChangesTests.cs
new file mode 100644
index 0000000..7139409
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DetectColumnCountChangesTests.cs
@@ -0,0 +1,199 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class DetectColumnCountChangesTests
+ {
+ [Fact]
+ public void ConsistentColumnsWithDetectColumnChangesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectColumnCountChanges = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Column 1,Column 2");
+ writer.WriteLine("1,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ while (!csv.Read())
+ {
+ }
+ }
+ }
+
+ [Fact]
+ public void InconsistentColumnsMultipleRowsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectColumnCountChanges = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Column 1,Column 2");
+ writer.WriteLine("1,2"); // Valid
+ writer.WriteLine("1,2,3"); // Error - too many fields
+ writer.WriteLine("1,2"); // Valid
+ writer.WriteLine("1"); // Error - not enough fields
+ writer.WriteLine("1,2,3,4"); // Error - too many fields
+ writer.WriteLine("1,2"); // Valid
+ writer.WriteLine("1,2"); // Valid
+ writer.Flush();
+ stream.Position = 0;
+
+ var failCount = 0;
+
+ while (true)
+ {
+ try
+ {
+ if (!csv.Read())
+ {
+ break;
+ }
+ }
+ catch (BadDataException)
+ {
+ failCount++;
+ }
+ }
+
+ // Expect only 3 errors
+ Assert.Equal<int>(3, failCount);
+ }
+ }
+
+ [Fact]
+ public void InconsistentColumnsSmallerTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectColumnCountChanges = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4");
+ writer.WriteLine("5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+
+ try
+ {
+ csv.Read();
+ throw new XUnitException();
+ }
+ catch (BadDataException)
+ {
+ }
+ }
+ }
+
+ [Fact]
+ public void InconsistentColumnsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectColumnCountChanges = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Column 1,Column 2");
+ writer.WriteLine("1,2,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+
+ try
+ {
+ csv.Read();
+ throw new XUnitException();
+ }
+ catch (BadDataException)
+ {
+ }
+ }
+ }
+
+ [Fact]
+ public void WillThrowOnMissingFieldStillWorksTest()
+ {
+ var missingFieldExceptionCount = 0;
+ var columnCountChangeExceptionCount = 0;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DetectColumnCountChanges = true,
+ HeaderValidated = null,
+ ReadingExceptionOccurred = (args) =>
+ {
+ if (args.Exception is MissingFieldException)
+ {
+ missingFieldExceptionCount++;
+ }
+ else if (args.Exception is BadDataException)
+ {
+ columnCountChangeExceptionCount++;
+ }
+
+ return false;
+ },
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3");
+ writer.WriteLine("4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+ Assert.Equal(1, missingFieldExceptionCount);
+ Assert.Equal(1, columnCountChangeExceptionCount);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DynamicTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DynamicTests.cs
new file mode 100644
index 0000000..d843eb0
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/DynamicTests.cs
@@ -0,0 +1,126 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class DynamicTests
+ {
+ [Fact]
+ public void PrepareHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args => args.Header.Replace(" ", string.Empty),
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("O ne,Tw o,Thr ee");
+ writer.WriteLine("1,2,3");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<dynamic>().ToList();
+ Assert.Equal("1", records[0].One);
+ Assert.Equal("2", records[0].Two);
+ Assert.Equal("3", records[0].Three);
+ }
+ }
+
+ [Fact]
+ public void BlankHeadersTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ PrepareHeaderForMatch = args =>
+ {
+ if (string.IsNullOrWhiteSpace(args.Header))
+ {
+ return $"Blank{args.FieldIndex}";
+ }
+
+ return args.Header;
+ },
+ };
+ var s = new StringBuilder();
+ s.AppendLine("Id,,");
+ s.AppendLine("1,2");
+ s.AppendLine("3");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, config))
+ {
+ var records = csv.GetRecords<dynamic>().ToList();
+
+ var record = records[0];
+ Assert.Equal("1", record.Id);
+ Assert.Equal("2", record.Blank1);
+ Assert.Equal(null, record.Blank2);
+
+ record = records[1];
+ Assert.Equal("3", record.Id);
+ Assert.Equal(null, record.Blank1);
+ Assert.Equal(null, record.Blank2);
+ }
+ }
+
+ [Fact]
+ public void DuplicateFieldNamesTest()
+ {
+ var headerNameCounts = new Dictionary<string, int>();
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ GetDynamicPropertyName = args =>
+ {
+ var header = args.Context.Reader.HeaderRecord[args.FieldIndex];
+ var prepareHeaderForMatchArgs = new PrepareHeaderForMatchArgs(header, args.FieldIndex);
+ header = args.Context.Reader.Configuration.PrepareHeaderForMatch(prepareHeaderForMatchArgs);
+ var name = headerNameCounts[header] > 1 ? $"{header}{args.FieldIndex}" : header;
+
+ return name;
+ },
+ };
+ var parser = new ParserMock(config)
+ {
+ { "Id", "Name", "Name" },
+ { "1", "foo", "bar" },
+ null
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Read();
+ csv.ReadHeader();
+ var counts =
+ (from header in csv.Context.Reader.HeaderRecord.Select((h, i) => csv.Configuration.PrepareHeaderForMatch(new PrepareHeaderForMatchArgs(h, i)))
+ group header by header into g
+ select new
+ {
+ Header = g.Key,
+ Count = g.Count()
+ }).ToDictionary(x => x.Header, x => x.Count);
+ foreach (var count in counts)
+ {
+ headerNameCounts.Add(count.Key, count.Value);
+ }
+
+ var records = csv.GetRecords<dynamic>().ToList();
+ var record = records[0];
+ Assert.Equal("1", record.Id);
+ Assert.Equal("foo", record.Name1);
+ Assert.Equal("bar", record.Name2);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/EmptyTextReaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/EmptyTextReaderTests.cs
new file mode 100644
index 0000000..0400092
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/EmptyTextReaderTests.cs
@@ -0,0 +1,25 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class EmptyTextReaderTests
+ {
+ [Fact]
+ public void EmptyStreamDoesntFailTest()
+ {
+ using( var stream = new MemoryStream() )
+ using( var reader = new StreamReader( stream ) )
+ using( var csv = new CsvReader(reader, CultureInfo.InvariantCulture) )
+ {
+ Assert.False( csv.Read() );
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleGetRecordsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleGetRecordsTests.cs
new file mode 100644
index 0000000..5aeed79
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleGetRecordsTests.cs
@@ -0,0 +1,60 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class MultipleGetRecordsTests
+ {
+ [Fact]
+ public void GetRecordsAfterRefillingReaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<Test>().ToList();
+
+ var position = stream.Position;
+ writer.WriteLine("2,two");
+ writer.Flush();
+ stream.Position = position;
+
+ records = csv.GetRecords<Test>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(2, records[0].Id);
+ Assert.Equal("two", records[0].Name);
+
+ position = stream.Position;
+ writer.WriteLine("3,three");
+ writer.Flush();
+ stream.Position = position;
+
+ records = csv.GetRecords<Test>().ToList();
+
+ Assert.Single(records);
+ Assert.Equal(3, records[0].Id);
+ Assert.Equal("three", records[0].Name);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleHeadersTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleHeadersTests.cs
new file mode 100644
index 0000000..49a0b22
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/MultipleHeadersTests.cs
@@ -0,0 +1,114 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class MultipleHeadersTests
+ {
+ [Fact]
+ public void ReadWithoutMapTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("A,B");
+ writer.WriteLine("1,one");
+ writer.WriteLine("Y,Z");
+ writer.WriteLine("two,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.Equal(1, csv.GetField<int>("A"));
+ Assert.Equal("one", csv.GetField("B"));
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.Equal("two", csv.GetField("Y"));
+ Assert.Equal(2, csv.GetField<int>("Z"));
+ }
+ }
+
+ [Fact]
+ public void ReadWithMapTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("A,B");
+ writer.WriteLine("1,one");
+ writer.WriteLine("Y,Z");
+ writer.WriteLine("two,2");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<AlphaMap>();
+ csv.Context.RegisterClassMap<OmegaMap>();
+
+ csv.Read();
+ csv.ReadHeader();
+
+ csv.Read();
+ var alphaRecord = csv.GetRecord<Alpha>();
+
+ Assert.Equal(1, alphaRecord.A);
+ Assert.Equal("one", alphaRecord.B);
+
+ csv.Read();
+ csv.ReadHeader();
+
+ csv.Read();
+ var omegaRecord = csv.GetRecord<Omega>();
+
+ Assert.Equal("two", omegaRecord.Y);
+ Assert.Equal(2, omegaRecord.Z);
+ }
+ }
+
+ private class Alpha
+ {
+ public int A { get; set; }
+ public string B { get; set; }
+ }
+
+ private class Omega
+ {
+ public string Y { get; set; }
+ public int Z { get; set; }
+ }
+
+ private sealed class AlphaMap : ClassMap<Alpha>
+ {
+ public AlphaMap()
+ {
+ Map(m => m.A);
+ Map(m => m.B);
+ }
+ }
+
+ private sealed class OmegaMap : ClassMap<Omega>
+ {
+ public OmegaMap()
+ {
+ Map(m => m.Y);
+ Map(m => m.Z);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/NullableValuesInEmptyColumnsInputTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/NullableValuesInEmptyColumnsInputTests.cs
new file mode 100644
index 0000000..c5fcdd5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/NullableValuesInEmptyColumnsInputTests.cs
@@ -0,0 +1,224 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System.Globalization;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class NullableValuesInEmptyColumnsInputTests
+ {
+ [Fact]
+ public void SingleColumnCsvWithHeadersAndSingleNullDataRowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ MissingFieldFound = null,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NullableInt32Field" },
+ { new string[0] },
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<int?>().NullValues.Add(string.Empty);
+
+ // Read header row, assert header row columns:
+ Assert.True(csv.Read());
+ Assert.True(csv.ReadHeader());
+ Assert.Single(csv.HeaderRecord);
+ Assert.Equal("NullableInt32Field", csv.HeaderRecord[0]);
+
+ // Read single data row, assert single null value:
+ Assert.True(csv.Read());
+
+ var nullableIntValueByIndex = csv.GetField<int?>(index: 0);
+ var nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.False(nullableIntValueByIndex.HasValue);
+ Assert.False(nullableIntValueByName.HasValue);
+
+ // Read to end of file:
+ Assert.False(csv.Read());
+ }
+ }
+
+ [Fact]
+ public void SingleColumnCsvWithHeadersAndPresentAndNullDataRowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ MissingFieldFound = null,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NullableInt32Field" },
+ { "1" },
+ { new string[0] },
+ { "3" },
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<int?>().NullValues.Add(string.Empty);
+
+ // Read header row, assert header row columns:
+ Assert.True(csv.Read());
+ Assert.True(csv.ReadHeader());
+ Assert.Single(csv.HeaderRecord);
+ Assert.Equal("NullableInt32Field", csv.HeaderRecord[0]);
+
+ // Read first data row, assert "1" value:
+ Assert.True(csv.Read());
+
+ var nullableIntValueByIndex = csv.GetField<int?>(0);
+ var nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.True(nullableIntValueByIndex.HasValue);
+ Assert.True(nullableIntValueByName.HasValue);
+
+ Assert.Equal(1, nullableIntValueByIndex);
+ Assert.Equal(1, nullableIntValueByName);
+
+ // Read second data row, assert null value:
+ Assert.True(csv.Read());
+
+ nullableIntValueByIndex = csv.GetField<int?>(0);
+ nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.False(nullableIntValueByIndex.HasValue);
+ Assert.False(nullableIntValueByName.HasValue);
+
+ // Read third data row, assert "3" value:
+ Assert.True(csv.Read());
+
+ nullableIntValueByIndex = csv.GetField<int?>(0);
+ nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.True(nullableIntValueByIndex.HasValue);
+ Assert.True(nullableIntValueByName.HasValue);
+
+ Assert.Equal(3, nullableIntValueByIndex);
+ Assert.Equal(3, nullableIntValueByName);
+
+ // Read to end of file:
+ Assert.False(csv.Read());
+ }
+ }
+
+ [Fact]
+ public void TwoColumnCsvWithHeadersAndPresentAndNullDataRowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IgnoreBlankLines = false,
+ MissingFieldFound = null,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NullableInt32Field", "NullableStringField" },
+ { "1" },
+ { "", "Foo" },
+ { "", "" },
+ { "4", "Bar" },
+ };
+
+ using (var csv = new CsvReader(parser))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add(string.Empty); // Read empty fields as nulls instead of `""`.
+
+ // Read header row, assert header row columns:
+ Assert.True(csv.Read());
+ Assert.True(csv.ReadHeader());
+ Assert.Equal(2, csv.HeaderRecord.Length);
+ Assert.Equal("NullableInt32Field", csv.HeaderRecord[0]);
+ Assert.Equal("NullableStringField", csv.HeaderRecord[1]);
+
+ // Read first data row:
+ Assert.True(csv.Read());
+
+ // Read `Int32?`, assert "1" value:
+ var nullableIntValueByIndex = csv.GetField<int?>(0);
+ var nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.True(nullableIntValueByIndex.HasValue);
+ Assert.True(nullableIntValueByName.HasValue);
+
+ Assert.Equal(1, nullableIntValueByIndex);
+ Assert.Equal(1, nullableIntValueByName);
+
+ // Read nullable String, assert null value:
+ var strByIndex = csv.GetField<string>(1);
+ var strByName = csv.GetField<string>("NullableStringField");
+
+ Assert.Null(strByIndex);
+ Assert.Null(strByName);
+
+ // Read second data row:
+ Assert.True(csv.Read());
+
+ // Read `Int32?`, assert NULL value:
+ nullableIntValueByIndex = csv.GetField<int?>(0);
+ nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.False(nullableIntValueByIndex.HasValue);
+ Assert.False(nullableIntValueByName.HasValue);
+
+ // Read nullable String, assert "Foo" value:
+ strByIndex = csv.GetField<string>(1);
+ strByName = csv.GetField<string>("NullableStringField");
+
+ Assert.Equal("Foo", strByIndex);
+ Assert.Equal("Foo", strByName);
+
+ // Read third data row:
+ Assert.True(csv.Read());
+
+ // Read `Int32?`, assert NULL value:
+ nullableIntValueByIndex = csv.GetField<int?>(0);
+ nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.False(nullableIntValueByIndex.HasValue);
+ Assert.False(nullableIntValueByName.HasValue);
+
+ // Read nullable String, assert "Foo" value:
+ strByIndex = csv.GetField<string>(1);
+ strByName = csv.GetField<string>("NullableStringField");
+
+ Assert.Null(strByIndex);
+ Assert.Null(strByName);
+
+ // Read fourth data row:
+ Assert.True(csv.Read());
+
+ // Read `Int32?`, assert "3" value:
+ nullableIntValueByIndex = csv.GetField<int?>(0);
+ nullableIntValueByName = csv.GetField<int?>("NullableInt32Field");
+
+ Assert.True(nullableIntValueByIndex.HasValue);
+ Assert.True(nullableIntValueByName.HasValue);
+
+ Assert.Equal(4, nullableIntValueByIndex);
+ Assert.Equal(4, nullableIntValueByName);
+
+ // Read nullable String, assert "Bar" value:
+ strByIndex = csv.GetField<string>(1);
+ strByName = csv.GetField<string>("NullableStringField");
+
+ Assert.Equal("Bar", strByIndex);
+ Assert.Equal("Bar", strByName);
+
+ // Read to end of file:
+ Assert.False(csv.Read());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/PrivateSettersInParentTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/PrivateSettersInParentTests.cs
new file mode 100644
index 0000000..af192f0
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/PrivateSettersInParentTests.cs
@@ -0,0 +1,90 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class PrivateSettersInParentTests
+ {
+ [Fact]
+ public void AutoMappingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IncludePrivateMembers = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ var records = csv.GetRecords<Child>().ToList();
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void ClassMappingTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ IncludePrivateMembers = true,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<ChildMap>();
+
+ var records = csv.GetRecords<Child>().ToList();
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal("one", records[0].Name);
+ }
+ }
+
+ private class Parent
+ {
+ public int Id { get; private set; }
+
+ public string Name { get; set; }
+
+ public Parent() { }
+
+ public Parent(int id, string name)
+ {
+ Id = id;
+ Name = name;
+ }
+ }
+
+ private class Child : Parent { }
+
+ private sealed class ChildMap : ClassMap<Child>
+ {
+ public ChildMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ReadHeaderTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ReadHeaderTests.cs
new file mode 100644
index 0000000..a502db4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ReadHeaderTests.cs
@@ -0,0 +1,166 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class ReadHeaderTests
+ {
+ [Fact]
+ public void ReadHeaderReadsHeaderTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "One" },
+ { "2", "two" },
+ null
+ };
+
+ var csv = new CsvReader(parser);
+ csv.Read();
+ csv.ReadHeader();
+
+ Assert.NotNull(csv.HeaderRecord);
+ Assert.Equal("Id", csv.HeaderRecord[0]);
+ Assert.Equal("Name", csv.HeaderRecord[1]);
+ }
+
+ [Fact]
+ public void ReadHeaderDoesNotAffectCurrentRecordTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "One" },
+ { "2", "two" },
+ null,
+ };
+
+ var csv = new CsvReader(parser);
+ csv.Read();
+ csv.ReadHeader();
+
+ Assert.Equal("Id", csv.Parser[0]);
+ Assert.Equal("Name", csv.Parser[1]);
+ }
+
+ [Fact]
+ public void ReadingHeaderFailsWhenReaderIsDoneTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "Id", "Name" },
+ { "1", "One" },
+ { "2", "two" },
+ null,
+ };
+
+ var csv = new CsvReader(parser);
+ while (csv.Read()) { }
+
+ Assert.Throws<ReaderException>(() => csv.ReadHeader());
+ }
+
+ [Fact]
+ public void ReadingHeaderFailsWhenNoHeaderRecordTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "Id", "Name" },
+ { "1", "One" },
+ { "2", "two" },
+ null
+ };
+
+ var csv = new CsvReader(parser);
+
+ Assert.Throws<ReaderException>(() => csv.ReadHeader());
+ }
+
+ [Fact]
+ public void ReadingHeaderDoesNotFailWhenHeaderAlreadyReadTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1", "One" },
+ { "2", "two" },
+ null
+ };
+
+ var csv = new CsvReader(parser);
+ csv.Read();
+ csv.ReadHeader();
+ csv.ReadHeader();
+ }
+
+ [Fact]
+ public void ReadHeaderResetsNamedIndexesTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name" },
+ { "Name", "Id" },
+ };
+ var csv = new CsvReader(parser);
+ csv.Read();
+ csv.ReadHeader();
+
+ Assert.Equal(0, csv.GetFieldIndex("Id"));
+ Assert.Equal(1, csv.GetFieldIndex("Name"));
+
+ csv.Read();
+ csv.ReadHeader();
+
+ Assert.Equal(1, csv.GetFieldIndex("Id"));
+ Assert.Equal(0, csv.GetFieldIndex("Name"));
+ }
+
+ [Fact]
+ public void MultipleReadHeaderCallsWorksWithNamedIndexCacheTest()
+ {
+ var parser = new ParserMock
+ {
+ { "Id", "Name", "Id", "Name" },
+ { "1", "one", "2", "two" },
+ { "Name", "Id", "Name", "Id" },
+ { "three", "3", "four", "4" },
+ };
+ var csv = new CsvReader(parser);
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.Equal(1, csv.GetField<int>("Id"));
+ Assert.Equal("one", csv.GetField("Name"));
+ Assert.Equal(2, csv.GetField<int>("Id", 1));
+ Assert.Equal("two", csv.GetField("Name", 1));
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+
+ Assert.Equal(3, csv.GetField<int>("Id"));
+ Assert.Equal("three", csv.GetField("Name"));
+ Assert.Equal(4, csv.GetField<int>("Id", 1));
+ Assert.Equal("four", csv.GetField("Name", 1));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ShouldSkipRecordTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ShouldSkipRecordTests.cs
new file mode 100644
index 0000000..cac1fd8
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ShouldSkipRecordTests.cs
@@ -0,0 +1,87 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class ShouldSkipRecordTests
+ {
+ [Fact]
+ public void SkipEmptyHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldSkipRecord = args => args.Row.Parser.Record.All(string.IsNullOrWhiteSpace),
+ };
+ var parser = new ParserMock(config)
+ {
+ { " " },
+ { "First,Second" },
+ { "1", "2" },
+ };
+
+ var csv = new CsvReader(parser);
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ Assert.Equal("1", csv.GetField(0));
+ Assert.Equal("2", csv.GetField(1));
+ }
+
+ [Fact]
+ public void SkipEmptyRowTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldSkipRecord = args => args.Row.Parser.Record.All(string.IsNullOrWhiteSpace),
+ };
+ var parser = new ParserMock(config)
+ {
+ { "First,Second" },
+ { " " },
+ { "1", "2" },
+ };
+
+ var csv = new CsvReader(parser);
+
+ csv.Read();
+ csv.ReadHeader();
+ csv.Read();
+ Assert.Equal("1", csv.GetField(0));
+ Assert.Equal("2", csv.GetField(1));
+ }
+
+ [Fact]
+ public void ShouldSkipWithEmptyRows()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldSkipRecord = args => args.Row[0].StartsWith("skipme") || args.Row.Parser.Record.All(string.IsNullOrWhiteSpace),
+ };
+
+ var parser = new ParserMock(config)
+ {
+ { "First,Second" },
+ { "skipme," },
+ { "" },
+ { "1", "2" },
+ };
+
+ var csv = new CsvReader(parser);
+
+ csv.Read();
+ csv.Read();
+ Assert.Equal("1", csv.GetField(0));
+ Assert.Equal("2", csv.GetField(1));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/TryGetTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/TryGetTests.cs
new file mode 100644
index 0000000..2814fb2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/TryGetTests.cs
@@ -0,0 +1,228 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class TryGetTests
+ {
+ [Fact]
+ public void TryGetFieldInvalidIndexTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "One", "Two" },
+ new[] { "one", "two" },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ var got = reader.TryGetField(0, out int field);
+ Assert.False(got);
+ Assert.Equal(default(int), field);
+ }
+
+ [Fact]
+ public void TryGetFieldInvalidNameTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "One", "Two" },
+ new[] { "one", "two" },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+
+ var got = reader.TryGetField("One", out int field);
+ Assert.False(got);
+ Assert.Equal(default(int), field);
+ }
+
+ [Fact]
+ public void TryGetFieldTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "One", "Two" },
+ new[] { "1", "2" },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ var got = reader.TryGetField(0, out int field);
+ Assert.True(got);
+ Assert.Equal(1, field);
+ }
+
+ [Fact]
+ public void TryGetFieldStrictTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "One", "Two" },
+ new[] { "1", "2" },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ var got = reader.TryGetField("One", out int field);
+ Assert.True(got);
+ Assert.Equal(1, field);
+ }
+
+ [Fact]
+ public void TryGetFieldEmptyDate()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+
+ // DateTimeConverter.IsValid() doesn't work correctly
+ // so we need to test and make sure that the conversion
+ // fails for an empty string for a date.
+ var parserMock = new ParserMock(config)
+ {
+ new[] { " " },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ var got = reader.TryGetField(0, out DateTime field);
+
+ Assert.False(got);
+ Assert.Equal(DateTime.MinValue, field);
+ }
+
+ [Fact]
+ public void TryGetNullableFieldEmptyDate()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+
+ // DateTimeConverter.IsValid() doesn't work correctly
+ // so we need to test and make sure that the conversion
+ // fails for an empty string for a date.
+ var parserMock = new ParserMock(config)
+ {
+ new[] { " " },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+
+ var got = reader.TryGetField(0, out DateTime? field);
+
+ Assert.False(got);
+ Assert.Null(field);
+ }
+
+ [Fact]
+ public void TryGetDoesNotThrowWhenWillThrowOnMissingFieldIsEnabled()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+
+ var parserMock = new ParserMock(config)
+ {
+ new[] { "1" },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ Assert.False(reader.TryGetField("test", out string field));
+ }
+
+ [Fact]
+ public void TryGetFieldIndexTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "One", "Two", "Two" },
+ { "1", "2", "3" }
+ };
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ var got = reader.TryGetField("Two", 0, out int field);
+ Assert.True(got);
+ Assert.Equal(2, field);
+
+ got = reader.TryGetField("Two", 1, out field);
+ Assert.True(got);
+ Assert.Equal(3, field);
+ }
+
+ [Fact]
+ public void TryGetMissingDateTimeFieldTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "Name" },
+ { "1" },
+ null
+ };
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ var got = reader.TryGetField(typeof(DateTime), "Name", out object field);
+
+ Assert.False(got);
+ Assert.Equal(DateTime.MinValue, field);
+ }
+
+ [Fact]
+ public void TryGetMissingDateTimeOffsetFieldTest()
+ {
+ var parserMock = new ParserMock
+ {
+ { "Id", "DateTime" },
+ { "1" },
+ null
+ };
+ var reader = new CsvReader(parserMock);
+ reader.Read();
+ reader.ReadHeader();
+ reader.Read();
+
+ var got = reader.TryGetField(typeof(DateTimeOffset), "DateTime", out object field);
+
+ Assert.False(got);
+ Assert.Equal(DateTimeOffset.MinValue, field);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ValidateTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ValidateTests.cs
new file mode 100644
index 0000000..1b9da38
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/ValidateTests.cs
@@ -0,0 +1,197 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using Xunit;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class ValidateTests
+ {
+ [Fact]
+ public void GenericValidateTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine(",one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<GenericValidateMap>();
+ Assert.Throws<FieldValidationException>(() => csv.GetRecords<Test>().ToList());
+ }
+ }
+
+ [Fact]
+ public void NonGenericValidateTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine(",one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<NonGenericValidateMap>();
+ Assert.Throws<FieldValidationException>(() => csv.GetRecords<Test>().ToList());
+ }
+ }
+
+ [Fact]
+ public void LogInsteadTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine("1,");
+ writer.Flush();
+ stream.Position = 0;
+
+ var logger = new StringBuilder();
+ csv.Context.RegisterClassMap(new LogInsteadMap(logger));
+ csv.GetRecords<Test>().ToList();
+
+ var expected = new StringBuilder();
+ expected.AppendLine("Field '' is not valid!");
+
+ Assert.Equal(expected.ToString(), logger.ToString());
+ }
+ }
+
+ [Fact]
+ public void CustomExceptionTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ MissingFieldFound = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Id,Name");
+ writer.WriteLine(",one");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<CustomExceptionMap>();
+ Assert.Throws<CustomException>(() => csv.GetRecords<Test>().ToList());
+ }
+ }
+
+ [Fact]
+ public void ValidateMessageTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ };
+ var s = new TestStringBuilder(config.NewLine);
+ s.AppendLine("Id,Name");
+ s.AppendLine("1,one");
+ using (var reader = new StringReader(s))
+ using (var csv = new CsvReader(reader, config))
+ {
+ csv.Context.RegisterClassMap<ValidationMessageMap>();
+ var exception = Assert.Throws<FieldValidationException>(() => csv.GetRecords<Test>().ToList());
+ Assert.StartsWith("Field 'one' was not foo.", exception.Message);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class GenericValidateMap : ClassMap<Test>
+ {
+ public GenericValidateMap()
+ {
+ Map(m => m.Id).Validate(args => !string.IsNullOrEmpty(args.Field));
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class NonGenericValidateMap : ClassMap<Test>
+ {
+ public NonGenericValidateMap()
+ {
+ AutoMap(System.Globalization.CultureInfo.InvariantCulture);
+ foreach (var memberMap in MemberMaps)
+ {
+ Map(typeof(Test), memberMap.Data.Member).Validate(args => !string.IsNullOrEmpty(args.Field));
+ }
+ }
+ }
+
+ private sealed class LogInsteadMap : ClassMap<Test>
+ {
+ public LogInsteadMap(StringBuilder logger)
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Validate(args =>
+ {
+ var isValid = !string.IsNullOrEmpty(args.Field);
+ if (!isValid)
+ {
+ logger.AppendLine($"Field '{args.Field}' is not valid!");
+ }
+
+ return true;
+ });
+ }
+ }
+
+ private sealed class CustomExceptionMap : ClassMap<Test>
+ {
+ public CustomExceptionMap()
+ {
+ Map(m => m.Id).Validate(field => throw new CustomException());
+ Map(m => m.Name);
+ }
+ }
+
+ private class CustomException : CsvHelperException
+ {
+ }
+
+ private class ValidationMessageMap : ClassMap<Test>
+ {
+ public ValidationMessageMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Validate(args => args.Field == "foo", args => $"Field '{args.Field}' was not foo.");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/YieldTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/YieldTests.cs
new file mode 100644
index 0000000..a39d899
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reading/YieldTests.cs
@@ -0,0 +1,142 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Reading
+{
+
+ public class YieldTests
+ {
+ [Fact]
+ public void GetRecordsGeneric_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ IEnumerable<Foo> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.GetRecords<Foo>();
+ }
+ Assert.Throws<ObjectDisposedException>(() => records.ToList());
+ }
+
+ [Fact]
+ public void GetRecords_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ IEnumerable<object> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.GetRecords(typeof(Foo));
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => records.ToList());
+ }
+
+ [Fact]
+ public void EnumerateRecords_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ Foo record = null;
+ IEnumerable<Foo> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.EnumerateRecords(record);
+ }
+
+ Assert.Throws<ObjectDisposedException>(() => records.ToList());
+ }
+
+#if !NET45
+ [Fact]
+ public async Task GetRecordsAsyncGeneric_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ IAsyncEnumerable<Foo> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.GetRecordsAsync<Foo>();
+ }
+
+ await Assert.ThrowsAsync<ObjectDisposedException>(async () => await records.GetAsyncEnumerator().MoveNextAsync());
+ }
+
+ [Fact]
+ public async Task GetRecordsAsync_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ IAsyncEnumerable<object> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.GetRecordsAsync(typeof(Foo));
+ }
+
+ await Assert.ThrowsAsync<ObjectDisposedException>(async () => await records.GetAsyncEnumerator().MoveNextAsync());
+ }
+
+ [Fact]
+ public async Task EnumerateRecordsAsync_Disposed_ThrowsObjectDisposedExceptionTest()
+ {
+ var parserMock = new ParserMock
+ {
+ new[] { "Id", "Name" },
+ new[] { "1", "one" },
+ null
+ };
+
+ Foo record = null;
+ IAsyncEnumerable<Foo> records;
+ using (var csv = new CsvReader(parserMock))
+ {
+ records = csv.EnumerateRecordsAsync(record);
+ }
+
+ await Assert.ThrowsAsync<ObjectDisposedException>(async () => await records.GetAsyncEnumerator().MoveNextAsync());
+ }
+#endif
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingClassMapTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingClassMapTests.cs
new file mode 100644
index 0000000..bc0b210
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingClassMapTests.cs
@@ -0,0 +1,169 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class ReferenceMappingClassMapTests
+ {
+ [Fact]
+ public void ReferenceMappingTest()
+ {
+ var parserMock = new ParserMock
+ {
+ {
+ "FirstName",
+ "LastName",
+ "HomeStreet",
+ "HomeCity",
+ "HomeState",
+ "HomeZip",
+ "WorkStreet",
+ "WorkCity",
+ "WorkState",
+ "WorkZip"
+ },
+ };
+ var row = new[]
+ {
+ "John",
+ "Doe",
+ "1234 Home St",
+ "Home Town",
+ "Home State",
+ "12345",
+ "5678 Work Rd",
+ "Work City",
+ "Work State",
+ "67890"
+ };
+ parserMock.Add(row);
+
+ var reader = new CsvReader(parserMock);
+ reader.Context.RegisterClassMap<PersonMap>();
+ reader.Read();
+ var person = reader.GetRecord<Person>();
+
+ Assert.Equal(row[0], person.FirstName);
+ Assert.Equal(row[1], person.LastName);
+ Assert.Equal(row[2], person.HomeAddress.Street);
+ Assert.Equal(row[3], person.HomeAddress.City);
+ Assert.Equal(row[4], person.HomeAddress.State);
+ Assert.Equal(row[5], person.HomeAddress.Zip);
+ Assert.Equal(row[6], person.WorkAddress.Street);
+ Assert.Equal(row[7], person.WorkAddress.City);
+ Assert.Equal(row[8], person.WorkAddress.State);
+ Assert.Equal(row[9], person.WorkAddress.Zip);
+ }
+
+ [Fact]
+ public void OnlyReferencesTest()
+ {
+ var parserMock = new ParserMock()
+ {
+ new[]
+ {
+ "FirstName",
+ "LastName",
+ "HomeStreet",
+ "HomeCity",
+ "HomeState",
+ "HomeZip",
+ "WorkStreet",
+ "WorkCity",
+ "WorkState",
+ "WorkZip"
+ },
+ new[]
+ {
+ "John",
+ "Doe",
+ "1234 Home St",
+ "Home Town",
+ "Home State",
+ "12345",
+ "5678 Work Rd",
+ "Work City",
+ "Work State",
+ "67890"
+ },
+ null
+ };
+
+ var reader = new CsvReader(parserMock);
+ reader.Context.RegisterClassMap<OnlyReferencesMap>();
+ reader.Read();
+ var person = reader.GetRecord<Person>();
+ }
+
+ private class Person
+ {
+ public string FirstName { get; set; }
+
+ public string LastName { get; set; }
+
+ public Address HomeAddress { get; set; }
+
+ public Address WorkAddress { get; set; }
+ }
+
+ private class Address
+ {
+ public string Street { get; set; }
+
+ public string City { get; set; }
+
+ public string State { get; set; }
+
+ public string Zip { get; set; }
+ }
+
+ private sealed class PersonMap : ClassMap<Person>
+ {
+ public PersonMap()
+ {
+ Map(m => m.FirstName);
+ Map(m => m.LastName);
+ References<HomeAddressMap>(m => m.HomeAddress);
+ References<WorkAddressMap>(m => m.WorkAddress);
+ }
+ }
+
+ private sealed class HomeAddressMap : ClassMap<Address>
+ {
+ public HomeAddressMap()
+ {
+ Map(m => m.Street).Name("HomeStreet");
+ Map(m => m.City).Name("HomeCity");
+ Map(m => m.State).Name("HomeState");
+ Map(m => m.Zip).Name("HomeZip");
+ }
+ }
+
+ private sealed class WorkAddressMap : ClassMap<Address>
+ {
+ public WorkAddressMap()
+ {
+ Map(m => m.Street).Name("WorkStreet");
+ Map(m => m.City).Name("WorkCity");
+ Map(m => m.State).Name("WorkState");
+ Map(m => m.Zip).Name("WorkZip");
+ }
+ }
+
+ private sealed class OnlyReferencesMap : ClassMap<Person>
+ {
+ public OnlyReferencesMap()
+ {
+ References<HomeAddressMap>(m => m.HomeAddress);
+ References<WorkAddressMap>(m => m.WorkAddress);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingIndexTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingIndexTests.cs
new file mode 100644
index 0000000..e926f79
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/ReferenceMappingIndexTests.cs
@@ -0,0 +1,69 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests
+{
+
+ public class ReferenceMappingIndexTests
+ {
+ [Fact]
+ public void MapByIndexTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ new[] { "0", "1" },
+ new[] { "2", "3" },
+ };
+
+ var csv = new CsvReader(parserMock);
+ csv.Context.RegisterClassMap<AMap>();
+
+ var records = csv.GetRecords<A>().ToList();
+ Assert.Equal(1, records[0].Id);
+ Assert.Equal(0, records[0].B.Id);
+ Assert.Equal(3, records[1].Id);
+ Assert.Equal(2, records[1].B.Id);
+ }
+
+ private class A
+ {
+ public int Id { get; set; }
+
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public int Id { get; set; }
+ }
+
+ private sealed class AMap : ClassMap<A>
+ {
+ public AMap()
+ {
+ Map(m => m.Id).Index(1);
+ References<BMap>(m => m.B);
+ }
+ }
+
+ private sealed class BMap : ClassMap<B>
+ {
+ public BMap()
+ {
+ Map(m => m.Id).Index(0);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reflection/GetMemberExpressionStackTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reflection/GetMemberExpressionStackTests.cs
new file mode 100644
index 0000000..a779081
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Reflection/GetMemberExpressionStackTests.cs
@@ -0,0 +1,56 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+
+namespace CsvHelper.Tests.Reflection
+{
+
+ public class GetPropertiesTests
+ {
+ [Fact]
+ public void FirstLevelTest()
+ {
+ var stack = ReflectionHelper.GetMembers<A, string>(a => a.P1);
+
+ Assert.Single(stack);
+ Assert.Equal("P1", stack.Pop().Name);
+ }
+
+ [Fact]
+ public void LastLevelTest()
+ {
+ var stack = ReflectionHelper.GetMembers<A, string>(a => a.B.C.D.P4);
+
+ Assert.Equal(4, stack.Count);
+ Assert.Equal("B", stack.Pop().Name);
+ Assert.Equal("C", stack.Pop().Name);
+ Assert.Equal("D", stack.Pop().Name);
+ Assert.Equal("P4", stack.Pop().Name);
+ }
+
+ private class A
+ {
+ public string P1 { get; set; }
+ public B B { get; set; }
+ }
+
+ private class B
+ {
+ public string P2 { get; set; }
+ public C C { get; set; }
+ }
+
+ private class C
+ {
+ public string P3 { get; set; }
+ public D D { get; set; }
+ }
+
+ private class D
+ {
+ public string P4 { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringBuilder.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringBuilder.cs
new file mode 100644
index 0000000..43bfc75
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringBuilder.cs
@@ -0,0 +1,34 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Text;
+
+namespace CsvHelper.Tests
+{
+ /// <summary>
+ /// A <see cref="StringBuilder"/> like class with configurable line ending for unit tests.
+ /// </summary>
+ public class TestStringBuilder
+ {
+ private readonly string newLine;
+ private readonly StringBuilder builder;
+
+ public TestStringBuilder(string newLine)
+ {
+ this.newLine = newLine ?? throw new ArgumentNullException(nameof(newLine));
+ builder = new StringBuilder();
+ }
+
+ public TestStringBuilder AppendLine(string value)
+ {
+ builder.Append(value).Append(newLine);
+ return this;
+ }
+
+ public override string ToString() => builder.ToString();
+
+ public static implicit operator string(TestStringBuilder sb) => sb.ToString();
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringWriter.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringWriter.cs
new file mode 100644
index 0000000..7691faa
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TestStringWriter.cs
@@ -0,0 +1,28 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.IO;
+
+namespace CsvHelper.Tests
+{
+ /// <summary>
+ /// A <see cref="StreamWriter"/> class with configurable line ending for unit tests.
+ /// </summary>
+ public class TestStreamWriter : StreamWriter
+ {
+ private readonly string newLine;
+
+ public TestStreamWriter(Stream stream, string newLine = "\r\n") : base(stream)
+ {
+ this.newLine = newLine ?? throw new ArgumentNullException(nameof(newLine));
+ }
+
+ public override void WriteLine(string value)
+ {
+ base.Write(value);
+ base.Write(newLine);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ArrayConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ArrayConverterTests.cs
new file mode 100644
index 0000000..7f98b0d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ArrayConverterTests.cs
@@ -0,0 +1,211 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using System.Collections.Generic;
+using System.IO;
+using Xunit;
+using System.Reflection;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.Configuration.Attributes;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class ArrayConverterTests
+ {
+ [Fact]
+ public void FullReadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithNamedHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderListItemsScattered()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,A,List,B,List,After");
+ writer.WriteLine("1,2,3,4,5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(4, list[1]);
+ Assert.Equal(6, list[2]);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_NullValuesAttributeWithIndex_UsesCustomNullValue()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NULL", "", "2" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<NullValuesAttributeIndexTest>().ToList();
+ }
+ }
+
+ private class NullValuesAttributeIndexTest
+ {
+ [Index(0, 2)]
+ [NullValues("NULL")]
+ public int?[] List { get; set; }
+ }
+
+ private class Test
+ {
+ public string Before { get; set; }
+ public int?[] List { get; set; }
+ public string After { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.Before).Index(0);
+ Map(m => m.List).Index(1, 3);
+ Map(m => m.After).Index(4);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.Before).Name("Before");
+ Map(m => m.List).Name("List");
+ Map(m => m.After).Name("After");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.Before);
+ Map(m => m.List);
+ Map(m => m.After);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BigIntegerConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BigIntegerConverterTests.cs
new file mode 100644
index 0000000..6b0c580
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BigIntegerConverterTests.cs
@@ -0,0 +1,40 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class BigIntegerConverterTests
+ {
+ [Fact]
+ public void RoundTripMaxValueTest()
+ {
+ var converter = new BigIntegerConverter();
+ var s = converter.ConvertToString((BigInteger)long.MaxValue + 1, null, new MemberMapData(null));
+ var bi = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal((BigInteger)long.MaxValue + 1, bi);
+ }
+
+ [Fact]
+ public void RoundTripMinValueTest()
+ {
+ var converter = new BigIntegerConverter();
+ var s = converter.ConvertToString((BigInteger)long.MinValue - 1, null, new MemberMapData(null));
+ var bi = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal((BigInteger)long.MinValue - 1, bi);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BooleanConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BooleanConverterTests.cs
new file mode 100644
index 0000000..4cb9769
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/BooleanConverterTests.cs
@@ -0,0 +1,166 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class BooleanConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new BooleanConverter();
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ Assert.Equal("True", converter.ConvertToString(true, null, memberMapData));
+
+ Assert.Equal("False", converter.ConvertToString(false, null, memberMapData));
+
+ Assert.Equal("", converter.ConvertToString(null, null, memberMapData));
+ Assert.Equal("1", converter.ConvertToString(1, null, memberMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new BooleanConverter();
+
+ var memberMapData = new MemberMapData(null);
+ memberMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.True((bool)converter.ConvertFromString("true", null, memberMapData));
+ Assert.True((bool)converter.ConvertFromString("True", null, memberMapData));
+ Assert.True((bool)converter.ConvertFromString("TRUE", null, memberMapData));
+ Assert.True((bool)converter.ConvertFromString("1", null, memberMapData));
+ Assert.True((bool)converter.ConvertFromString(" true ", null, memberMapData));
+
+ Assert.False((bool)converter.ConvertFromString("false", null, memberMapData));
+ Assert.False((bool)converter.ConvertFromString("False", null, memberMapData));
+ Assert.False((bool)converter.ConvertFromString("FALSE", null, memberMapData));
+ Assert.False((bool)converter.ConvertFromString("0", null, memberMapData));
+ Assert.False((bool)converter.ConvertFromString(" false ", null, memberMapData));
+ Assert.False((bool)converter.ConvertFromString(" 0 ", null, memberMapData));
+
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, memberMapData));
+ }
+
+ [Fact]
+ public void ConvertToString_SingleBooleanTrueValue_UsesValue()
+ {
+ var converter = new BooleanConverter();
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions =
+ {
+ BooleanTrueValues = { "Foo" },
+ },
+ };
+
+ var value = converter.ConvertToString(true, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void ConvertToString_MultipleBooleanTrueValues_UsesFirstValue()
+ {
+ var converter = new BooleanConverter();
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions =
+ {
+ BooleanTrueValues = { "Foo", "Bar" },
+ },
+ };
+
+ var value = converter.ConvertToString(true, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void ConvertToString_SingleBooleanFalseValue_UsesValue()
+ {
+ var converter = new BooleanConverter();
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions =
+ {
+ BooleanFalseValues = { "Foo" },
+ },
+ };
+
+ var value = converter.ConvertToString(false, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void ConvertToString_MultipleBooleanFalseValues_UsesFirstValue()
+ {
+ var converter = new BooleanConverter();
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions =
+ {
+ BooleanFalseValues = { "Foo", "Bar" },
+ },
+ };
+
+ var value = converter.ConvertToString(false, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void WriteField_TrueValue_UsesValue()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<bool>().BooleanTrueValues.Add("Foo");
+
+ csv.WriteField(true);
+ csv.Flush();
+ writer.Flush();
+
+ Assert.Equal("Foo", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_FalseValue_UsesValue()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<bool>().BooleanFalseValues.Add("Foo");
+
+ csv.WriteField(false);
+ csv.Flush();
+ writer.Flush();
+
+ Assert.Equal("Foo", writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteArrayConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteArrayConverterTests.cs
new file mode 100644
index 0000000..58d1920
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteArrayConverterTests.cs
@@ -0,0 +1,139 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Linq;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class ByteArrayConverterTests
+ {
+ [Fact]
+ public void WhenConverting_FromStringToByteArray_ReturnsCorrectValues()
+ {
+ var testCases = new[]
+ {
+ new
+ {
+ Options = ByteArrayConverterOptions.Hexadecimal | ByteArrayConverterOptions.HexInclude0x,
+ FieldStrings = new[] { "0xDEAD", "0xB33FBEEF", "0xEA5EEA5EEA5E", "0xCA75CA75CA75CA75" },
+ Expected = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F, 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ },
+ new
+ {
+ Options = ByteArrayConverterOptions.Hexadecimal | ByteArrayConverterOptions.HexDashes,
+ FieldStrings = new[] { "DE-AD", "B3-3F-BE-EF", "EA-5E-EA-5E-EA-5E", "CA-75-CA-75-CA-75-CA-75" },
+ Expected = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F, 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ },
+ new
+ {
+ Options = ByteArrayConverterOptions.Base64,
+ FieldStrings = new []
+ {
+ Convert.ToBase64String( new byte[] { 0xDE, 0xAD } ),
+ Convert.ToBase64String( new byte[] { 0xB3, 0x3F, 0xBE, 0xEF } ),
+ Convert.ToBase64String( new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E } ),
+ Convert.ToBase64String( new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 } )
+ },
+ Expected = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F, 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ }
+ };
+
+ foreach( var t in testCases )
+ {
+ var converter = new ByteArrayConverter( t.Options );
+ foreach( var f in t.FieldStrings.Zip( t.Expected, ( test, expected ) => new { test, expected } ) )
+ {
+ var actual = (byte[])converter.ConvertFromString( f.test, null, null );
+ foreach( var b in actual.Zip( f.expected, ( a, e ) => new { a, e } ) )
+ {
+ Assert.Equal( b.e, b.a );
+ }
+ }
+ }
+ }
+
+ [Fact]
+ public void WhenConverting_FromByteArrayToString_ReturnsCorrectValues()
+ {
+ var testCases = new[]
+ {
+ new
+ {
+ Options = ByteArrayConverterOptions.Hexadecimal | ByteArrayConverterOptions.HexInclude0x,
+ Expected = new[] { "0xDEAD", "0xB33FBEEF", "0xEA5EEA5EEA5E", "0xCA75CA75CA75CA75" },
+ FieldBytes = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F, 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ },
+ new
+ {
+ Options = ByteArrayConverterOptions.Hexadecimal | ByteArrayConverterOptions.HexDashes,
+ Expected = new[] { "DE-AD", "B3-3F-BE-EF", "EA-5E-EA-5E-EA-5E", "CA-75-CA-75-CA-75-CA-75" },
+ FieldBytes = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F, 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ },
+ new
+ {
+ Options = ByteArrayConverterOptions.Base64,
+ Expected = new []
+ {
+ Convert.ToBase64String( new byte[] { 0xDE, 0xAD } ),
+ Convert.ToBase64String( new byte[] { 0xB3, 0x3F, 0xBE, 0xEF } ),
+ Convert.ToBase64String( new byte[] { 0xEA, 0x5E, 0xEA, 0x5E, 0xEA, 0x5E } ),
+ Convert.ToBase64String( new byte[] { 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 } )
+ },
+ FieldBytes = new []
+ {
+ new byte[] { 0xDE, 0xAD },
+ new byte[] { 0xB3, 0x3F , 0xBE, 0xEF },
+ new byte[] { 0xEA, 0x5E , 0xEA, 0x5E, 0xEA, 0x5E },
+ new byte[] { 0xCA, 0x75 , 0xCA, 0x75, 0xCA, 0x75, 0xCA, 0x75 }
+ }
+ }
+ };
+
+ foreach( var t in testCases )
+ {
+ var converter = new ByteArrayConverter( t.Options );
+ foreach( var f in t.Expected.Zip( t.FieldBytes, ( expected, test ) => new { test, expected } ) )
+ {
+ var actual = converter.ConvertToString( f.test, null, null );
+
+ Assert.Equal( actual, f.expected );
+ }
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteConverterTests.cs
new file mode 100644
index 0000000..cbeb016
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/ByteConverterTests.cs
@@ -0,0 +1,47 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class ByteConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new ByteConverter();
+ var propertyMapData = new MemberMapData( null )
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ Assert.Equal( "123", converter.ConvertToString( (byte)123, null, propertyMapData ) );
+
+ Assert.Equal( "", converter.ConvertToString( null, null, propertyMapData ) );
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new ByteConverter();
+
+ var propertyMapData = new MemberMapData( null );
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Equal( (byte)123, converter.ConvertFromString( "123", null, propertyMapData ) );
+ Assert.Equal( (byte)123, converter.ConvertFromString( " 123 ", null, propertyMapData ) );
+
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CharConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CharConverterTests.cs
new file mode 100644
index 0000000..aefa138
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CharConverterTests.cs
@@ -0,0 +1,50 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class CharConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new CharConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ Assert.Equal("a", converter.ConvertToString('a', null, propertyMapData));
+
+ Assert.Equal("True", converter.ConvertToString(true, null, propertyMapData));
+
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new CharConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Equal('a', converter.ConvertFromString("a", null, propertyMapData));
+ Assert.Equal('a', converter.ConvertFromString(" a ", null, propertyMapData));
+ Assert.Equal(' ', converter.ConvertFromString(" ", null, propertyMapData));
+
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CollectionGenericConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CollectionGenericConverterTests.cs
new file mode 100644
index 0000000..c5efd01
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/CollectionGenericConverterTests.cs
@@ -0,0 +1,101 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using System.Collections.Generic;
+using System.IO;
+using Xunit;
+using System.Reflection;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.Configuration.Attributes;
+using System.Linq;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class CollectionGenericConverterTests
+ {
+ [Fact]
+ public void FullWriteTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int?> { 1, 2, 3 } }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal("1,2,3\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_NullValuesAttributeWithIndex_UsesCustomNullValue()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NULL", "", "2" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<NullValuesAttributeIndexTest>().ToList();
+ }
+ }
+
+ private class Test
+ {
+ public List<int?> List { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.List).Index(1, 3);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.List).Name("List");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.List);
+ }
+ }
+
+ private class NullValuesAttributeIndexTest
+ {
+ [Index(0, 2)]
+ [NullValues("NULL")]
+ public List<int?> List { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateOnlyConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateOnlyConverterTests.cs
new file mode 100644
index 0000000..4c567ba
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateOnlyConverterTests.cs
@@ -0,0 +1,59 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+#if NET6_0
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using System;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+ public class DateOnlyConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new DateOnlyConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var date = DateOnly.FromDateTime(DateTime.Now);
+
+ // Valid conversions.
+ Assert.Equal(date.ToString(), converter.ConvertToString(date, null, propertyMapData));
+
+ // Invalid conversions.
+ Assert.Equal("1", converter.ConvertToString(1, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new DateOnlyConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ var date = DateOnly.FromDateTime(DateTime.Now);
+
+ // Valid conversions.
+ Assert.Equal(date.ToString(), converter.ConvertFromString(date.ToString(), null, propertyMapData).ToString());
+ Assert.Equal(date.ToString(), converter.ConvertFromString(date.ToString("o"), null, propertyMapData).ToString());
+ Assert.Equal(date.ToString(), converter.ConvertFromString(" " + date + " ", null, propertyMapData).ToString());
+
+ // Invalid conversions.
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+ }
+}
+#endif
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeConverterTests.cs
new file mode 100644
index 0000000..8f44627
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeConverterTests.cs
@@ -0,0 +1,76 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class DateTimeConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new DateTimeConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var dateTime = DateTime.Now;
+
+ // Valid conversions.
+ Assert.Equal(dateTime.ToString(), converter.ConvertToString(dateTime, null, propertyMapData));
+
+ // Invalid conversions.
+ Assert.Equal("1", converter.ConvertToString(1, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new DateTimeConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ var dateTime = DateTime.Now;
+
+ // Valid conversions.
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(dateTime.ToString(), null, propertyMapData).ToString());
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(dateTime.ToString("o"), null, propertyMapData).ToString());
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(" " + dateTime + " ", null, propertyMapData).ToString());
+
+ // Invalid conversions.
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(" ", row, propertyMapData));
+ }
+
+ [Fact]
+ public void ComponentModelCompatibilityTest()
+ {
+ var converter = new DateTimeConverter();
+ var cmConverter = new System.ComponentModel.DateTimeConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Throws<NotSupportedException>(() => cmConverter.ConvertFromString(null));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ Assert.Throws<FormatException>(() => cmConverter.ConvertFromString("blah"));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString("blah", row, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeOffsetConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeOffsetConverterTests.cs
new file mode 100644
index 0000000..b829361
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DateTimeOffsetConverterTests.cs
@@ -0,0 +1,75 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class DateTimeOffsetConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new DateTimeOffsetConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var dateTime = DateTimeOffset.Now;
+
+ // Valid conversions.
+ Assert.Equal(dateTime.ToString(), converter.ConvertToString(dateTime, null, propertyMapData));
+
+ // Invalid conversions.
+ Assert.Equal("1", converter.ConvertToString(1, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new DateTimeOffsetConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ var dateTime = DateTimeOffset.Now;
+
+ // Valid conversions.
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(dateTime.ToString(), null, propertyMapData).ToString());
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(dateTime.ToString("o"), null, propertyMapData).ToString());
+ Assert.Equal(dateTime.ToString(), converter.ConvertFromString(" " + dateTime + " ", null, propertyMapData).ToString());
+
+ // Invalid conversions.
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+
+ [Fact]
+ public void ComponentModelCompatibilityTest()
+ {
+ var converter = new DateTimeOffsetConverter();
+ var cmConverter = new System.ComponentModel.DateTimeOffsetConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Throws<NotSupportedException>(() => cmConverter.ConvertFromString(null));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ Assert.Throws<FormatException>(() => cmConverter.ConvertFromString("blah"));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString("blah", row, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultConverterTests.cs
new file mode 100644
index 0000000..07818d2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultConverterTests.cs
@@ -0,0 +1,81 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class DefaultConverterTests
+ {
+ [Fact]
+ public void ConvertToString_ValueIsNull_ReturnsEmptyString()
+ {
+ var converter = new DefaultTypeConverter();
+
+ var memberMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertToString(null, null, memberMapData);
+
+ Assert.Equal(string.Empty, value);
+ }
+
+ [Fact]
+ public void ConvertToString_SingleNullValue_UsesValue()
+ {
+ var converter = new DefaultTypeConverter();
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { NullValues = { "Foo" } },
+ };
+
+ var value = converter.ConvertToString(null, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void ConvertToString_MultipleNullValues_UsesFirstValue()
+ {
+ var converter = new DefaultTypeConverter();
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { NullValues = { "Foo", "Bar" } },
+ };
+
+ var value = converter.ConvertToString(null, null, memberMapData);
+
+ Assert.Equal("Foo", value);
+ }
+
+ [Fact]
+ public void WriteField_NullValue_UsesValue()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("Foo");
+
+ csv.WriteField<string>(null);
+ csv.Flush();
+ writer.Flush();
+
+ Assert.Equal("Foo", writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultValueTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultValueTests.cs
new file mode 100644
index 0000000..8b17420
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DefaultValueTests.cs
@@ -0,0 +1,67 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Numerics;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+ public class DefaultValueTests
+ {
+ [Fact]
+ public void BigIntegerConverter_ConvertFromString_InvalidValue_UsesDefault()
+ {
+ var converter = new BigIntegerConverter();
+
+ var data = new MemberMapData(typeof(Foo).GetProperty(nameof(Foo.Property)));
+ data.IsDefaultSet = true;
+ data.Default = (BigInteger)1;
+ data.UseDefaultOnConversionFailure = true;
+
+ var result = converter.ConvertFromString("foo", null, data);
+
+ Assert.Equal(data.Default, result);
+ }
+
+ [Fact]
+ public void GetRecords_EmptyValue_DefaultSet_UsesDefault()
+ {
+ var s = new StringBuilder();
+ s.Append("Property\r\n");
+ s.Append("foo\r\n");
+ using (var reader = new StringReader(s.ToString()))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ var records = csv.GetRecords<Foo>().ToList();
+
+ Assert.Equal(1, records[0].Property);
+ }
+ }
+
+ private class Foo
+ {
+ public BigInteger Property { get; set; }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Property).Default(1, useOnConversionFailure: true);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DoubleConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DoubleConverterTests.cs
new file mode 100644
index 0000000..12a3cc3
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/DoubleConverterTests.cs
@@ -0,0 +1,39 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class DoubleConverterTests
+ {
+ [Fact]
+ public void RoundTripMaxValueTest()
+ {
+ var converter = new DoubleConverter();
+ var s = converter.ConvertToString(double.MaxValue, null, new MemberMapData(null));
+ var d = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal(double.MaxValue, d);
+ }
+
+ [Fact]
+ public void RoundTripMinValueTest()
+ {
+ var converter = new DoubleConverter();
+ var s = converter.ConvertToString(double.MinValue, null, new MemberMapData(null));
+ var d = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal(double.MinValue, d);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumConverterTests.cs
new file mode 100644
index 0000000..b70d02c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumConverterTests.cs
@@ -0,0 +1,367 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using CsvHelper.Configuration;
+using Xunit;
+using CsvHelper.TypeConversion;
+using CsvHelper.Configuration.Attributes;
+using CsvHelper.Tests.Mocks;
+using System.Text;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class EnumConverterTests
+ {
+ [Fact]
+ public void ConstructorTest()
+ {
+ try
+ {
+ new EnumConverter(typeof(string));
+ throw new XUnitException();
+ }
+ catch (ArgumentException ex)
+ {
+ Assert.Equal("'System.String' is not an Enum.", ex.Message);
+ }
+ }
+
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new EnumConverter(typeof(TestEnum));
+ var propertyMapData = new MemberMapData(null);
+
+ Assert.Equal("None", converter.ConvertToString((TestEnum)0, null, propertyMapData));
+ Assert.Equal("None", converter.ConvertToString(TestEnum.None, null, propertyMapData));
+ Assert.Equal("One", converter.ConvertToString((TestEnum)1, null, propertyMapData));
+ Assert.Equal("One", converter.ConvertToString(TestEnum.One, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new EnumConverter(typeof(TestEnum));
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { EnumIgnoreCase = true },
+ };
+
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Equal(TestEnum.One, converter.ConvertFromString("One", null, propertyMapData));
+ Assert.Equal(TestEnum.One, converter.ConvertFromString("one", null, propertyMapData));
+ Assert.Equal(TestEnum.One, converter.ConvertFromString("1", null, propertyMapData));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString("", row, propertyMapData));
+ Assert.Throws<TypeConverterException>(() => Assert.Equal(TestEnum.One, converter.ConvertFromString(null, row, propertyMapData)));
+ }
+
+ [Fact]
+ public void ConvertToString_NameAttribute_ReturnsNameFromNameAttribute()
+ {
+ var converter = new EnumConverter(typeof(NameAttributeEnum));
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var value = converter.ConvertToString(NameAttributeEnum.Foo, null, propertyMapData);
+
+ Assert.Equal("Bar", value);
+ }
+
+ [Fact]
+ public void ConvertFromString_NameAttribute_ReturnsValueFromNameAttribute()
+ {
+ var converter = new EnumConverter(typeof(NameAttributeEnum));
+ var propertyMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertFromString("Bar", null, propertyMapData);
+
+ Assert.Equal(NameAttributeEnum.Foo, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_Int16Enum_ReturnsEnumValue()
+ {
+ var converter = new EnumConverter(typeof(Int16Enum));
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var value = converter.ConvertFromString("1", null, propertyMapData);
+
+ Assert.Equal(Int16Enum.One, value);
+ }
+
+ [Fact]
+ public void ConvertToString_Int16Enum_ReturnsString()
+ {
+ var converter = new EnumConverter(typeof(Int16Enum));
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var value = converter.ConvertToString(Int16Enum.One, null, propertyMapData);
+
+ Assert.Equal("One", value);
+ }
+
+ [Fact]
+ public void ConvertFromString_Int16EnumWithNameAttribute_ReturnsEnumValue()
+ {
+ var converter = new EnumConverter(typeof(Int16Enum));
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var value = converter.ConvertFromString("Bar", null, propertyMapData);
+
+ Assert.Equal(Int16Enum.Foo, value);
+ }
+
+ [Fact]
+ public void ConvertToString_Int16EnumWithNameAttribute_ReturnsString()
+ {
+ var converter = new EnumConverter(typeof(Int16Enum));
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var value = converter.ConvertToString(Int16Enum.Foo, null, propertyMapData);
+
+ Assert.Equal("Bar", value);
+ }
+
+ [Fact]
+ public void ConvertFromString_DuplicateNames_IgnoreCase_ReturnsNameWithLowestValue()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNames));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { EnumIgnoreCase = true },
+ };
+
+ var value = converter.ConvertFromString("oNe", null, memberMapData);
+
+ Assert.Equal(DuplicateNames.one, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_DuplicateValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateValues));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertFromString("1", null, memberMapData);
+
+ Assert.Equal(DuplicateValues.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_UsingValue_DuplicateNamesAndValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNamesAndValues));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertFromString("1", null, memberMapData);
+
+ Assert.Equal(DuplicateNamesAndValues.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_UsingName_DuplicateNamesAndValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNamesAndValues));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { EnumIgnoreCase = true },
+ };
+
+ var value = converter.ConvertFromString("oNe", null, memberMapData);
+
+ Assert.Equal(DuplicateNamesAndValues.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_DuplicateAttributeNames_IgnoreCase_ReturnsNameWithLowestValue()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNamesAttributeEnum));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { EnumIgnoreCase = true },
+ };
+
+ var value = converter.ConvertFromString("oNe", null, memberMapData);
+
+ Assert.Equal(DuplicateNamesAttributeEnum.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_DuplicateAttributeValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateValuesAttributeEnum));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertFromString("1", null, memberMapData);
+
+ Assert.Equal(DuplicateValuesAttributeEnum.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_UsingValue_DuplicateAttributeNamesAndValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNamesAndValuesAttributeEnum));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ };
+
+ var value = converter.ConvertFromString("1", null, memberMapData);
+
+ Assert.Equal(DuplicateNamesAndValuesAttributeEnum.One, value);
+ }
+
+ [Fact]
+ public void ConvertFromString_UsingName_DuplicateAttributeNamesAndValues_ReturnsNameThatAppearsFirst()
+ {
+ var converter = new EnumConverter(typeof(DuplicateNamesAndValuesAttributeEnum));
+
+ var memberMapData = new MemberMapData(null)
+ {
+ TypeConverterOptions = { EnumIgnoreCase = true },
+ };
+
+ var value = converter.ConvertFromString("oNe", null, memberMapData);
+
+ Assert.Equal(DuplicateNamesAndValuesAttributeEnum.One, value);
+ }
+
+ private class TestClass
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public TestEnum TestEnum { get; set; }
+ }
+
+ private class TestClassMap : ClassMap<TestClass>
+ {
+ public TestClassMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name);
+ Map(m => m.TestEnum).TypeConverterOption.EnumIgnoreCase();
+ }
+ }
+
+ private enum TestEnum
+ {
+ None = 0,
+ One = 1,
+ }
+
+ private enum NameAttributeEnum
+ {
+ None = 0,
+ [Name("Bar")]
+ Foo = 1
+ }
+
+ private enum Int16Enum : short
+ {
+ None = 0,
+ One = 1,
+ [Name("Bar")]
+ Foo = 2
+ }
+
+ private enum DuplicateNames
+ {
+ None = 0,
+ One = 2,
+ one = 1,
+ Three = 3
+ }
+
+ private enum DuplicateValues
+ {
+ None = 0,
+ One = 1,
+ Two = 1,
+ Three = 3
+ }
+
+ private enum DuplicateNamesAndValues
+ {
+ None = 0,
+ One = 1,
+ one = 1,
+ Two = 2
+ }
+
+ private enum DuplicateNamesAttributeEnum
+ {
+ None = 0,
+ [Name("Foo")]
+ One = 2,
+ [Name("foo")]
+ Two = 1,
+ Three = 3
+ }
+
+ private enum DuplicateValuesAttributeEnum
+ {
+ None = 0,
+ [Name("Foo")]
+ One = 1,
+ [Name("Bar")]
+ Two = 1,
+ Three = 3
+ }
+
+ private enum DuplicateNamesAndValuesAttributeEnum
+ {
+ None = 0,
+ [Name("Foo")]
+ One = 1,
+ [Name("foo")]
+ Two = 1,
+ Three = 3
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumerableConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumerableConverterTests.cs
new file mode 100644
index 0000000..3f1d4f5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/EnumerableConverterTests.cs
@@ -0,0 +1,32 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using Xunit;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using CsvHelper.Tests.Mocks;
+using System.IO;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class EnumerableConverterTests
+ {
+ [Fact]
+ public void ConvertTest()
+ {
+ var converter = new EnumerableConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var readerRow = new CsvReader(new ParserMock());
+ var writerRow = new CsvWriter(new StringWriter(), CultureInfo.InvariantCulture);
+
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString("", readerRow, propertyMapData));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertToString(5, writerRow, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryConverterTests.cs
new file mode 100644
index 0000000..75915b2
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryConverterTests.cs
@@ -0,0 +1,303 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class IDictionaryConverterTests
+ {
+ [Fact]
+ public void FullWriteTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Dictionary = new Dictionary<string, int> { { "Prop1", 1 }, { "Prop2", 2 }, { "Prop3", 3 } } }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(",1,2,3,\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void FullReadTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Prop1,Prop2,Prop3,Prop4,Prop5");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var dict = records[0].Dictionary;
+
+ Assert.Equal(3, dict.Count);
+ Assert.Equal("2", dict["Prop2"]);
+ Assert.Equal("3", dict["Prop3"]);
+ Assert.Equal("4", dict["Prop4"]);
+ }
+ }
+
+ [Fact]
+ public void FullReadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // You can't read into a dictionary without a header.
+ // You need to header value to use as the key.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderIndexDifferentNamesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Before,Dictionary1,Dictionary2,Dictionary3,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].Dictionary;
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list["Dictionary1"]);
+ Assert.Equal("3", list["Dictionary2"]);
+ Assert.Equal("4", list["Dictionary3"]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderIndexSameNamesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,Dictionary,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Can't have same name with Dictionary.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderDifferentNamesTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Before,Dictionary1,Dictionary2,Dictionary3,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Indexes must be specified for dictionaries.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderSameNamesTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,Dictionary,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Headers can't have the same name.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithNamedHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,Dictionary,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Header's can't have the same name.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderListItemsScattered()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,A,Dictionary,B,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Header's can't have the same name.
+ }
+ }
+ }
+
+ private class Test
+ {
+ public string Before { get; set; }
+ public IDictionary Dictionary { get; set; }
+ public string After { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.Before).Index(0);
+ Map(m => m.Dictionary).Index(1, 3);
+ Map(m => m.After).Index(4);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.Before).Name("Before");
+ Map(m => m.Dictionary).Name("Dictionary");
+ Map(m => m.After).Name("After");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.Before);
+ Map(m => m.Dictionary);
+ Map(m => m.After);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryGenericConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryGenericConverterTests.cs
new file mode 100644
index 0000000..b135632
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IDictionaryGenericConverterTests.cs
@@ -0,0 +1,198 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System.Reflection;
+using CsvHelper.Tests.Mocks;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class IDictionaryGenericConverterTests
+ {
+ [Fact]
+ public void FullReadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // You can't read into a dictionary without a header.
+ // You need to header value to use as the key.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HeaderValidated = null,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("Before,Dictionary1,Dictionary2,Dictionary3,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].Dictionary;
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list["Dictionary1"]);
+ Assert.Equal(3, list["Dictionary2"]);
+ Assert.Equal(4, list["Dictionary3"]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,Dictionary,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Can't have same name with Dictionary.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithNamedHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,Dictionary,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Can't have same name with Dictionary.
+ }
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderListItemsScattered()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,Dictionary,A,Dictionary,B,Dictionary,After");
+ writer.WriteLine("1,2,3,4,5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ try
+ {
+ var records = csv.GetRecords<Test>().ToList();
+ throw new XUnitException();
+ }
+ catch (ReaderException)
+ {
+ // Can't have same name with Dictionary.
+ }
+ }
+ }
+
+ private class Test
+ {
+ public string Before { get; set; }
+ public Dictionary<string, int?> Dictionary { get; set; }
+ public string After { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.Before).Index(0);
+ Map(m => m.Dictionary).Index(1, 3);
+ Map(m => m.After).Index(4);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.Before).Name("Before");
+ Map(m => m.Dictionary).Name("Dictionary");
+ Map(m => m.After).Name("After");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.Before);
+ Map(m => m.Dictionary);
+ Map(m => m.After);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableConverterTests.cs
new file mode 100644
index 0000000..22a7bd5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableConverterTests.cs
@@ -0,0 +1,261 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections;
+using System.Linq;
+using CsvHelper.Configuration;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Xunit;
+using System.Globalization;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class IEnumerableConverterTests
+ {
+ [Fact]
+ public void FullReadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.Cast<string>().ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list[0]);
+ Assert.Equal("3", list[1]);
+ Assert.Equal("4", list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.Cast<string>().ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list[0]);
+ Assert.Equal("3", list[1]);
+ Assert.Equal("4", list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.Cast<string>().ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list[0]);
+ Assert.Equal("3", list[1]);
+ Assert.Equal("4", list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithNamedHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.Cast<string>().ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list[0]);
+ Assert.Equal("3", list[1]);
+ Assert.Equal("4", list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderListItemsScattered()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,A,List,B,List,After");
+ writer.WriteLine("1,2,3,4,5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.Cast<string>().ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal("2", list[0]);
+ Assert.Equal("4", list[1]);
+ Assert.Equal("6", list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullWriteNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int> { 1, 2, 3 } }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(",1,2,3,\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void FullWriteWithHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int> { 1, 2, 3 } }
+ };
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Before,List1,List2,List3,After");
+ expected.AppendLine(",1,2,3,");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void FullWriteWithHeaderAutoMapTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int> { 1, 2, 3 } }
+ };
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Before,After");
+ expected.AppendLine(",");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ private class Test
+ {
+ public string Before { get; set; }
+ public IEnumerable List { get; set; }
+ public string After { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.Before).Index(0);
+ Map(m => m.List).Index(1, 3);
+ Map(m => m.After).Index(4);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.Before).Name("Before");
+ Map(m => m.List).Name("List");
+ Map(m => m.After).Name("After");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.Before);
+ Map(m => m.List);
+ Map(m => m.After);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableGenericConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableGenericConverterTests.cs
new file mode 100644
index 0000000..deebb6d
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/IEnumerableGenericConverterTests.cs
@@ -0,0 +1,265 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Xunit;
+using System.Reflection;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.Configuration.Attributes;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class IEnumerableGenericConverterTests
+ {
+ [Fact]
+ public void FullReadNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithDefaultHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestDefaultMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithNamedHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,List,List,After");
+ writer.WriteLine("1,2,3,4,5");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(3, list[1]);
+ Assert.Equal(4, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullReadWithHeaderListItemsScattered()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("Before,List,A,List,B,List,After");
+ writer.WriteLine("1,2,3,4,5,6,7");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestNamedMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ var list = records[0].List.ToList();
+
+ Assert.Equal(3, list.Count);
+ Assert.Equal(2, list[0]);
+ Assert.Equal(4, list[1]);
+ Assert.Equal(6, list[2]);
+ }
+ }
+
+ [Fact]
+ public void FullWriteNoHeaderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int?> { 1, 2, 3 } }
+ };
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(",1,2,3,\r\n", result);
+ }
+ }
+
+ [Fact]
+ public void FullWriteWithHeaderTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { List = new List<int?> { 1, 2, 3 } }
+ };
+ csv.Context.RegisterClassMap<TestIndexMap>();
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Before,List1,List2,List3,After");
+ expected.AppendLine(",1,2,3,");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void GetRecords_NullValuesAttributeWithIndex_UsesCustomNullValue()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parser = new ParserMock(config)
+ {
+ { "NULL", "", "2" },
+ };
+ using (var csv = new CsvReader(parser))
+ {
+ var records = csv.GetRecords<NullValuesAttributeIndexTest>().ToList();
+ }
+ }
+
+ private class NullValuesAttributeIndexTest
+ {
+ [Index(0, 2)]
+ [NullValues("NULL")]
+ public List<int?> List { get; set; }
+ }
+
+ private class Test
+ {
+ public string Before { get; set; }
+ public IEnumerable<int?> List { get; set; }
+ public string After { get; set; }
+ }
+
+ private sealed class TestIndexMap : ClassMap<Test>
+ {
+ public TestIndexMap()
+ {
+ Map(m => m.Before).Index(0);
+ Map(m => m.List).Index(1, 3);
+ Map(m => m.After).Index(4);
+ }
+ }
+
+ private sealed class TestNamedMap : ClassMap<Test>
+ {
+ public TestNamedMap()
+ {
+ Map(m => m.Before).Name("Before");
+ Map(m => m.List).Name("List");
+ Map(m => m.After).Name("After");
+ }
+ }
+
+ private sealed class TestDefaultMap : ClassMap<Test>
+ {
+ public TestDefaultMap()
+ {
+ Map(m => m.Before);
+ Map(m => m.List);
+ Map(m => m.After);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/SingleConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/SingleConverterTests.cs
new file mode 100644
index 0000000..38b86ea
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/SingleConverterTests.cs
@@ -0,0 +1,39 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class SingleConverterTests
+ {
+ [Fact]
+ public void RoundTripMaxValueTest()
+ {
+ var converter = new SingleConverter();
+ var s = converter.ConvertToString(float.MaxValue, null, new MemberMapData(null));
+ var f = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal(float.MaxValue, f);
+ }
+
+ [Fact]
+ public void RoundTripMinValueTest()
+ {
+ var converter = new SingleConverter();
+ var s = converter.ConvertToString(float.MinValue, null, new MemberMapData(null));
+ var f = converter.ConvertFromString(s, null, new MemberMapData(null));
+
+ Assert.Equal(float.MinValue, f);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeOnlyConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeOnlyConverterTests.cs
new file mode 100644
index 0000000..7792868
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeOnlyConverterTests.cs
@@ -0,0 +1,59 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+#if NET6_0
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using System;
+using System.Globalization;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+ public class TimeOnlyConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new TimeOnlyConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var date = DateOnly.FromDateTime(DateTime.Now);
+
+ // Valid conversions.
+ Assert.Equal(date.ToString(), converter.ConvertToString(date, null, propertyMapData));
+
+ // Invalid conversions.
+ Assert.Equal("1", converter.ConvertToString(1, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new TimeOnlyConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+
+ var row = new CsvReader(new ParserMock());
+
+ var time = TimeOnly.FromDateTime(DateTime.Now);
+
+ // Valid conversions.
+ Assert.Equal(time.ToString(), converter.ConvertFromString(time.ToString(), null, propertyMapData).ToString());
+ Assert.Equal(time.ToString(), converter.ConvertFromString(time.ToString("o"), null, propertyMapData).ToString());
+ Assert.Equal(time.ToString(), converter.ConvertFromString(" " + time + " ", null, propertyMapData).ToString());
+
+ // Invalid conversions.
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+ }
+}
+#endif
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeSpanConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeSpanConverterTests.cs
new file mode 100644
index 0000000..21af674
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TimeSpanConverterTests.cs
@@ -0,0 +1,54 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Globalization;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class TimeSpanConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new TimeSpanConverter();
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture }
+ };
+
+ var dateTime = DateTime.Now;
+ var timeSpan = new TimeSpan(dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
+
+ // Valid conversions.
+ Assert.Equal(timeSpan.ToString(), converter.ConvertToString(timeSpan, null, propertyMapData));
+
+ // Invalid conversions.
+ Assert.Equal("1", converter.ConvertToString(1, null, propertyMapData));
+ Assert.Equal("", converter.ConvertToString(null, null, propertyMapData));
+ }
+
+ [Fact]
+ public void ComponentModelCompatibilityTest()
+ {
+ var converter = new TimeSpanConverter();
+ var cmConverter = new System.ComponentModel.TimeSpanConverter();
+
+ var propertyMapData = new MemberMapData(null);
+ propertyMapData.TypeConverterOptions.CultureInfo = CultureInfo.CurrentCulture;
+ var row = new CsvReader(new ParserMock());
+
+ Assert.Throws<FormatException>(() => cmConverter.ConvertFromString(""));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString("", row, propertyMapData));
+ Assert.Throws<NotSupportedException>(() => cmConverter.ConvertFromString(null));
+ Assert.Throws<TypeConverterException>(() => converter.ConvertFromString(null, row, propertyMapData));
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterCacheTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterCacheTests.cs
new file mode 100644
index 0000000..499013a
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterCacheTests.cs
@@ -0,0 +1,243 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class TypeConverterCacheTests
+ {
+ [Fact]
+ public void GetConverterForUnknownTypeTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(TestUnknownClass));
+
+ Assert.IsType<DefaultTypeConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForKnownTypeTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter<TestKnownClass>();
+
+ Assert.IsType<DefaultTypeConverter>(converter);
+
+ typeConverterFactory.AddConverter<TestKnownClass>(new TestKnownConverter());
+ converter = typeConverterFactory.GetConverter<TestKnownClass>();
+
+ Assert.IsType<TestKnownConverter>(converter);
+ }
+
+ [Fact]
+ public void RemoveConverterForUnknownTypeTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ typeConverterFactory.RemoveConverter<TestUnknownClass>();
+ typeConverterFactory.RemoveConverter(typeof(TestUnknownClass));
+ }
+
+ [Fact]
+ public void GetConverterForByteTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(byte));
+
+ Assert.IsType<ByteConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForByteArrayTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(byte[]));
+
+ Assert.IsType<ByteArrayConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForCharTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(char));
+
+ Assert.IsType<CharConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForDateTimeTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(DateTime));
+
+ Assert.IsType<DateTimeConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForDecimalTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(decimal));
+
+ Assert.IsType<DecimalConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForDoubleTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(double));
+
+ Assert.IsType<DoubleConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForFloatTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(float));
+
+ Assert.IsType<SingleConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForGuidTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(Guid));
+
+ Assert.IsType<GuidConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForInt16Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(short));
+
+ Assert.IsType<Int16Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForInt32Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(int));
+
+ Assert.IsType<Int32Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForInt64Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(long));
+
+ Assert.IsType<Int64Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForNullableTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(int?));
+
+ Assert.IsType<NullableConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForSByteTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(sbyte));
+
+ Assert.IsType<SByteConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForStringTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(string));
+
+ Assert.IsType<StringConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForUInt16Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(ushort));
+
+ Assert.IsType<UInt16Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForUInt32Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(uint));
+
+ Assert.IsType<UInt32Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForUInt64Test()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(ulong));
+
+ Assert.IsType<UInt64Converter>(converter);
+ }
+
+ [Fact]
+ public void GetConverterForEnumTest()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ var converter = typeConverterFactory.GetConverter(typeof(FooEnum));
+
+ Assert.IsType<EnumConverter>(converter);
+ }
+
+ [Fact]
+ public void GetConverter_ConverterRegisteredForEnum_ReturnCustomConverterForAllEnums()
+ {
+ var typeConverterFactory = new TypeConverterCache();
+ typeConverterFactory.AddConverter<Enum>(new TestKnownConverter());
+ var fooConverter = typeConverterFactory.GetConverter(typeof(FooEnum));
+ var barConverter = typeConverterFactory.GetConverter(typeof(BarEnum));
+
+ Assert.IsType<TestKnownConverter>(fooConverter);
+ Assert.IsType<TestKnownConverter>(barConverter);
+ }
+
+ private class TestListConverter : DefaultTypeConverter
+ {
+ }
+
+ private class TestUnknownClass
+ {
+ }
+
+ private class TestKnownClass
+ {
+ }
+
+ private class TestKnownConverter : DefaultTypeConverter
+ {
+ }
+
+ private enum FooEnum
+ {
+ }
+
+ private enum BarEnum
+ {
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsFactoryTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsFactoryTests.cs
new file mode 100644
index 0000000..d0beeee
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsFactoryTests.cs
@@ -0,0 +1,211 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class TypeConverterOptionsFactoryTests
+ {
+ [Fact]
+ public void AddGetRemoveTest()
+ {
+ var customOptions = new TypeConverterOptions
+ {
+ Formats = new string[] { "custom" },
+ };
+ var typeConverterOptionsFactory = new TypeConverterOptionsCache();
+
+ typeConverterOptionsFactory.AddOptions<string>(customOptions);
+ var options = typeConverterOptionsFactory.GetOptions<string>();
+
+ Assert.Equal(customOptions.Formats, options.Formats);
+
+ typeConverterOptionsFactory.RemoveOptions<string>();
+
+ options = typeConverterOptionsFactory.GetOptions<string>();
+
+ Assert.NotEqual(customOptions.Formats, options.Formats);
+ }
+
+ [Fact]
+ public void GetFieldTest()
+ {
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.Read();
+ Assert.Equal(1234, csvReader.GetField<int>(0));
+ Assert.Equal(5678, csvReader.GetField(typeof(int), 1));
+ }
+ }
+
+ [Fact]
+ public void GetRecordsTest()
+ {
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.GetRecords<Test>().ToList();
+ }
+ }
+
+ [Fact]
+ public void GetRecordsAppliedWhenMappedTest()
+ {
+ var options = new TypeConverterOptions { NumberStyles = NumberStyles.AllowThousands };
+
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvReader = new CsvReader(reader, config))
+ {
+ writer.WriteLine("\"1,234\",\"$5,678\"");
+ writer.Flush();
+ stream.Position = 0;
+
+ csvReader.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvReader.Context.RegisterClassMap<TestMap>();
+ csvReader.GetRecords<Test>().ToList();
+ }
+ }
+
+ [Fact]
+ public void WriteFieldTest()
+ {
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.WriteField(1234);
+ csvWriter.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\"\r\n", record);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsTest()
+ {
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Number = 1234, NumberOverridenInMap = 5678 },
+ };
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\",\"$5,678.00\"\r\n", record);
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsAppliedWhenMappedTest()
+ {
+ var options = new TypeConverterOptions { Formats = new string[] { "c" } };
+
+ var config = new CsvConfiguration(new CultureInfo("en-US"))
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csvWriter = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Number = 1234, NumberOverridenInMap = 5678 },
+ };
+ csvWriter.Context.TypeConverterOptionsCache.AddOptions<int>(options);
+ csvWriter.Context.RegisterClassMap<TestMap>();
+ csvWriter.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+ var record = reader.ReadToEnd();
+
+ Assert.Equal("\"$1,234.00\",\"5,678.00\"\r\n", record);
+ }
+ }
+
+ private class Test
+ {
+ public int Number { get; set; }
+
+ public int NumberOverridenInMap { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Number);
+ Map(m => m.NumberOverridenInMap)
+ .TypeConverterOption.NumberStyles(NumberStyles.AllowThousands | NumberStyles.AllowCurrencySymbol)
+ .TypeConverterOption.Format("N2");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsTests.cs
new file mode 100644
index 0000000..90f8f0b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterOptionsTests.cs
@@ -0,0 +1,110 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class TypeConverterOptionsTests
+ {
+ [Fact]
+ public void GlobalNullValueTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine(",");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add(string.Empty);
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Null(records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void MappingNullValueTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine(",");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Null(records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ [Fact]
+ public void GlobalAndMappingNullValueTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var writer = new StreamWriter(stream))
+ using (var reader = new StreamReader(stream))
+ using (var csv = new CsvReader(reader, config))
+ {
+ writer.WriteLine(",");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.TypeConverterOptionsCache.GetOptions<string>().NullValues.Add("null");
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Null(records[0].Id);
+ Assert.Null(records[0].Name);
+ }
+ }
+
+ private class Test
+ {
+ public int? Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).TypeConverterOption.NullValues(string.Empty);
+ }
+ }
+
+ // auto map options have defaults
+ // map options could be default or custom if set
+ // global has defaults or custom
+ // merge global with map
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterTests.cs
new file mode 100644
index 0000000..da71236
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/TypeConverterTests.cs
@@ -0,0 +1,51 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Linq;
+using Xunit;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using CsvHelper.TypeConversion;
+using System.Globalization;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class TypeConverterTests
+ {
+ [Fact]
+ public void ReaderInheritedConverter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ var parserMock = new ParserMock(config)
+ {
+ { "1" },
+ };
+ var csv = new CsvReader(parserMock);
+ csv.Context.RegisterClassMap<TestMap>();
+ var list = csv.GetRecords<Test>().ToList();
+ }
+
+ private class Test
+ {
+ public int IntColumn { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.IntColumn).Index(0).TypeConverter<Converter>();
+ }
+ }
+
+ private class Converter : Int32Converter
+ {
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/UriConverterTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/UriConverterTests.cs
new file mode 100644
index 0000000..d55baed
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/TypeConversion/UriConverterTests.cs
@@ -0,0 +1,106 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.TypeConversion;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.IO;
+
+namespace CsvHelper.Tests.TypeConversion
+{
+
+ public class UriConverterTests
+ {
+ [Fact]
+ public void ConvertToStringTest()
+ {
+ var converter = new UriConverter();
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture },
+ };
+
+ Assert.Equal("https://test.com/", converter.ConvertToString(new Uri("https://test.com"), null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringTest()
+ {
+ var converter = new UriConverter();
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture },
+ };
+
+ Assert.Equal(new Uri("https://test.com"), converter.ConvertFromString("https://test.com", null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringUriKindRelativeTest()
+ {
+ var converter = new UriConverter();
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture, UriKind = UriKind.Relative },
+ };
+
+ Assert.Equal(new Uri("/a/b/c", UriKind.Relative), converter.ConvertFromString("/a/b/c", null, propertyMapData));
+ }
+
+ [Fact]
+ public void ConvertFromStringUriKindAbsoluteTest()
+ {
+ var converter = new UriConverter();
+
+ var propertyMapData = new MemberMapData(null)
+ {
+ TypeConverter = converter,
+ TypeConverterOptions = { CultureInfo = CultureInfo.CurrentCulture, UriKind = UriKind.Absolute },
+ };
+
+ Assert.Equal(new Uri("https://test.com"), converter.ConvertFromString("https://test.com", null, propertyMapData));
+ }
+
+ [Fact]
+ public void TypeConverterCacheTest()
+ {
+ var cache = new TypeConverterCache();
+ var converter = cache.GetConverter<Uri>();
+
+ Assert.IsType<UriConverter>(converter);
+ }
+
+ [Fact]
+ public void AnonymousTypeTest()
+ {
+ var sw = new StringWriter();
+ var entries = new[]
+ {
+ new { Uri = new Uri("http://host/path") }
+ };
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Delimiter = ";",
+ };
+ using (var cw = new CsvWriter(sw, config))
+ {
+ cw.WriteRecords(entries);
+ }
+
+ Assert.Equal("Uri\r\nhttp://host/path\r\n", sw.ToString());
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/AnonymousTypesTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/AnonymousTypesTests.cs
new file mode 100644
index 0000000..8ad8682
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/AnonymousTypesTests.cs
@@ -0,0 +1,34 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections;
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class AnonymousTypesTests
+ {
+ [Fact]
+ public void AnonymousIEnumerableTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ IEnumerable records = new ArrayList
+ {
+ new
+ {
+ Id = 1,
+ Name = "one",
+ }
+ };
+
+ csv.WriteRecords(records);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ConstantTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ConstantTests.cs
new file mode 100644
index 0000000..6bf29e4
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ConstantTests.cs
@@ -0,0 +1,126 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class ConstantTests
+ {
+ [Fact]
+ public void StringConstantTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" },
+ new Test { Id = 2, Name = "two" }
+ };
+
+ csv.Context.RegisterClassMap<TestStringMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,constant");
+ expected.AppendLine("2,constant");
+
+ var result = reader.ReadToEnd();
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void NullConstantTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" },
+ };
+
+ csv.Context.RegisterClassMap<TestNullMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+
+ Assert.Equal("1,\r\n", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void IntConstantTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var records = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" },
+ };
+
+ csv.Context.RegisterClassMap<TestIntMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+
+ Assert.Equal("-1,one\r\n", writer.ToString());
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+
+ private sealed class TestIntMap : ClassMap<Test>
+ {
+ public TestIntMap()
+ {
+ Map(m => m.Id).Constant(-1);
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class TestNullMap : ClassMap<Test>
+ {
+ public TestNullMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Constant(null);
+ }
+ }
+
+ private sealed class TestStringMap : ClassMap<Test>
+ {
+ public TestStringMap()
+ {
+ Map(m => m.Id);
+ Map(m => m.Name).Constant("constant");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/CsvModeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/CsvModeTests.cs
new file mode 100644
index 0000000..65e5e49
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/CsvModeTests.cs
@@ -0,0 +1,145 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class CsvModeTests
+ {
+ [Fact]
+ public void WriteField_EscapeMode_ContainsQuote_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a\"b", true);
+ csv.Flush();
+
+ Assert.Equal("a\\\"b", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoEscapeMode_ContainsQuote_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.NoEscape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a\"b", true);
+ csv.Flush();
+
+ Assert.Equal("a\"b", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_EscapeMode_ContainsDelimiter_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a,b", true);
+ csv.Flush();
+
+ Assert.Equal("a\\,b", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoEscapeMode_ContainsDelimiter_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.NoEscape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a,b", true);
+ csv.Flush();
+
+ Assert.Equal("a,b", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_EscapeMode_ContainsNewline_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ NewLine = "\n",
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a\nb", true);
+ csv.Flush();
+
+ Assert.Equal("a\\\nb", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_EscapeMode_Contains2CharNewline_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.Escape,
+ Escape = '\\',
+ NewLine = "\r\n",
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a\r\nb", true);
+ csv.Flush();
+
+ Assert.Equal("a\\\r\\\nb", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoEscapeMode_ContainsNewline_EscapesWithoutQuotingField()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ Mode = CsvMode.NoEscape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("a\r\nb", true);
+ csv.Flush();
+
+ Assert.Equal("a\r\nb", writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/DynamicTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/DynamicTests.cs
new file mode 100644
index 0000000..1cf33dc
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/DynamicTests.cs
@@ -0,0 +1,218 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Dynamic;
+using System.Globalization;
+using System.IO;
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class DynamicTests
+ {
+ [Fact]
+ public void WriteDynamicExpandoObjectsTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<dynamic>();
+
+ dynamic obj = new ExpandoObject();
+ obj.Id = 1;
+ obj.Name = "one";
+ list.Add(obj);
+
+ obj = new ExpandoObject();
+ obj.Id = 2;
+ obj.Name = "two";
+ list.Add(obj);
+
+ csv.WriteRecords(list);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = "Id,Name\r\n";
+ expected += "1,one\r\n";
+ expected += "2,two\r\n";
+
+ Assert.Equal(expected, reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicExpandoObjectTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ dynamic obj = new ExpandoObject();
+ obj.Id = 1;
+ obj.Name = "one";
+
+ csv.WriteDynamicHeader(obj);
+ csv.NextRecord();
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ obj = new ExpandoObject();
+ obj.Id = 2;
+ obj.Name = "two";
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = "Id,Name\r\n";
+ expected += "1,one\r\n";
+ expected += "2,two\r\n";
+
+ Assert.Equal(expected, reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicExpandoObjectHasDifferentPropertyOrderingTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ dynamic obj = new ExpandoObject();
+ obj.Name = "one";
+ obj.Id = 1;
+
+ csv.WriteDynamicHeader(obj);
+ csv.NextRecord();
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ obj = new ExpandoObject();
+ obj.Name = "two";
+ obj.Id = 2;
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ var expected = "Name,Id\r\n";
+ expected += "one,1\r\n";
+ expected += "two,2\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicIDynamicMetaObjectProviderHasDifferentPropertyOrderingTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ dynamic obj = new DynamicObjectMock();
+ obj.Name = "one";
+ obj.Id = 1;
+
+ csv.WriteDynamicHeader(obj);
+ csv.NextRecord();
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ obj = new ExpandoObject();
+ obj.Name = "two";
+ obj.Id = 2;
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ var expected = "Name,Id\r\n";
+ expected += "one,1\r\n";
+ expected += "two,2\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicExpandoObjectHasDifferentPropertyOrderingWithDynamicSortTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DynamicPropertySort = Comparer<string>.Create((x, y) => x.CompareTo(y)),
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ dynamic obj = new ExpandoObject();
+ obj.Name = "one";
+ obj.Id = 1;
+
+ csv.WriteDynamicHeader(obj);
+ csv.NextRecord();
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ obj = new ExpandoObject();
+ obj.Id = 2;
+ obj.Name = "two";
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ var expected = "Id,Name\r\n";
+ expected += "1,one\r\n";
+ expected += "2,two\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteDynamicIDynamicMetaObjectProviderHasDifferentPropertyOrderingWithDynamicSortTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ DynamicPropertySort = Comparer<string>.Create((x, y) => x.CompareTo(y)),
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ dynamic obj = new DynamicObjectMock();
+ obj.Name = "one";
+ obj.Id = 1;
+
+ csv.WriteDynamicHeader(obj);
+ csv.NextRecord();
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ obj = new ExpandoObject();
+ obj.Id = 2;
+ obj.Name = "two";
+
+ csv.WriteRecord(obj);
+ csv.NextRecord();
+
+ var expected = "Id,Name\r\n";
+ expected += "1,one\r\n";
+ expected += "2,two\r\n";
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs
new file mode 100644
index 0000000..507bd44
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/FieldTypeTests.cs
@@ -0,0 +1,87 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class FieldTypeTests
+ {
+ [Fact]
+ public void WriteField_ShouldQuote_HasCorrectFieldType()
+ {
+ Type type = null;
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = args =>
+ {
+ type = args.FieldType;
+ return ConfigurationFunctions.ShouldQuote(args);
+ },
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField(string.Empty);
+ Assert.Equal(typeof(string), type);
+
+ csv.WriteField(1);
+ Assert.Equal(typeof(int), type);
+
+ csv.WriteField(string.Empty);
+ Assert.Equal(typeof(string), type);
+ }
+ }
+
+ [Fact]
+ public void WriteRecords_ShouldQuote_HasCorrectFieldType()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ };
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = args =>
+ {
+ if (args.Row.Row > 1)
+ {
+ switch (args.Row.Index)
+ {
+ case 0:
+ Assert.Equal(typeof(int), args.FieldType);
+ break;
+ case 1:
+ Assert.Equal(typeof(string), args.FieldType);
+ break;
+ }
+ }
+
+ return ConfigurationFunctions.ShouldQuote(args);
+ },
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IAsyncEnumerableTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IAsyncEnumerableTests.cs
new file mode 100644
index 0000000..dc5fd61
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IAsyncEnumerableTests.cs
@@ -0,0 +1,50 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+#if !NET45
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+ public class IAsyncEnumerableTests
+ {
+ [Fact]
+ public async Task Test()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ new Foo { Id = 2, Name = "two" },
+ }.ToAsyncEnumerable();
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ await csv.WriteRecordsAsync(records);
+
+ var expected = new StringBuilder();
+ expected.Append("Id,Name\r\n");
+ expected.Append("1,one\r\n");
+ expected.Append("2,two\r\n");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+ }
+}
+#endif
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IgnoreTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IgnoreTests.cs
new file mode 100644
index 0000000..3fbe5e7
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/IgnoreTests.cs
@@ -0,0 +1,51 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class IgnoreTests
+ {
+ [Fact]
+ public void WritingWithAllPropertiesIgnoredTest()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1 },
+ };
+
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<FooMap>();
+ csv.WriteRecords(records);
+
+ Assert.Equal("\r\n\r\n", writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+ }
+
+ private class FooMap : ClassMap<Foo>
+ {
+ public FooMap()
+ {
+ Map(m => m.Id).Ignore();
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/InterfaceTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/InterfaceTests.cs
new file mode 100644
index 0000000..b3f2cad
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/InterfaceTests.cs
@@ -0,0 +1,90 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class InterfaceTests
+ {
+ [Fact]
+ public void WriteRecordsGenericTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var records = new List<IRecord>();
+ IRecord record = new Record { A = 1, B = 2 };
+ records.Add(record);
+ record = new Record { A = 3, B = 4 };
+ records.Add(record);
+
+ csv.Context.RegisterClassMap<RecordMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = "RenameA\r\n1\r\n3\r\n";
+ Assert.Equal(expected, reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public void WriteRecordTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.Context.RegisterClassMap<RecordMap>();
+
+ csv.WriteHeader<IRecord>();
+ csv.NextRecord();
+
+ IRecord record = new Record { A = 1, B = 2 };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ record = new Record { A = 3, B = 4 };
+ csv.WriteRecord(record);
+ csv.NextRecord();
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = "RenameA\r\n1\r\n3\r\n";
+ Assert.Equal(expected, reader.ReadToEnd());
+ }
+ }
+
+ private interface IRecord
+ {
+ int A { get; set; }
+ int B { get; set; }
+ }
+
+ private class Record : IRecord
+ {
+ public int A { get; set; }
+ public int B { get; set; }
+ }
+
+ private sealed class RecordMap : ClassMap<IRecord>
+ {
+ public RecordMap()
+ {
+ Map(m => m.A).Name("RenameA");
+ }
+ }
+
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleFieldsFromOnePropertyTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleFieldsFromOnePropertyTests.cs
new file mode 100644
index 0000000..f33508b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleFieldsFromOnePropertyTests.cs
@@ -0,0 +1,79 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class MultipleFieldsFromOnePropertyTests
+ {
+ [Fact]
+ public void WriteMultipleFieldsFromSinglePropertyTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, new CultureInfo("en-US")))
+ {
+ var records = new List<Test>
+ {
+ new Test { Dob = DateTime.Parse("9/6/2017", new CultureInfo("en-US")) }
+ };
+ csv.Context.RegisterClassMap<TestMap>();
+ csv.WriteRecords(records);
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("A,B,C");
+ expected.AppendLine("9/6/2017 12:00:00 AM,9/6/2017 12:00:00 AM,9/6/2017 12:00:00 AM");
+
+ Assert.Equal(expected.ToString(), reader.ReadToEnd());
+ }
+ }
+
+ [Fact]
+ public void ReadingWhenMultipleMapsForAPropertyAreSpecifiedUsesTheLastMapTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
+ {
+ writer.WriteLine("A,B,C");
+ writer.WriteLine("9/6/2017 12:00:00 AM,9/7/2017 12:00:00 AM,9/8/2017 12:00:00 AM");
+ writer.Flush();
+ stream.Position = 0;
+
+ csv.Context.RegisterClassMap<TestMap>();
+ var records = csv.GetRecords<Test>().ToList();
+
+ Assert.Equal(DateTime.Parse("9/8/2017", CultureInfo.InvariantCulture), records[0].Dob);
+ }
+ }
+
+ private class Test
+ {
+ public DateTime Dob { get; set; }
+ }
+
+ private sealed class TestMap : ClassMap<Test>
+ {
+ public TestMap()
+ {
+ Map(m => m.Dob, false).Name("A");
+ Map(m => m.Dob, false).Name("B");
+ Map(m => m.Dob, false).Name("C");
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleHeadersTest.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleHeadersTest.cs
new file mode 100644
index 0000000..086bb86
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/MultipleHeadersTest.cs
@@ -0,0 +1,84 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using Xunit;
+using System.Dynamic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class MultipleHeadersTest
+ {
+ [Fact]
+ public void GenericTypeTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteHeader<A>();
+ csv.NextRecord();
+ csv.WriteRecord(new A { Id = 1 });
+ csv.NextRecord();
+
+ csv.WriteHeader<B>();
+ csv.NextRecord();
+ csv.WriteRecord(new B { Name = "one" });
+ csv.NextRecord();
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+ expected.AppendLine("Name");
+ expected.AppendLine("one");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void DynamicTypeTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ dynamic a = new ExpandoObject();
+ a.Id = 1;
+ csv.WriteDynamicHeader(a);
+ csv.NextRecord();
+ csv.WriteRecord(a);
+ csv.NextRecord();
+
+ dynamic b = new ExpandoObject();
+ b.Name = "one";
+ csv.WriteDynamicHeader(b);
+ csv.NextRecord();
+ csv.WriteRecord(b);
+ csv.NextRecord();
+ writer.Flush();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id");
+ expected.AppendLine("1");
+ expected.AppendLine("Name");
+ expected.AppendLine("one");
+
+ Assert.Equal(expected.ToString(), writer.ToString());
+ }
+ }
+
+ private class A
+ {
+ public int Id { get; set; }
+ }
+
+ private class B
+ {
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NewLineTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NewLineTests.cs
new file mode 100644
index 0000000..34e1e0b
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NewLineTests.cs
@@ -0,0 +1,92 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using CsvHelper.Tests.Mocks;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class NewLineTests
+ {
+ [Fact]
+ public void CRLFTest()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+
+ Assert.Equal("1,one\r\n", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void CRTest()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ NewLine = "\r",
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+
+ Assert.Equal("1,one\r", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void LFTest()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one" },
+ };
+
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ NewLine = "\n",
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+
+ Assert.Equal("1,one\n", writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NoPropertyMappingTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NoPropertyMappingTests.cs
new file mode 100644
index 0000000..e284836
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/NoPropertyMappingTests.cs
@@ -0,0 +1,218 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Text;
+using CsvHelper.Configuration;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class NoPropertyMappingTests
+ {
+ [Fact]
+ public void NoPropertyWithHeaderAndNameTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1 },
+ new Test { Id = 2 }
+ };
+
+ csv.Context.RegisterClassMap<TestWithNameMap>();
+ csv.WriteRecords(list);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,Constant,Name");
+ expected.AppendLine("1,const,");
+ expected.AppendLine("2,const,");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void NoPropertyWithHeaderAndNoNameTest()
+ {
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1 },
+ new Test { Id = 2 }
+ };
+
+ csv.Context.RegisterClassMap<TestWithNoNameMap>();
+ csv.WriteRecords(list);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("Id,");
+ expected.AppendLine("1,const");
+ expected.AppendLine("2,const");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void NoPropertyWithNoHeaderAndNameTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1 },
+ new Test { Id = 2 }
+ };
+
+ csv.Context.RegisterClassMap<TestWithNameMap>();
+ csv.WriteRecords(list);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("1,const,");
+ expected.AppendLine("2,const,");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void NoPropertyWithNoHeaderAndNoNameTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1 },
+ new Test { Id = 2 }
+ };
+
+ csv.Context.RegisterClassMap<TestWithNoNameMap>();
+ csv.WriteRecords(list);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("1,const");
+ expected.AppendLine("2,const");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ [Fact]
+ public void OutOfOrderTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var list = new List<Test>
+ {
+ new Test { Id = 1, Name = "one" },
+ new Test { Id = 2, Name = "two" }
+ };
+
+ csv.Context.RegisterClassMap<TestMapOutOfOrderWithEmptyFieldsMap>();
+ csv.WriteRecords(list);
+
+ writer.Flush();
+ stream.Position = 0;
+
+ var result = reader.ReadToEnd();
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("one,,,1");
+ expected.AppendLine("two,,,2");
+
+ Assert.Equal(expected.ToString(), result);
+ }
+ }
+
+ private class Test
+ {
+ public int Id { get; set; }
+
+ public string Name { get; set; }
+ }
+
+ private sealed class TestWithNameMap : ClassMap<Test>
+ {
+ public TestWithNameMap()
+ {
+ Map(m => m.Id);
+ Map().Name("Constant").Constant("const");
+ Map(m => m.Name);
+ }
+ }
+
+ private sealed class TestWithNoNameMap : ClassMap<Test>
+ {
+ public TestWithNoNameMap()
+ {
+ Map(m => m.Id);
+ Map().Constant("const");
+ }
+ }
+
+ private sealed class TestMapOutOfOrderWithEmptyFieldsMap : ClassMap<Test>
+ {
+ public TestMapOutOfOrderWithEmptyFieldsMap()
+ {
+ Map(m => m.Name).Index(0);
+ Map().Index(1).Constant(null);
+ Map().Index(2).Constant(string.Empty);
+ Map(m => m.Id).Index(3);
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/SanitizationTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/SanitizationTests.cs
new file mode 100644
index 0000000..1442cd5
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/SanitizationTests.cs
@@ -0,0 +1,422 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace CsvHelper.Tests.Serializing
+{
+
+ public class SanitizationTests
+ {
+ [Fact]
+ public void WriteField_NoQuotes_OptionsNone_DoesNotSanitize()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.None,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{ch}foo", false);
+ }
+
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{ch}foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsNone_DoesNotSanitize()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.None,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsException_ThrowsException()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Exception,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ Assert.Throws<WriterException>(() => csv.WriteField($"{ch}foo", false));
+ }
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsException_ThrowsException()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Exception,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ Assert.Throws<WriterException>(() => csv.WriteField($"{config.Quote}{ch}foo{config.Quote}", false));
+ }
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsException_CharIsNotFirst_DoesNotThrowException()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Exception,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"a{ch}foo", false);
+ }
+
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"a{ch}foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsException_CharIsNotFirst_DoesNotThrowException()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Exception,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}a{ch}foo{config.Quote}", false);
+ }
+
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}a{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsStrip_StripsCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{ch}foo", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsStrip_CharIsNotFirst_DoesNotStripCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"a{ch}foo", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"a{ch}foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_MultipleChars_OptionsStrip_StripsCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{ch}{ch}{ch}foo", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_MultipleChars_OptionsStrip_CharIsNotFirst_DoesNotStripCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"a{ch}{ch}{ch}foo", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"a{ch}{ch}{ch}foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsStrip_StripsCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsStrip_CharIsNotFirst_DoesNotStripCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}a{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}a{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_MultipleChars_OptionsStrip_StripsCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}{ch}{ch}{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_MultipleChars_OptionsStripCharIsNotFirst_DoesNotStripCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Strip,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}a{ch}{ch}{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}a{ch}{ch}{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsEscape_QuotesFieldAndEscapes()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Escape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{ch}foo", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}{config.InjectionEscapeCharacter}{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_NoQuotes_OptionsEscape_CharIsNotFirst_DoesNotQuoteFieldAndEscape()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Escape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"a{ch}foo", false);
+ }
+
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"a{ch}foo"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsEscape_EscapesInsideQuotes()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Escape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}{config.InjectionEscapeCharacter}{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_Quotes_OptionsEscape_CharIsNotFirst_DoesNotEscapeInsideQuotes()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ InjectionOptions = InjectionOptions.Escape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ foreach (var ch in config.InjectionCharacters)
+ {
+ csv.WriteField($"{config.Quote}a{ch}foo{config.Quote}", false);
+ }
+ csv.Flush();
+ writer.Flush();
+
+ var expected = string.Join(config.Delimiter, config.InjectionCharacters.Select(ch => $"{config.Quote}a{ch}foo{config.Quote}"));
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs
new file mode 100644
index 0000000..a97d2c6
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/ShouldQuoteTests.cs
@@ -0,0 +1,187 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class ShouldQuoteTests
+ {
+ [Fact]
+ public void QuoteAllFieldsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => true,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("one");
+ csv.Flush();
+
+ Assert.Equal("\"one\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void QuoteNoFieldsTest()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = _ => false,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("o\"e");
+ csv.Flush();
+
+ Assert.Equal("o\"e", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ContainsQuoteTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField($"o{csv.Configuration.Quote}e");
+ csv.Flush();
+
+ Assert.Equal($"\"o{csv.Configuration.Quote}{csv.Configuration.Quote}e\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void StartsWithSpaceTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField(" one");
+ csv.Flush();
+
+ Assert.Equal("\" one\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void EndsWithSpaceTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("one ");
+ csv.Flush();
+
+ Assert.Equal("\"one \"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ContainsCrTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("o\re");
+ csv.Flush();
+
+ Assert.Equal("\"o\re\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ContainsLfTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("o\ne");
+ csv.Flush();
+
+ Assert.Equal("\"o\ne\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ContainsCrLfTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField("o\r\ne");
+ csv.Flush();
+
+ Assert.Equal("\"o\r\ne\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void ContainsDelimiterTest()
+ {
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
+ {
+ csv.WriteField($"o{csv.Configuration.Delimiter}e");
+ csv.Flush();
+
+ Assert.Equal($"\"o{csv.Configuration.Delimiter}e\"", writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void Test1()
+ {
+ var data = new List<(int row, int column, string field)>();
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ ShouldQuote = args =>
+ {
+ data.Add((args.Row.Row, args.Row.Index, args.Field));
+
+ return ConfigurationFunctions.ShouldQuote(args);
+ },
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField("Id");
+ csv.WriteField("Name");
+ csv.NextRecord();
+
+ csv.WriteField("1");
+ csv.WriteField("one");
+ csv.NextRecord();
+
+ csv.Flush();
+ }
+
+ Assert.Equal(4, data.Count);
+
+ Assert.Equal(1, data[0].row);
+ Assert.Equal(0, data[0].column);
+ Assert.Equal("Id", data[0].field);
+
+ Assert.Equal(1, data[1].row);
+ Assert.Equal(1, data[1].column);
+ Assert.Equal("Name", data[1].field);
+
+ Assert.Equal(2, data[2].row);
+ Assert.Equal(0, data[2].column);
+ Assert.Equal("1", data[2].field);
+
+ Assert.Equal(2, data[3].row);
+ Assert.Equal(1, data[3].column);
+ Assert.Equal("one", data[3].field);
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/TrimTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/TrimTests.cs
new file mode 100644
index 0000000..836f7df
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/TrimTests.cs
@@ -0,0 +1,41 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System.Globalization;
+using System.IO;
+using System.Text;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class TrimTests
+ {
+ [Fact]
+ public void Test()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ TrimOptions = TrimOptions.Trim,
+ };
+ using (var stream = new MemoryStream())
+ using (var reader = new StreamReader(stream))
+ using (var writer = new StreamWriter(stream))
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteField(" a b c ");
+ csv.WriteField(" d e f ");
+ csv.NextRecord();
+ writer.Flush();
+ stream.Position = 0;
+
+ var expected = new TestStringBuilder(csv.Configuration.NewLine);
+ expected.AppendLine("a b c,d e f");
+
+ Assert.Equal(expected.ToString(), reader.ReadToEnd());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteBufferTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteBufferTests.cs
new file mode 100644
index 0000000..4e73fab
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteBufferTests.cs
@@ -0,0 +1,36 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using CsvHelper.Configuration;
+using Xunit;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests.Writing
+{
+
+ public class WriteBufferTests
+ {
+ [Fact]
+ public void Write_FieldThatIsLargerThenTwiceTheBuffer_Writes()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ BufferSize = 16
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ var random = new Random();
+ csv.WriteField("one");
+ csv.WriteField(new string(Enumerable.Range(0, 1000).Select(i => (char)random.Next((int)'a', (int)'z' + 1)).ToArray()));
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteCustomEscapeTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteCustomEscapeTests.cs
new file mode 100644
index 0000000..f45da08
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteCustomEscapeTests.cs
@@ -0,0 +1,63 @@
+using CsvHelper.Configuration;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+ public class WriteCustomEscapeTests
+ {
+ [Fact]
+ public void WriteField_CustomEscapeChar_ModeRFC4180_EscapesQuotesAndEscapeCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ Escape = '\\',
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ // {"json":"{\"name\":\"foo\"}"}
+ // json string -> csv field
+ // "{\"json\":\"{\\\"name\\\":\\\"foo\\\"}\"}"
+ csv.WriteField(@"{""json"":""{\""name\"":\""foo\""}""}");
+ csv.Flush();
+
+ var expected = @"""{\""json\"":\""{\\\""name\\\"":\\\""foo\\\""}\""}""";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteField_CustomEscapeChar_ModeEscape_EscapesQuotesAndEscapeCharacter()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture)
+ {
+ HasHeaderRecord = false,
+ Escape = '\\',
+ Mode = CsvMode.Escape,
+ };
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ // {"json":"{\"name\":\"foo\"}"}
+ // json string -> csv field
+ // {\"json\":\"{\\\"name\\\":\\\"foo\\\"}\"}
+ csv.WriteField(@"{""json"":""{\""name\"":\""foo\""}""}");
+ csv.Flush();
+
+ var expected = @"{\""json\"":\""{\\\""name\\\"":\\\""foo\\\""}\""}";
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteNullTests.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteNullTests.cs
new file mode 100644
index 0000000..7d7f23f
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/Writing/WriteNullTests.cs
@@ -0,0 +1,84 @@
+using CsvHelper.Configuration;
+using System.Collections;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Xunit;
+
+namespace CsvHelper.Tests.Writing
+{
+ public class WriteNullTests
+ {
+ [Fact]
+ public void WriteRecordsEnumerableGeneric_RecordIsNull_WritesEmptyRecord()
+ {
+ var records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one"},
+ null,
+ new Foo { Id = 2, Name = "two" },
+ };
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+ csv.Flush();
+
+ var expected = new TestStringBuilder(config.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+ expected.AppendLine(",");
+ expected.AppendLine("2,two");
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteRecordsEnumerable_RecordIsNull_WritesEmptyRecord()
+ {
+ IEnumerable records = new List<Foo>
+ {
+ new Foo { Id = 1, Name = "one"},
+ null,
+ new Foo { Id = 2, Name = "two" },
+ };
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecords(records);
+ csv.Flush();
+
+ var expected = new TestStringBuilder(config.NewLine);
+ expected.AppendLine("Id,Name");
+ expected.AppendLine("1,one");
+ expected.AppendLine("");
+ expected.AppendLine("2,two");
+
+ Assert.Equal(expected, writer.ToString());
+ }
+ }
+
+ [Fact]
+ public void WriteRecord_RecordIsNull_WritesEmptyRecord()
+ {
+ var config = new CsvConfiguration(CultureInfo.InvariantCulture);
+ using (var writer = new StringWriter())
+ using (var csv = new CsvWriter(writer, config))
+ {
+ csv.WriteRecord((Foo)null);
+ csv.Flush();
+
+ Assert.Equal(",", writer.ToString());
+ }
+ }
+
+ private class Foo
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/XunitException.cs b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/XunitException.cs
new file mode 100644
index 0000000..d209d41
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/XunitException.cs
@@ -0,0 +1,19 @@
+// Copyright 2009-2022 Josh Close
+// This file is a part of CsvHelper and is dual licensed under MS-PL and Apache 2.0.
+// See LICENSE.txt for details or visit http://www.opensource.org/licenses/ms-pl.html for MS-PL and http://opensource.org/licenses/Apache-2.0 for Apache 2.0.
+// https://github.com/JoshClose/CsvHelper
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CsvHelper.Tests
+{
+ public class XUnitException : Exception
+ {
+ public XUnitException() : base() { }
+
+ public XUnitException(string message) : base(message) { }
+ }
+}
diff --git a/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/xunit.runner.json b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/xunit.runner.json
new file mode 100644
index 0000000..d4e998c
--- /dev/null
+++ b/ThirdParty/CsvHelper-master/tests/CsvHelper.Tests/xunit.runner.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json",
+ "parallelizeTestCollections": false
+} \ No newline at end of file