diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 636a519..a1f96eb 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,17 +1,17 @@ name: CI -on: [push, pull_request] +on: [ push, pull_request ] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore source - name: Build diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 9983a65..67c93af 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -8,13 +8,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v4 with: - dotnet-version: 8.0.x + dotnet-version: 9.0.x - run: echo "ACTIONS_ALLOW_UNSECURE_COMMANDS=true" >> $GITHUB_ENV - name: Install GitVersion uses: gittools/actions/gitversion/setup@v0 diff --git a/README.md b/README.md index c1e49a9..f2a968f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,6 @@ NoCommonsNET Port av NoCommons-biblioteket for .NET - * https://github.com/bekkopen/NoCommons +* https://github.com/bekkopen/NoCommons - Sample apps can be found [in the samples repo](https://github.com/johnkors/NoCommonsNET.Samples) +Sample apps can be found [in the samples repo](https://github.com/johnkors/NoCommonsNET.Samples) diff --git a/source/.editorconfig b/source/.editorconfig new file mode 100644 index 0000000..3dc8841 --- /dev/null +++ b/source/.editorconfig @@ -0,0 +1,162 @@ +# Remove the line below if you want to inherit .editorconfig settings from higher directories +root = true + +[*] +charset = utf-8 +insert_final_newline = true + +# C# files +[*.cs] + +#### Core EditorConfig Options #### + +# Indentation and spacing +indent_size = 4 +indent_style = space +tab_width = 4 + +# New line preferences +insert_final_newline = true +trim_trailing_whitespace = true + + +#### .NET Coding Conventions #### + +# this. and Me. preferences +dotnet_style_qualification_for_event = false:warning +dotnet_style_qualification_for_field = false:warning +dotnet_style_qualification_for_method = false:warning +dotnet_style_qualification_for_property = false:warning + +# Language keywords vs BCL types preferences +dotnet_style_predefined_type_for_locals_parameters_members = true:silent +dotnet_style_predefined_type_for_member_access = true:silent + +# Parentheses preferences +dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent +dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent +dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent + +# Modifier preferences +dotnet_style_require_accessibility_modifiers = for_non_interface_members:warning + +# Expression-level preferences +csharp_style_deconstructed_variable_declaration = true:suggestion +csharp_style_inlined_variable_declaration = true:suggestion +csharp_style_throw_expression = true:suggestion +dotnet_style_coalesce_expression = true:suggestion +dotnet_style_collection_initializer = true:suggestion +dotnet_style_explicit_tuple_names = true:suggestion +dotnet_style_null_propagation = true:suggestion +dotnet_style_object_initializer = true:suggestion +dotnet_style_prefer_auto_properties = true:silent +dotnet_style_prefer_compound_assignment = true:suggestion +dotnet_style_prefer_conditional_expression_over_assignment = true:silent +dotnet_style_prefer_conditional_expression_over_return = true:silent +dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion +dotnet_style_prefer_inferred_tuple_names = true:suggestion +dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion + +# Field preferences +dotnet_style_readonly_field = true:suggestion + +# Parameter preferences +dotnet_code_quality_unused_parameters = all:suggestion + +#### C# Coding Conventions #### + +# var preferences +csharp_style_var_elsewhere = false:silent +csharp_style_var_for_built_in_types = false:silent +csharp_style_var_when_type_is_apparent = false:silent + +# Expression-bodied members +csharp_style_expression_bodied_accessors = true:silent +csharp_style_expression_bodied_constructors = false:silent +csharp_style_expression_bodied_indexers = true:silent +csharp_style_expression_bodied_lambdas = true:silent +csharp_style_expression_bodied_local_functions = false:silent +csharp_style_expression_bodied_methods = false:silent +csharp_style_expression_bodied_operators = false:silent +csharp_style_expression_bodied_properties = true:silent + +# Pattern matching preferences +csharp_style_pattern_matching_over_as_with_null_check = true:suggestion +csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion + +# Null-checking preferences +csharp_style_conditional_delegate_call = true:suggestion + +# Modifier preferences +csharp_preferred_modifier_order = public, private, protected, internal, static, extern, new, virtual, abstract, sealed, override, readonly, unsafe, volatile, async + +# Code-block preferences +csharp_prefer_braces = true:silent + +# Expression-level preferences +csharp_prefer_simple_default_expression = true:suggestion +csharp_style_pattern_local_over_anonymous_function = true:suggestion +csharp_style_prefer_index_operator = true:suggestion +csharp_style_prefer_range_operator = true:suggestion +csharp_style_unused_value_assignment_preference = discard_variable:suggestion +csharp_style_unused_value_expression_statement_preference = discard_variable:silent + +# C# 10 +csharp_style_namespace_declarations = file_scoped:error +csharp_style_prefer_primary_constructors = true +dotnet_diagnostic.IDE0290.severity = error + + +#### C# Formatting Rules #### + +# New line preferences +csharp_new_line_before_catch = true +csharp_new_line_before_else = true +csharp_new_line_before_finally = true +csharp_new_line_before_members_in_anonymous_types = true +csharp_new_line_before_members_in_object_initializers = true +csharp_new_line_before_open_brace = all +csharp_new_line_between_query_expression_clauses = true + +# Indentation preferences +csharp_indent_block_contents = true +csharp_indent_braces = false +csharp_indent_case_contents = true +csharp_indent_case_contents_when_block = true +csharp_indent_labels = one_less_than_current +csharp_indent_switch_labels = true + +# Space preferences +csharp_space_after_cast = false +csharp_space_after_colon_in_inheritance_clause = true +csharp_space_after_comma = true +csharp_space_after_dot = false +csharp_space_after_keywords_in_control_flow_statements = true +csharp_space_after_semicolon_in_for_statement = true +csharp_space_around_binary_operators = before_and_after +csharp_space_around_declaration_statements = false +csharp_space_before_colon_in_inheritance_clause = true +csharp_space_before_comma = false +csharp_space_before_dot = false +csharp_space_before_open_square_brackets = false +csharp_space_before_semicolon_in_for_statement = false +csharp_space_between_empty_square_brackets = false +csharp_space_between_method_call_empty_parameter_list_parentheses = false +csharp_space_between_method_call_name_and_opening_parenthesis = false +csharp_space_between_method_call_parameter_list_parentheses = false +csharp_space_between_method_declaration_empty_parameter_list_parentheses = false +csharp_space_between_method_declaration_name_and_open_parenthesis = false +csharp_space_between_method_declaration_parameter_list_parentheses = false +csharp_space_between_parentheses = false +csharp_space_between_square_brackets = false + +# Wrapping preferences +csharp_preserve_single_line_blocks = true +csharp_preserve_single_line_statements = true + + +[*.csproj] +indent_size = 2 +indent_style = space +tab_width = 2 diff --git a/source/NoCommons.NET.sln b/source/NoCommons.NET.sln index e0b79cd..32fc114 100644 --- a/source/NoCommons.NET.sln +++ b/source/NoCommons.NET.sln @@ -13,6 +13,7 @@ ProjectSection(SolutionItems) = preProject .github\workflows\CI.yml = ..\.github\workflows\CI.yml .github\workflows\Release.yml = ..\.github\workflows\Release.yml GitVersion.yml = ..\GitVersion.yml + .editorconfig = .editorconfig EndProjectSection EndProject Global diff --git a/source/NoCommons.Tests/AssertionUtils.cs b/source/NoCommons.Tests/AssertionUtils.cs index e2c8921..f23cb1b 100644 --- a/source/NoCommons.Tests/AssertionUtils.cs +++ b/source/NoCommons.Tests/AssertionUtils.cs @@ -1,16 +1,10 @@ -using System; -using Xunit; +namespace NoCommons.Tests; -namespace NoCommons.Tests +public class AssertionUtils { - public class AssertionUtils + public static void AssertMessageContains(ArgumentException argumentException, string errorSyntax) { - public static void AssertMessageContains(ArgumentException argumentException, string errorSyntax) - { - bool containsText = argumentException.Message.Contains(errorSyntax); - Assert.True(containsText); - } - - + bool containsText = argumentException.Message.Contains(errorSyntax); + Assert.True(containsText); } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Banking/IbanValidationTests.cs b/source/NoCommons.Tests/Banking/IbanValidationTests.cs index 40fccaf..1b5ba0e 100644 --- a/source/NoCommons.Tests/Banking/IbanValidationTests.cs +++ b/source/NoCommons.Tests/Banking/IbanValidationTests.cs @@ -1,32 +1,29 @@ -using Xunit; using NoCommons.Banking; -namespace NoCommons.Tests.Banking +namespace NoCommons.Tests.Banking; + +public class IbanValidationTests { - public class IbanValidationTests + /// Structure for IBAN in a lot of counties are found here: + /// URL: http://www.ecbs.org/iban.htm + [Theory] + [InlineData("NO9386011117947", "Norway")] + [InlineData("ES9121000418450200051332", "Spain")] + public void TestValidNorwegianIban(string ibanValue, string country) { - /// Structure for IBAN in a lot of counties are found here: - /// URL: http://www.ecbs.org/iban.htm - [Theory] - [InlineData("NO9386011117947", "Norway")] - [InlineData("ES9121000418450200051332", "Spain")] - public void TestValidNorwegianIban(string ibanValue, string country) - { - Assert.True(IbanValidator.IsValid(ibanValue), string.Format("Invalid for {0}", country)); - } - - [Theory] - [InlineData("NO93 8601 1117 947", "On valid print format, but not valid digital format")] - [InlineData("ES91 2100 0418 4502 0005 1332", "On valid print format, but not valid digital format")] - [InlineData("no9386011117947", "Lower case country code")] - [InlineData("9386011117947", "Missing country code")] - [InlineData("NO938601111794", "Missing end digit")] - [InlineData("", "Empty string")] - [InlineData(null, "null")] - public void InvalidIbansReturnsFalse(string ibanValue, string reason) - { - Assert.False(IbanValidator.IsValid(ibanValue), string.Format("Valid when {0}. ", reason)); - } + Assert.True(IbanValidator.IsValid(ibanValue), $"Invalid for {country}"); + } + [Theory] + [InlineData("NO93 8601 1117 947", "On valid print format, but not valid digital format")] + [InlineData("ES91 2100 0418 4502 0005 1332", "On valid print format, but not valid digital format")] + [InlineData("no9386011117947", "Lower case country code")] + [InlineData("9386011117947", "Missing country code")] + [InlineData("NO938601111794", "Missing end digit")] + [InlineData("", "Empty string")] + [InlineData(null, "null")] + public void InvalidIbansReturnsFalse(string? ibanValue, string reason) + { + Assert.False(IbanValidator.IsValid(ibanValue), $"Valid when {reason}. "); } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Banking/KidnummerValidatorTests.cs b/source/NoCommons.Tests/Banking/KidnummerValidatorTests.cs index 2f0304a..8b9bf47 100644 --- a/source/NoCommons.Tests/Banking/KidnummerValidatorTests.cs +++ b/source/NoCommons.Tests/Banking/KidnummerValidatorTests.cs @@ -1,86 +1,101 @@ -using System; -using Xunit; using NoCommons.Banking; using NoCommons.Common; -namespace NoCommons.Tests.Banking +namespace NoCommons.Tests.Banking; + +public class KidnummerValidatorTests { - public class KidnummerValidatorTests + private const string KIDNUMMER_VALID_MOD10 = "2345676"; + private const string KIDNUMMER_VALID_MOD11 = "12345678903"; + private const string KIDNUMMER_INVALID_CHECKSUM = "2345674"; + private const string KIDNUMMER_INVALID_LENGTH_SHORT = "1"; + private const string KIDNUMMER_INVALID_LENGTH_LONG = "12345678901234567890123456"; + + [Fact] + public void testInvalidKidnummer() { - private const string KIDNUMMER_VALID_MOD10 = "2345676"; - private const string KIDNUMMER_VALID_MOD11 = "12345678903"; - private const string KIDNUMMER_INVALID_CHECKSUM = "2345674"; - private const string KIDNUMMER_INVALID_LENGTH_SHORT = "1"; - private const string KIDNUMMER_INVALID_LENGTH_LONG = "12345678901234567890123456"; - - protected void assertMessageContains(ArgumentException e, string message) + try { - Assert.Contains(message, e.Message); + KidnummerValidator.ValidateSyntax(""); + Assert.True(false); } - - [Fact] - public void testInvalidKidnummer() { - try { - KidnummerValidator.ValidateSyntax(""); - Assert.True(false); - } catch (ArgumentException e) { - assertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } + catch (ArgumentException e) + { + Assert.Contains(StringNumberValidator.ERROR_SYNTAX, e.Message); } + } - [Fact] - public void testInvalidKidnummerNotDigits() { - try { - KidnummerValidator.ValidateSyntax("abcdefghijk"); - Assert.True(false); - } catch (ArgumentException e) { - assertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } + [Fact] + public void testInvalidKidnummerNotDigits() + { + try + { + KidnummerValidator.ValidateSyntax("abcdefghijk"); + Assert.True(false); } - - [Fact] - public void testInvalidKidnummerTooShort() { - try { - KidnummerValidator.ValidateSyntax(KIDNUMMER_INVALID_LENGTH_SHORT); - Assert.True(false); - } catch (ArgumentException e) { - assertMessageContains(e, KidnummerValidator.ERROR_LENGTH); - } + catch (ArgumentException e) + { + Assert.Contains(StringNumberValidator.ERROR_SYNTAX, e.Message); } + } - [Fact] - public void testInvalidKidnummerTooLong() { - try { - KidnummerValidator.ValidateSyntax(KIDNUMMER_INVALID_LENGTH_LONG); - Assert.True(false); - } catch (ArgumentException e) { - assertMessageContains(e, KidnummerValidator.ERROR_LENGTH); - } + [Fact] + public void testInvalidKidnummerTooShort() + { + try + { + KidnummerValidator.ValidateSyntax(KIDNUMMER_INVALID_LENGTH_SHORT); + Assert.True(false); } - - [Fact] - public void testInvalidKidnummerWrongChecksum() { - try { - KidnummerValidator.ValidateChecksum(KIDNUMMER_INVALID_CHECKSUM); - Assert.True(false); - } catch (ArgumentException e) { - assertMessageContains(e, StringNumberValidator.ERROR_INVALID_CHECKSUM); - } + catch (ArgumentException e) + { + Assert.Contains(KidnummerValidator.ERROR_LENGTH, e.Message); } + } - [Fact] - public void testIsValidMod10() { - Assert.True(KidnummerValidator.IsValid(KIDNUMMER_VALID_MOD10)); + [Fact] + public void testInvalidKidnummerTooLong() + { + try + { + KidnummerValidator.ValidateSyntax(KIDNUMMER_INVALID_LENGTH_LONG); + Assert.True(false); } - - [Fact] - public void testIsValidMod11() { - Assert.True(KidnummerValidator.IsValid(KIDNUMMER_VALID_MOD11)); + catch (ArgumentException e) + { + Assert.Contains(KidnummerValidator.ERROR_LENGTH, e.Message); } + } - [Fact] - public void testIsInvalid() { - Assert.False(KidnummerValidator.IsValid(KIDNUMMER_INVALID_CHECKSUM)); + [Fact] + public void testInvalidKidnummerWrongChecksum() + { + try + { + KidnummerValidator.ValidateChecksum(KIDNUMMER_INVALID_CHECKSUM); + Assert.True(false); + } + catch (ArgumentException e) + { + Assert.Contains(StringNumberValidator.ERROR_INVALID_CHECKSUM, e.Message); } } -} \ No newline at end of file + + [Fact] + public void testIsValidMod10() + { + Assert.True(KidnummerValidator.IsValid(KIDNUMMER_VALID_MOD10)); + } + + [Fact] + public void testIsValidMod11() + { + Assert.True(KidnummerValidator.IsValid(KIDNUMMER_VALID_MOD11)); + } + + [Fact] + public void testIsInvalid() + { + Assert.False(KidnummerValidator.IsValid(KIDNUMMER_INVALID_CHECKSUM)); + } +} diff --git a/source/NoCommons.Tests/Banking/KontonrValideringTests.cs b/source/NoCommons.Tests/Banking/KontonrValideringTests.cs index 00c39cc..aeeacb8 100644 --- a/source/NoCommons.Tests/Banking/KontonrValideringTests.cs +++ b/source/NoCommons.Tests/Banking/KontonrValideringTests.cs @@ -1,157 +1,157 @@ -using System; using System.Text; -using Xunit; using NoCommons.Banking; using NoCommons.Common; -namespace NoCommons.Tests.Banking +namespace NoCommons.Tests.Banking; + +public class KontonrValideringTests { - public class KontonrValideringTests + private const string KONTONUMMER_VALID = "99990000006"; + private const string KONTONUMMER_INVALID_CHECKSUM = "99990000005"; + + [Fact] + public void TestInvalidKontonummerWrongLength() { - private const string KONTONUMMER_VALID = "99990000006"; - private const string KONTONUMMER_INVALID_CHECKSUM = "99990000005"; - - [Fact] - public void TestInvalidKontonummerWrongLength() - { - try - { - KontonummerValidator.ValidateSyntax("123456789012"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestInvalidKontonummerNotDigits() - { - try - { - KontonummerValidator.ValidateSyntax("abcdefghijk"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestInvalidKontonummerWrongChecksum() - { - try - { - KontonummerValidator.ValidateChecksum(KONTONUMMER_INVALID_CHECKSUM); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_INVALID_CHECKSUM); - } - } - - [Fact] - public void TestInvalidAccountTypeWrongLength() - { - var b = new StringBuilder(KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS + 1); - for (int i = 0; i < KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS + 1; i++) - { - b.Append("0"); - } - try - { - KontonummerValidator.ValidateAccountTypeSyntax(b.ToString()); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestInvalidAccountTypeNotDigits() - { - var b = new StringBuilder(KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS); - for (int i = 0; i < KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS; i++) - { - b.Append("A"); - } - try - { - KontonummerValidator.ValidateAccountTypeSyntax(b.ToString()); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestInvalidRegisternummerNotDigits() - { - var b = new StringBuilder(KontonummerValidator.REGISTERNUMMER_NUM_DIGITS); - for (int i = 0; i < KontonummerValidator.REGISTERNUMMER_NUM_DIGITS; i++) - { - b.Append("A"); - } - try - { - KontonummerValidator.ValidateRegisternummerSyntax(b.ToString()); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestInvalidRegisternummerWrongLength() - { - var b = new StringBuilder(KontonummerValidator.REGISTERNUMMER_NUM_DIGITS + 1); - for (int i = 0; i < KontonummerValidator.REGISTERNUMMER_NUM_DIGITS + 1; i++) - { - b.Append("0"); - } - try - { - KontonummerValidator.ValidateRegisternummerSyntax(b.ToString()); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); - } - } - - [Fact] - public void TestGetValidKontonummerFromInvalidKontonummerWrongChecksum() - { - Kontonummer knr = KontonummerValidator.GetAndForceValidKontonummer(KONTONUMMER_INVALID_CHECKSUM); - Assert.True(KontonummerValidator.IsValid(knr.ToString())); - } - - [Fact] - public void TestIsValid() - { - Assert.True(KontonummerValidator.IsValid(KONTONUMMER_VALID)); - Assert.False(KontonummerValidator.IsValid(KONTONUMMER_INVALID_CHECKSUM)); - } - - [Theory] - [InlineData("97104133219")] - [InlineData("97105302049")] - [InlineData("97104008309")] - [InlineData("97102749069")] - public void TestValidNumberEndingOn9(string kontonrEndingOn9) - { - Assert.True(KontonummerValidator.IsValid(kontonrEndingOn9)); + try + { + KontonummerValidator.ValidateSyntax("123456789012"); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); + } + } + + [Fact] + public void TestInvalidKontonummerNotDigits() + { + try + { + KontonummerValidator.ValidateSyntax("abcdefghijk"); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); } } -} + [Fact] + public void TestInvalidKontonummerWrongChecksum() + { + try + { + KontonummerValidator.ValidateChecksum(KONTONUMMER_INVALID_CHECKSUM); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_INVALID_CHECKSUM); + } + } + + [Fact] + public void TestInvalidAccountTypeWrongLength() + { + StringBuilder b = new(KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS + 1); + for (int i = 0; i < KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS + 1; i++) + { + b.Append("0"); + } + + try + { + KontonummerValidator.ValidateAccountTypeSyntax(b.ToString()); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); + } + } + + [Fact] + public void TestInvalidAccountTypeNotDigits() + { + StringBuilder b = new(KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS); + for (int i = 0; i < KontonummerValidator.ACCOUNTTYPE_NUM_DIGITS; i++) + { + b.Append("A"); + } + + try + { + KontonummerValidator.ValidateAccountTypeSyntax(b.ToString()); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); + } + } + + [Fact] + public void TestInvalidRegisternummerNotDigits() + { + StringBuilder b = new(KontonummerValidator.REGISTERNUMMER_NUM_DIGITS); + for (int i = 0; i < KontonummerValidator.REGISTERNUMMER_NUM_DIGITS; i++) + { + b.Append("A"); + } + + try + { + KontonummerValidator.ValidateRegisternummerSyntax(b.ToString()); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); + } + } + + [Fact] + public void TestInvalidRegisternummerWrongLength() + { + StringBuilder b = new(KontonummerValidator.REGISTERNUMMER_NUM_DIGITS + 1); + for (int i = 0; i < KontonummerValidator.REGISTERNUMMER_NUM_DIGITS + 1; i++) + { + b.Append("0"); + } + + try + { + KontonummerValidator.ValidateRegisternummerSyntax(b.ToString()); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, StringNumberValidator.ERROR_SYNTAX); + } + } + + [Fact] + public void TestGetValidKontonummerFromInvalidKontonummerWrongChecksum() + { + Kontonummer knr = KontonummerValidator.GetAndForceValidKontonummer(KONTONUMMER_INVALID_CHECKSUM); + Assert.True(KontonummerValidator.IsValid(knr.ToString())); + } + + [Fact] + public void TestIsValid() + { + Assert.True(KontonummerValidator.IsValid(KONTONUMMER_VALID)); + Assert.False(KontonummerValidator.IsValid(KONTONUMMER_INVALID_CHECKSUM)); + } + + [Theory] + [InlineData("97104133219")] + [InlineData("97105302049")] + [InlineData("97104008309")] + [InlineData("97102749069")] + public void TestValidNumberEndingOn9(string kontonrEndingOn9) + { + Assert.True(KontonummerValidator.IsValid(kontonrEndingOn9)); + } +} diff --git a/source/NoCommons.Tests/Banking/KontonummerCalculatorTests.cs b/source/NoCommons.Tests/Banking/KontonummerCalculatorTests.cs index 42ab820..a9bab6d 100644 --- a/source/NoCommons.Tests/Banking/KontonummerCalculatorTests.cs +++ b/source/NoCommons.Tests/Banking/KontonummerCalculatorTests.cs @@ -1,50 +1,47 @@ -using Xunit; using NoCommons.Banking; -namespace NoCommons.Tests.Banking +namespace NoCommons.Tests.Banking; + +public class KontonummerCalculatorTests { - public class KontonummerCalculatorTests - { - private const int LIST_LENGTH = 100; - private const string TEST_ACCOUNT_TYPE = "45"; - private const string TEST_REGISTERNUMMER = "9710"; + private const int LIST_LENGTH = 100; + private const string TEST_ACCOUNT_TYPE = "45"; + private const string TEST_REGISTERNUMMER = "9710"; - [Fact] - public void testGetKontonummerList() + [Fact] + public void testGetKontonummerList() + { + List? options = KontonummerCalculator.GetKontonummerList(LIST_LENGTH); + Assert.Equal(LIST_LENGTH, options.Count); + foreach (Kontonummer k in options) { - var options = KontonummerCalculator.GetKontonummerList(LIST_LENGTH); - Assert.Equal(LIST_LENGTH, options.Count); - foreach (Kontonummer k in options) - { - Assert.True(KontonummerValidator.IsValid(k.ToString())); - } + Assert.True(KontonummerValidator.IsValid(k.ToString())); } + } - [Fact] - public void testGetKontonummerListForAccountType() + [Fact] + public void testGetKontonummerListForAccountType() + { + List? options = + KontonummerCalculator.GetKontonummerListForAccountType(TEST_ACCOUNT_TYPE, LIST_LENGTH); + Assert.Equal(LIST_LENGTH, options.Count); + foreach (Kontonummer option in options) { - var options = KontonummerCalculator.GetKontonummerListForAccountType(TEST_ACCOUNT_TYPE, LIST_LENGTH); - Assert.Equal(LIST_LENGTH, options.Count); - foreach (Kontonummer option in options) - { - Assert.True(KontonummerValidator.IsValid(option.ToString()), "Invalid kontonr. "); - Assert.True(option.GetAccountType().Equals(TEST_ACCOUNT_TYPE), "Invalid account type. "); - } + Assert.True(KontonummerValidator.IsValid(option.ToString())); + Assert.Equal(TEST_ACCOUNT_TYPE, option.GetAccountType()); } + } - [Fact] - public void testGetKontonummerListForRegisternummer() + [Fact] + public void testGetKontonummerListForRegisternummer() + { + List? options = + KontonummerCalculator.GetKontonummerListForRegisternummer(TEST_REGISTERNUMMER, LIST_LENGTH); + Assert.Equal(LIST_LENGTH, options.Count); + foreach (Kontonummer? option in options) { - var options = KontonummerCalculator.GetKontonummerListForRegisternummer(TEST_REGISTERNUMMER, LIST_LENGTH); - Assert.Equal(LIST_LENGTH, options.Count); - foreach (Kontonummer option in options) - { - - Assert.True(KontonummerValidator.IsValid(option.ToString())); - Assert.True(option.GetRegisternummer().Equals(TEST_REGISTERNUMMER)); - } + Assert.True(KontonummerValidator.IsValid(option.ToString())); + Assert.Equal(TEST_REGISTERNUMMER, option.GetRegisternummer()); } } - - -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Date/NorwegianDateUtilTests.cs b/source/NoCommons.Tests/Date/NorwegianDateUtilTests.cs index 9c30f9b..bd32e68 100644 --- a/source/NoCommons.Tests/Date/NorwegianDateUtilTests.cs +++ b/source/NoCommons.Tests/Date/NorwegianDateUtilTests.cs @@ -1,134 +1,130 @@ -using System; using System.Globalization; -using System.Linq; -using Xunit; using NoCommons.Date; -namespace NoCommons.Tests.Date +namespace NoCommons.Tests.Date; + +public class NorwegianDateUtilTest { - public class NorwegianDateUtilTest + [Fact] + public void testAdd2DaysWithinSameWeek() + { + DateTime date = new(2007, 3, 21); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 2); + + Assert.Equal(23, newDate.Day); + } + + [Fact] + public void testAdd2DaysToLastDayOfMonth() + { + DateTime date = new(2007, 2, 28); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 2); + + Assert.Equal(2, newDate.Day); + Assert.Equal(3, newDate.Month); + } + + [Fact] + public void testAdd5DaysWithNoHolidays() + { + DateTime date = new(2007, 03, 21); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); + + Assert.Equal(28, newDate.Day); + } + + [Fact] + public void testAdd5DaysBeforeEasterHoliday() + { + DateTime date = new(2007, 4, 4); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); + + Assert.Equal(16, newDate.Day); + } + + [Fact] + public void testAdd5DaysBeforeNationalDay() + { + DateTime date = new(2007, 5, 16); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); + + Assert.Equal(24, newDate.Day); + } + + [Fact] + public void testAdd5DaysBeforeChristmas() + { + DateTime date = new(2007, 12, 21); + DateTime newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); + + Assert.Equal(2, newDate.Day); + Assert.Equal(1, newDate.Month); + Assert.Equal(2008, newDate.Year); + } + + [Fact] + public void testWorkingDays() + { + Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007, 3, 25)), "Sunday not working day"); + Assert.True(NorwegianDateUtil.IsWorkingDay(new DateTime(2007, 3, 26)), "Monday is working day"); + Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007, 1, 1)), "New years day not working day"); + Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007, 4, 8)), "Easter day not working day"); + } + + [Fact] + public void testVariousNorwegianHolidays() + { + // Set dates + checkHoliday("01.01.2007"); + checkHoliday("01.05.2007"); + checkHoliday("17.05.2007"); + checkHoliday("25.12.2007"); + checkHoliday("26.12.2007"); + + // Movable dates 2007 + checkHoliday("01.04.2007"); + checkHoliday("05.04.2007"); + checkHoliday("06.04.2007"); + checkHoliday("08.04.2007"); + checkHoliday("09.04.2007"); + checkHoliday("17.05.2007"); + checkHoliday("27.05.2007"); + checkHoliday("28.05.2007"); + + // Movable dates 2008 + checkHoliday("16.03.2008"); + checkHoliday("20.03.2008"); + checkHoliday("21.03.2008"); + checkHoliday("23.03.2008"); + checkHoliday("24.03.2008"); + checkHoliday("01.05.2008"); + checkHoliday("11.05.2008"); + checkHoliday("12.05.2008"); + } + + [Fact] + public void testGetAllNorwegianHolidaysForYear() + { + const string format = "dd.MM.yyyy"; + IEnumerable? holidays = NorwegianDateUtil.GetHolidays(2008); + Assert.Equal(12, holidays.Count()); + Assert.Equal("01.01.2008", holidays.ElementAt(0).ToString(format)); + Assert.Equal("16.03.2008", holidays.ElementAt(1).ToString(format)); + Assert.Equal("20.03.2008", holidays.ElementAt(2).ToString(format)); + Assert.Equal("21.03.2008", holidays.ElementAt(3).ToString(format)); + Assert.Equal("23.03.2008", holidays.ElementAt(4).ToString(format)); + Assert.Equal("24.03.2008", holidays.ElementAt(5).ToString(format)); + Assert.Equal("01.05.2008", holidays.ElementAt(6).ToString(format)); + Assert.Equal("11.05.2008", holidays.ElementAt(7).ToString(format)); + Assert.Equal("12.05.2008", holidays.ElementAt(8).ToString(format)); + Assert.Equal("17.05.2008", holidays.ElementAt(9).ToString(format)); + Assert.Equal("25.12.2008", holidays.ElementAt(10).ToString(format)); + Assert.Equal("26.12.2008", holidays.ElementAt(11).ToString(format)); + } + + private void checkHoliday(string date) { - [Fact] - public void testAdd2DaysWithinSameWeek() - { - var date = new DateTime(2007,3,21); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 2); - - Assert.Equal(23, newDate.Day); - } - - [Fact] - public void testAdd2DaysToLastDayOfMonth() - { - var date = new DateTime(2007, 2, 28); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 2); - - Assert.Equal(2, newDate.Day); - Assert.Equal(3, newDate.Month); - } - - [Fact] - public void testAdd5DaysWithNoHolidays() - { - var date = new DateTime(2007, 03, 21); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); - - Assert.Equal(28, newDate.Day); - } - - [Fact] - public void testAdd5DaysBeforeEasterHoliday() - { - var date = new DateTime(2007, 4, 4); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); - - Assert.Equal(16, newDate.Day); - } - - [Fact] - public void testAdd5DaysBeforeNationalDay() - { - var date = new DateTime(2007, 5, 16); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); - - Assert.Equal(24, newDate.Day); - } - - [Fact] - public void testAdd5DaysBeforeChristmas() - { - var date = new DateTime(2007, 12, 21); - var newDate = NorwegianDateUtil.AddWorkingDaysToDate(date, 5); - - Assert.Equal(2, newDate.Day); - Assert.Equal(1, newDate.Month); - Assert.Equal(2008, newDate.Year); - } - - [Fact] - public void testWorkingDays() - { - Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007,3,25)), "Sunday not working day"); - Assert.True(NorwegianDateUtil.IsWorkingDay(new DateTime(2007, 3, 26)), "Monday is working day"); - Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007,1,1)), "New years day not working day"); - Assert.False(NorwegianDateUtil.IsWorkingDay(new DateTime(2007,4,8)), "Easter day not working day"); - } - - [Fact] - public void testVariousNorwegianHolidays() - { - // Set dates - checkHoliday("01.01.2007"); - checkHoliday("01.05.2007"); - checkHoliday("17.05.2007"); - checkHoliday("25.12.2007"); - checkHoliday("26.12.2007"); - - // Movable dates 2007 - checkHoliday("01.04.2007"); - checkHoliday("05.04.2007"); - checkHoliday("06.04.2007"); - checkHoliday("08.04.2007"); - checkHoliday("09.04.2007"); - checkHoliday("17.05.2007"); - checkHoliday("27.05.2007"); - checkHoliday("28.05.2007"); - - // Movable dates 2008 - checkHoliday("16.03.2008"); - checkHoliday("20.03.2008"); - checkHoliday("21.03.2008"); - checkHoliday("23.03.2008"); - checkHoliday("24.03.2008"); - checkHoliday("01.05.2008"); - checkHoliday("11.05.2008"); - checkHoliday("12.05.2008"); - } - - [Fact] - public void testGetAllNorwegianHolidaysForYear() - { - const string format = "dd.MM.yyyy"; - var holidays = NorwegianDateUtil.GetHolidays(2008); - Assert.Equal(12, holidays.Count()); - Assert.Equal("01.01.2008", holidays.ElementAt(0).ToString(format)); - Assert.Equal("16.03.2008", holidays.ElementAt(1).ToString(format)); - Assert.Equal("20.03.2008", holidays.ElementAt(2).ToString(format)); - Assert.Equal("21.03.2008", holidays.ElementAt(3).ToString(format)); - Assert.Equal("23.03.2008", holidays.ElementAt(4).ToString(format)); - Assert.Equal("24.03.2008", holidays.ElementAt(5).ToString(format)); - Assert.Equal("01.05.2008", holidays.ElementAt(6).ToString(format)); - Assert.Equal("11.05.2008", holidays.ElementAt(7).ToString(format)); - Assert.Equal("12.05.2008", holidays.ElementAt(8).ToString(format)); - Assert.Equal("17.05.2008", holidays.ElementAt(9).ToString(format)); - Assert.Equal("25.12.2008", holidays.ElementAt(10).ToString(format)); - Assert.Equal("26.12.2008", holidays.ElementAt(11).ToString(format)); - } - - private void checkHoliday(string date) - { - var dateTime = DateTime.ParseExact(date, "dd.MM.yyyy", CultureInfo.InvariantCulture); - Assert.True(NorwegianDateUtil.IsHoliday(dateTime)); - } + DateTime dateTime = DateTime.ParseExact(date, "dd.MM.yyyy", CultureInfo.InvariantCulture); + Assert.True(NorwegianDateUtil.IsHoliday(dateTime)); } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/GlobalUsings.cs b/source/NoCommons.Tests/GlobalUsings.cs new file mode 100644 index 0000000..5b790a5 --- /dev/null +++ b/source/NoCommons.Tests/GlobalUsings.cs @@ -0,0 +1,3 @@ +// Global using directives + +global using Xunit; diff --git a/source/NoCommons.Tests/NoCommons.Tests.csproj b/source/NoCommons.Tests/NoCommons.Tests.csproj index 5c77dc4..8d4f059 100644 --- a/source/NoCommons.Tests/NoCommons.Tests.csproj +++ b/source/NoCommons.Tests/NoCommons.Tests.csproj @@ -1,23 +1,25 @@  - net8.0;net7.0 + net8.0;net9.0 + enable + enable + true + Exe + true - + - - - + + + all runtime; build; native; contentfiles; analyzers - - - diff --git a/source/NoCommons.Tests/Org/OrganisasjonsnummerCalculatorTests.cs b/source/NoCommons.Tests/Org/OrganisasjonsnummerCalculatorTests.cs index 862c46b..6721642 100644 --- a/source/NoCommons.Tests/Org/OrganisasjonsnummerCalculatorTests.cs +++ b/source/NoCommons.Tests/Org/OrganisasjonsnummerCalculatorTests.cs @@ -1,21 +1,19 @@ -using Xunit; using NoCommons.Org; -namespace NoCommons.Tests.Org +namespace NoCommons.Tests.Org; + +public class OrganisasjonsnummerCalculatorTests { - public class OrganisasjonsnummerCalculatorTests - { - private const int LIST_LENGTH = 100; + private const int LIST_LENGTH = 100; - [Fact] - public void testGetOrganisasjonsnummerList() + [Fact] + public void testGetOrganisasjonsnummerList() + { + List? options = OrganisasjonsnummerCalculator.GetOrganisasjonsnummerList(LIST_LENGTH); + Assert.Equal(LIST_LENGTH, options.Count); + foreach (Organisasjonsnummer? nr in options) { - var options = OrganisasjonsnummerCalculator.GetOrganisasjonsnummerList(LIST_LENGTH); - Assert.Equal(LIST_LENGTH, options.Count); - foreach (var nr in options) - { - Assert.True(OrganisasjonsnummerValidator.IsValid(nr.ToString())); - } + Assert.True(OrganisasjonsnummerValidator.IsValid(nr.ToString())); } } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Org/OrganisasjonsnummerValidatorTests.cs b/source/NoCommons.Tests/Org/OrganisasjonsnummerValidatorTests.cs index c693b67..8e1c4f2 100644 --- a/source/NoCommons.Tests/Org/OrganisasjonsnummerValidatorTests.cs +++ b/source/NoCommons.Tests/Org/OrganisasjonsnummerValidatorTests.cs @@ -1,71 +1,66 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using Xunit; using NoCommons.Org; -namespace NoCommons.Tests.Org +namespace NoCommons.Tests.Org; + +public class OrganisasjonsnummerValidatorTests { - public class OrganisasjonsnummerValidatorTests - { - private const string ORGNUMMER_VALID = "981566378"; - private const string ORGNUMMER_INVALID_CHECKSUM = "123456789"; + private const string ORGNUMMER_VALID = "981566378"; + private const string ORGNUMMER_INVALID_CHECKSUM = "123456789"; - [Fact] - public void testInvalidOrgnummerWrongLength() + [Fact] + public void testInvalidOrgnummerWrongLength() + { + try { - try - { - OrganisasjonsnummerValidator.ValidateSyntax("0123456789"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_SYNTAX); - } + OrganisasjonsnummerValidator.ValidateSyntax("0123456789"); + Assert.True(false); } - - [Fact] - public void testInvalidOrgnummerNotDigits() + catch (ArgumentException e) { - try - { - OrganisasjonsnummerValidator.ValidateSyntax("abcdefghijk"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_SYNTAX); - } + AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_SYNTAX); } + } - [Fact] - public void testInvalidOrgnummerWrongChecksum() + [Fact] + public void testInvalidOrgnummerNotDigits() + { + try { - try - { - OrganisasjonsnummerValidator.ValidateChecksum(ORGNUMMER_INVALID_CHECKSUM); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_INVALID_CHECKSUM); - } + OrganisasjonsnummerValidator.ValidateSyntax("abcdefghijk"); + Assert.True(false); } - - [Fact] - public void testGetValidOrgnummerFromInvalidOrgnummerWrongChecksum() + catch (ArgumentException e) { - Organisasjonsnummer orgNr = OrganisasjonsnummerValidator.GetAndForceValidOrganisasjonsnummer(ORGNUMMER_INVALID_CHECKSUM); - Assert.True(OrganisasjonsnummerValidator.IsValid(orgNr.ToString())); + AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_SYNTAX); } + } - [Fact] - public void testIsValid() + [Fact] + public void testInvalidOrgnummerWrongChecksum() + { + try { - Assert.True(OrganisasjonsnummerValidator.IsValid(ORGNUMMER_VALID)); - Assert.False(OrganisasjonsnummerValidator.IsValid(ORGNUMMER_INVALID_CHECKSUM)); + OrganisasjonsnummerValidator.ValidateChecksum(ORGNUMMER_INVALID_CHECKSUM); + Assert.True(false); } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, OrganisasjonsnummerValidator.ERROR_INVALID_CHECKSUM); + } + } + + [Fact] + public void testGetValidOrgnummerFromInvalidOrgnummerWrongChecksum() + { + Organisasjonsnummer orgNr = + OrganisasjonsnummerValidator.GetAndForceValidOrganisasjonsnummer(ORGNUMMER_INVALID_CHECKSUM); + Assert.True(OrganisasjonsnummerValidator.IsValid(orgNr.ToString())); + } + + [Fact] + public void testIsValid() + { + Assert.True(OrganisasjonsnummerValidator.IsValid(ORGNUMMER_VALID)); + Assert.False(OrganisasjonsnummerValidator.IsValid(ORGNUMMER_INVALID_CHECKSUM)); } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Person/FodselsnummerCalculatorTests.cs b/source/NoCommons.Tests/Person/FodselsnummerCalculatorTests.cs index 261b611..d8e7ee7 100644 --- a/source/NoCommons.Tests/Person/FodselsnummerCalculatorTests.cs +++ b/source/NoCommons.Tests/Person/FodselsnummerCalculatorTests.cs @@ -1,82 +1,79 @@ -using System; -using System.Collections.Generic; using System.Globalization; -using Xunit; using NoCommons.Person; -namespace NoCommons.Tests.Person +namespace NoCommons.Tests.Person; + +public class FodselsnummerCalculatorTest { - public class FodselsnummerCalculatorTest - { - private DateTime date; - private const string _dateFormat = "ddMMyyyy"; + private const string _dateFormat = "ddMMyyyy"; + private DateTime date; - public FodselsnummerCalculatorTest() - { - date = new DateTime(2006, 9, 6); - } + public FodselsnummerCalculatorTest() + { + date = new DateTime(2006, 9, 6); + } - [Fact] - public void testGetFodselsnummerForDateAndGender() - { - List options = FodselsnummerCalculator.GetFodselsnummerForDateAndGender(date, KJONN.KVINNE); - Assert.Equal(207, options.Count); - } + [Fact] + public void testGetFodselsnummerForDateAndGender() + { + List options = FodselsnummerCalculator.GetFodselsnummerForDateAndGender(date, KJONN.KVINNE); + Assert.Equal(207, options.Count); + } - [Fact] - public void getValidFodselsnummerForDate() - { - List validOptions = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); - Assert.True(validOptions.Count == 412, "Forventet 412 fødselsnumre, men fikk " + validOptions.Count); - } + [Fact] + public void getValidFodselsnummerForDate() + { + List validOptions = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); + Assert.True(validOptions.Count == 412, "Forventet 412 fødselsnumre, men fikk " + validOptions.Count); + } - [Fact] - public void getValidFodselsnummerForDNumberDate() - { - List validOptions = FodselsnummerCalculator.GetManyFodselsnummerForDate(date, true); - Assert.True(validOptions.Count == 413, "Forventet 412 fødselsnumre som er d-nummer, men fikk " + validOptions.Count); - } + [Fact] + public void getValidFodselsnummerForDNumberDate() + { + List validOptions = FodselsnummerCalculator.GetManyFodselsnummerForDate(date, true); + Assert.True(validOptions.Count == 413, + "Forventet 412 fødselsnumre som er d-nummer, men fikk " + validOptions.Count); + } - [Fact] - public void testThatAllGeneratedNumbersAreValid() + [Fact] + public void testThatAllGeneratedNumbersAreValid() + { + foreach (Fodselsnummer fnr in FodselsnummerCalculator.GetManyFodselsnummerForDate(date)) { - foreach (Fodselsnummer fnr in FodselsnummerCalculator.GetManyFodselsnummerForDate(date)) - { - Assert.True(FodselsnummerValidator.IsValid(fnr.ToString()), "Ugyldig fødselsnummer: " + fnr); - } + Assert.True(FodselsnummerValidator.IsValid(fnr.ToString()), "Ugyldig fødselsnummer: " + fnr); } + } - [Fact] - public void testThatAllGeneratedDFodselsnumbersAreValid() + [Fact] + public void testThatAllGeneratedDFodselsnumbersAreValid() + { + foreach (Fodselsnummer fnr in FodselsnummerCalculator.GetManyFodselsnummerForDate(date, true)) { - foreach (Fodselsnummer fnr in FodselsnummerCalculator.GetManyFodselsnummerForDate(date, true)) - { - Assert.True(FodselsnummerValidator.IsValid(fnr.ToString()), "Ugyldig fødselsnummer: " + fnr); - } + Assert.True(FodselsnummerValidator.IsValid(fnr.ToString()), "Ugyldig fødselsnummer: " + fnr); } + } - [Fact] - public void testInvalidDateTooEarly() - { - date = DateTime.ParseExact("09091853", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); - List options = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); - Assert.Empty(options); - } + [Fact] + public void testInvalidDateTooEarly() + { + date = DateTime.ParseExact("09091853", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); + List options = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); + Assert.Empty(options); + } - [Fact] - public void testInvalidDateTooLate() - { - date = DateTime.ParseExact("09092040", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); - List options = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); - Assert.Empty(options); - } + [Fact] + public void testInvalidDateTooLate() + { + date = DateTime.ParseExact("09092040", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); + List options = FodselsnummerCalculator.GetManyFodselsnummerForDate(date); + Assert.Empty(options); + } - [Fact] - public void testOneFodselsnummer() - { - date = DateTime.ParseExact("01121980", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); - Fodselsnummer fodselsnummer = FodselsnummerCalculator.GetFodselsnummerForDate(date); - Assert.True(FodselsnummerValidator.IsValid(fodselsnummer.ToString())); - } + [Fact] + public void testOneFodselsnummer() + { + date = DateTime.ParseExact("01121980", _dateFormat, CultureInfo.InvariantCulture, DateTimeStyles.None); + Fodselsnummer fodselsnummer = FodselsnummerCalculator.GetFodselsnummerForDate(date); + Assert.True(FodselsnummerValidator.IsValid(fodselsnummer.ToString())); } -} \ No newline at end of file +} diff --git a/source/NoCommons.Tests/Person/FodselsnummerTests.cs b/source/NoCommons.Tests/Person/FodselsnummerTests.cs index 4e59793..3d94b27 100644 --- a/source/NoCommons.Tests/Person/FodselsnummerTests.cs +++ b/source/NoCommons.Tests/Person/FodselsnummerTests.cs @@ -1,150 +1,168 @@ -using Xunit; using NoCommons.Person; -namespace NoCommons.Tests.Person +namespace NoCommons.Tests.Person; + +public class FodselsnummerTest { - public class FodselsnummerTest { - - private const string VALID_FODSELSNUMMER = "01010123476"; - - private const string VALID_D_FODSELSNUMMER = "41010123476"; - - private Fodselsnummer sut; - - public FodselsnummerTest() { - sut = new Fodselsnummer(VALID_FODSELSNUMMER); - } - - [Fact] - public void testGetDateAndMonth() { - Assert.Equal("0101", sut.GetDateAndMonth()); - } - - [Fact] - public void testGetDayInMonth() { - Assert.Equal("01", sut.GetDayInMonth()); - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.Equal("01", sut.GetDayInMonth()); - } - - [Fact] - public void testGetMonth() { - Assert.Equal("01", sut.GetMonth()); - } - - [Fact] - public void testGetDateAndMonthDNumber() { - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.Equal("0101", sut.GetDateAndMonth()); - } - - [Fact] - public void testGetCentury() { - sut = new Fodselsnummer("01016666609"); - Assert.Equal("18", sut.GetCentury()); - - sut = new Fodselsnummer("01016633301"); - Assert.Equal("19", sut.GetCentury()); - - sut = new Fodselsnummer("01019196697"); - Assert.Equal("19", sut.GetCentury()); - - sut = new Fodselsnummer("01013366671"); - Assert.Equal("20", sut.GetCentury()); - - // DNumber... - sut = new Fodselsnummer("41016666609"); - Assert.Equal("18", sut.GetCentury()); - - sut = new Fodselsnummer("01015466609"); - Assert.Equal("18", sut.GetCentury()); - - sut = new Fodselsnummer("41016633301"); - Assert.Equal("19", sut.GetCentury()); - - sut = new Fodselsnummer("41019196697"); - Assert.Equal("19", sut.GetCentury()); - - sut = new Fodselsnummer("41013366671"); - Assert.Equal("20", sut.GetCentury()); - } - - [Fact] - public void testGet2DigitBirthYear() { - Assert.Equal("01", sut.Get2DigitBirthYear()); - } - - [Fact] - public void testGetBirthYear() { - Assert.Equal("1901", sut.GetBirthYear()); - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.Equal("1901", sut.GetBirthYear()); - } - - [Fact] - public void testGetDateOfBirth() { - Assert.Equal("010101", sut.GetDateOfBirth()); - } - - [Fact] - public void testGetDateOfBirthDNumber() { - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.Equal("010101", sut.GetDateOfBirth()); - } - - [Fact] - public void testGetPersonnummer() { - Assert.Equal("23476", sut.GetPersonnummer()); - } - - [Fact] - public void testGetIndividnummer() { - Assert.Equal("234", sut.GetIndividnummer()); - } - - [Fact] - public void testGetGenderDigit() { - Assert.Equal(4, sut.GetGenderDigit()); - } - - [Fact] - public void testGetChecksumDigits() { - Assert.Equal(7, sut.GetChecksumDigit1()); - Assert.Equal(6, sut.GetChecksumDigit2()); - } - - [Fact] - public void testIsMale() { - Assert.False(sut.IsMale()); - } - - [Fact] - public void testIsMaleDNumber() { - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.False(sut.IsMale()); - } - - [Fact] - public void testIsFemale() { - Assert.True(sut.IsFemale()); - } - - [Fact] - public void testIsFemaleDNumber() { - sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); - Assert.True(sut.IsFemale()); - } - - [Fact] - public void testIsDNumber() { - Assert.False(Fodselsnummer.IsDNumber("01010101006")); - Assert.False(Fodselsnummer.IsDNumber("80000000000")); - Assert.True(Fodselsnummer.IsDNumber("47086303651")); - } - - [Fact] - public void testParseDNumber() { - Assert.Equal("07086303651", Fodselsnummer.ParseDNumber("47086303651")); - } - } -} \ No newline at end of file + private const string VALID_FODSELSNUMMER = "01010123476"; + + private const string VALID_D_FODSELSNUMMER = "41010123476"; + + private Fodselsnummer sut; + + public FodselsnummerTest() + { + sut = new Fodselsnummer(VALID_FODSELSNUMMER); + } + + [Fact] + public void testGetDateAndMonth() + { + Assert.Equal("0101", sut.GetDateAndMonth()); + } + + [Fact] + public void testGetDayInMonth() + { + Assert.Equal("01", sut.GetDayInMonth()); + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.Equal("01", sut.GetDayInMonth()); + } + + [Fact] + public void testGetMonth() + { + Assert.Equal("01", sut.GetMonth()); + } + + [Fact] + public void testGetDateAndMonthDNumber() + { + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.Equal("0101", sut.GetDateAndMonth()); + } + + [Fact] + public void testGetCentury() + { + sut = new Fodselsnummer("01016666609"); + Assert.Equal("18", sut.GetCentury()); + + sut = new Fodselsnummer("01016633301"); + Assert.Equal("19", sut.GetCentury()); + + sut = new Fodselsnummer("01019196697"); + Assert.Equal("19", sut.GetCentury()); + + sut = new Fodselsnummer("01013366671"); + Assert.Equal("20", sut.GetCentury()); + + // DNumber... + sut = new Fodselsnummer("41016666609"); + Assert.Equal("18", sut.GetCentury()); + + sut = new Fodselsnummer("01015466609"); + Assert.Equal("18", sut.GetCentury()); + + sut = new Fodselsnummer("41016633301"); + Assert.Equal("19", sut.GetCentury()); + + sut = new Fodselsnummer("41019196697"); + Assert.Equal("19", sut.GetCentury()); + + sut = new Fodselsnummer("41013366671"); + Assert.Equal("20", sut.GetCentury()); + } + + [Fact] + public void testGet2DigitBirthYear() + { + Assert.Equal("01", sut.Get2DigitBirthYear()); + } + + [Fact] + public void testGetBirthYear() + { + Assert.Equal("1901", sut.GetBirthYear()); + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.Equal("1901", sut.GetBirthYear()); + } + + [Fact] + public void testGetDateOfBirth() + { + Assert.Equal("010101", sut.GetDateOfBirth()); + } + + [Fact] + public void testGetDateOfBirthDNumber() + { + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.Equal("010101", sut.GetDateOfBirth()); + } + + [Fact] + public void testGetPersonnummer() + { + Assert.Equal("23476", sut.GetPersonnummer()); + } + + [Fact] + public void testGetIndividnummer() + { + Assert.Equal("234", sut.GetIndividnummer()); + } + + [Fact] + public void testGetGenderDigit() + { + Assert.Equal(4, sut.GetGenderDigit()); + } + + [Fact] + public void testGetChecksumDigits() + { + Assert.Equal(7, sut.GetChecksumDigit1()); + Assert.Equal(6, sut.GetChecksumDigit2()); + } + + [Fact] + public void testIsMale() + { + Assert.False(sut.IsMale()); + } + + [Fact] + public void testIsMaleDNumber() + { + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.False(sut.IsMale()); + } + + [Fact] + public void testIsFemale() + { + Assert.True(sut.IsFemale()); + } + + [Fact] + public void testIsFemaleDNumber() + { + sut = new Fodselsnummer(VALID_D_FODSELSNUMMER); + Assert.True(sut.IsFemale()); + } + + [Fact] + public void testIsDNumber() + { + Assert.False(Fodselsnummer.IsDNumber("01010101006")); + Assert.False(Fodselsnummer.IsDNumber("80000000000")); + Assert.True(Fodselsnummer.IsDNumber("47086303651")); + } + + [Fact] + public void testParseDNumber() + { + Assert.Equal("07086303651", Fodselsnummer.ParseDNumber("47086303651")); + } +} diff --git a/source/NoCommons.Tests/Person/FodselsnummerValidatorTests.cs b/source/NoCommons.Tests/Person/FodselsnummerValidatorTests.cs index c834e85..2428b04 100644 --- a/source/NoCommons.Tests/Person/FodselsnummerValidatorTests.cs +++ b/source/NoCommons.Tests/Person/FodselsnummerValidatorTests.cs @@ -1,159 +1,156 @@ -using System; -using Xunit; using NoCommons.Person; -namespace NoCommons.Tests.Person +namespace NoCommons.Tests.Person; + +public class FodselsnummerValidatorTests { - public class FodselsnummerValidatorTests + [Fact] + public void testInvalidFodselsnummerWrongLength() { - [Fact] - public void testInvalidFodselsnummerWrongLength() - { - try - { - FodselsnummerValidator.ValidateSyntax("0123456789"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_SYNTAX); - } + try + { + FodselsnummerValidator.ValidateSyntax("0123456789"); + Assert.True(false); } - - [Fact] - public void testInvalidFodselsnummerNotDigits() - { - try - { - FodselsnummerValidator.ValidateSyntax("abcdefghijk"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_SYNTAX); - } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_SYNTAX); } + } - [Fact] - public void testInvalidIndividnummer() - { - try - { - FodselsnummerValidator.validateIndividnummer("01015780000"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_INDIVIDNUMMER); - } + [Fact] + public void testInvalidFodselsnummerNotDigits() + { + try + { + FodselsnummerValidator.ValidateSyntax("abcdefghijk"); + Assert.True(false); } - - [Fact] - public void testInvalidDateMonthMax() - { - try - { - FodselsnummerValidator.validateDate("01130400000"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); - } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_SYNTAX); } + } - [Fact] - public void testInvalidDateMonthMin() - { - try - { - FodselsnummerValidator.validateDate("01000400000"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); - } + [Fact] + public void testInvalidIndividnummer() + { + try + { + FodselsnummerValidator.validateIndividnummer("01015780000"); + Assert.True(false); } - - [Fact] - public void testInvalidDateDayMin() - { - try - { - FodselsnummerValidator.validateDate("00120467800"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); - } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_INDIVIDNUMMER); } + } - [Fact] - public void testInvalidDateDayMax() - { - try - { - FodselsnummerValidator.validateDate("32120400000"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); - } + [Fact] + public void testInvalidDateMonthMax() + { + try + { + FodselsnummerValidator.validateDate("01130400000"); + Assert.True(false); } - - [Fact] - public void testInvalidDateLeapDay() - { - try - { - FodselsnummerValidator.validateDate("29020700000"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); - } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); } + } - [Fact] - public void testInvalidFodselsnummerChecksum() - { - try - { - FodselsnummerValidator.validateChecksums("01010101010"); - Assert.True(false); - } - catch (ArgumentException e) - { - AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_CHECKSUM); - } + [Fact] + public void testInvalidDateMonthMin() + { + try + { + FodselsnummerValidator.validateDate("01000400000"); + Assert.True(false); + } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); } + } - [Fact] - public void testValidLeapDay() + [Fact] + public void testInvalidDateDayMin() + { + try { - Assert.True(FodselsnummerValidator.IsValid("29029633310")); + FodselsnummerValidator.validateDate("00120467800"); + Assert.True(false); } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); + } + } - [Fact] - public void testIsValid() + [Fact] + public void testInvalidDateDayMax() + { + try { - Assert.True(FodselsnummerValidator.IsValid("01010101006")); + FodselsnummerValidator.validateDate("32120400000"); + Assert.True(false); } + catch (ArgumentException e) + { + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); + } + } - [Fact] - public void testDNumberIsValid() + [Fact] + public void testInvalidDateLeapDay() + { + try + { + FodselsnummerValidator.validateDate("29020700000"); + Assert.True(false); + } + catch (ArgumentException e) { - Assert.True(FodselsnummerValidator.IsValid("47086303651")); + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_DATE); } + } - [Fact] - public void testGetDNumber() + [Fact] + public void testInvalidFodselsnummerChecksum() + { + try + { + FodselsnummerValidator.validateChecksums("01010101010"); + Assert.True(false); + } + catch (ArgumentException e) { - FodselsnummerValidator.getFodselsnummer("47086303651"); + AssertionUtils.AssertMessageContains(e, FodselsnummerValidator.ERROR_INVALID_CHECKSUM); } } + + [Fact] + public void testValidLeapDay() + { + Assert.True(FodselsnummerValidator.IsValid("29029633310")); + } + + [Fact] + public void testIsValid() + { + Assert.True(FodselsnummerValidator.IsValid("01010101006")); + } + + [Fact] + public void testDNumberIsValid() + { + Assert.True(FodselsnummerValidator.IsValid("47086303651")); + } + + [Fact] + public void testGetDNumber() + { + FodselsnummerValidator.getFodselsnummer("47086303651"); + } } diff --git a/source/NoCommons.Tests/packages.config b/source/NoCommons.Tests/packages.config index 92944f3..5f25f32 100644 --- a/source/NoCommons.Tests/packages.config +++ b/source/NoCommons.Tests/packages.config @@ -1,9 +1,9 @@  - - - - - - - \ No newline at end of file + + + + + + + diff --git a/source/NoCommons/Banking/IbanValidator.cs b/source/NoCommons/Banking/IbanValidator.cs index 233531a..b5685fe 100644 --- a/source/NoCommons/Banking/IbanValidator.cs +++ b/source/NoCommons/Banking/IbanValidator.cs @@ -1,66 +1,68 @@ -using System; -using System.Globalization; -using System.Text; +using System.Text; +using System.Text.RegularExpressions; -namespace NoCommons.Banking +namespace NoCommons.Banking; + +public static class IbanValidator { - public class IbanValidator + public static bool IsValid(string ibanValue) { - public static bool IsValid(string ibanValue) + try { - try - { - return Validate(ibanValue); - } - catch (Exception) - { - return false; - } + return Validate(ibanValue); } - - static bool Validate(string ibanValue) + catch (Exception) { - if (System.Text.RegularExpressions.Regex.IsMatch(ibanValue, "^[A-Z0-9]")) - { - string ibanLeftShiftedBy4 = ibanValue.Substring(4, ibanValue.Length - 4) + ibanValue.Substring(0, 4); - var checkSumString = CheckSumString(ibanLeftShiftedBy4); - int checksum = int.Parse(checkSumString.Substring(0, 1)); - return HasCorrectChecksum(checksum, checkSumString); - } return false; } + } - private static bool HasCorrectChecksum(int checksum, string checkSumString) + private static bool Validate(string ibanValue) + { + if (Regex.IsMatch(ibanValue, "^[A-Z0-9]")) { - for (int i = 1; i < checkSumString.Length; i++) - { - int v = int.Parse(checkSumString.Substring(i, 1)); - checksum *= 10; - checksum += v; - checksum %= 97; - } - return checksum == 1; + string ibanLeftShiftedBy4 = ibanValue.Substring(4, ibanValue.Length - 4) + ibanValue.Substring(0, 4); + string checkSumString = CheckSumString(ibanLeftShiftedBy4); + int checksum = int.Parse(checkSumString.Substring(0, 1)); + return HasCorrectChecksum(checksum, checkSumString); } - private static string CheckSumString(string ibanLeftShiftedBy4) + return false; + } + + private static bool HasCorrectChecksum(int checksum, string checkSumString) + { + for (int i = 1; i < checkSumString.Length; i++) + { + int v = int.Parse(checkSumString.Substring(i, 1)); + checksum *= 10; + checksum += v; + checksum %= 97; + } + + return checksum == 1; + } + + private static string CheckSumString(string ibanLeftShiftedBy4) + { + const int asciiShift = 55; + StringBuilder sb = new(); + foreach (char c in ibanLeftShiftedBy4) { - const int asciiShift = 55; - var sb = new StringBuilder(); - foreach (char c in ibanLeftShiftedBy4) + int v; + if (char.IsLetter(c)) + { + v = c - asciiShift; + } + else { - int v; - if (Char.IsLetter(c)) - { - v = c - asciiShift; - } - else - { - v = int.Parse(c.ToString()); - } - sb.Append(v); + v = int.Parse(c.ToString()); } - string checkSumString = sb.ToString(); - return checkSumString; + + sb.Append(v); } + + string checkSumString = sb.ToString(); + return checkSumString; } } diff --git a/source/NoCommons/Banking/Kidnummer.cs b/source/NoCommons/Banking/Kidnummer.cs index 05acd0e..d6afb06 100644 --- a/source/NoCommons/Banking/Kidnummer.cs +++ b/source/NoCommons/Banking/Kidnummer.cs @@ -1,17 +1,10 @@ using NoCommons.Common; -namespace NoCommons.Banking -{ - /** - * This class represent a Norwegian KID-nummer - a number used to identify - * a customer on invoices. A Kidnummer consists of digits only, and the last - * digit is a checksum digit (either mod10 or mod11). - */ - public class Kidnummer : StringNumber { +namespace NoCommons.Banking; - public Kidnummer(string kontonummer) : base(kontonummer) - { - - } - } -} \ No newline at end of file +/** + * This class represent a Norwegian KID-nummer - a number used to identify + * a customer on invoices. A Kidnummer consists of digits only, and the last + * digit is a checksum digit (either mod10 or mod11). + */ +public record Kidnummer(string value) : StringNumber(value); diff --git a/source/NoCommons/Banking/KidnummerValidator.cs b/source/NoCommons/Banking/KidnummerValidator.cs index 0646ea9..f2182c0 100644 --- a/source/NoCommons/Banking/KidnummerValidator.cs +++ b/source/NoCommons/Banking/KidnummerValidator.cs @@ -1,67 +1,74 @@ -using System; using NoCommons.Common; -namespace NoCommons.Banking +namespace NoCommons.Banking; + +/** + * This class represent a Norwegian KID-nummer - a number used to identify + * a customer on invoices. A Kidnummer consists of digits only, and the last + * digit is a checksum digit (either mod10 or mod11). + */ +public class KidnummerValidator : StringNumberValidator { + public const string ERROR_LENGTH = "A Kidnummer is between 2 and 25 digits"; + /** - * This class represent a Norwegian KID-nummer - a number used to identify - * a customer on invoices. A Kidnummer consists of digits only, and the last - * digit is a checksum digit (either mod10 or mod11). + * Return true if the provided string is a valid KID-nummmer. + * + * @param kidnummer + * A string containing a Kidnummer + * @return true or false */ - public class KidnummerValidator : StringNumberValidator { - - public const string ERROR_LENGTH = "A Kidnummer is between 2 and 25 digits"; - - /** - * Return true if the provided string is a valid KID-nummmer. - * - * @param kidnummer - * A string containing a Kidnummer - * @return true or false - */ - public static bool IsValid(string kidnummer) { - try { - GetKidnummer(kidnummer); - return true; - } catch (ArgumentException) { - return false; - } + public static bool IsValid(string kidnummer) + { + try + { + GetKidnummer(kidnummer); + return true; } - - /** - * Returns an object that represents a Kidnummer. - * - * @param kidnummer - * A string containing a Kidnummer - * @return A Kidnummer instance - * @throws IllegalArgumentException - * thrown if string contains an invalid Kidnummer - */ - public static Kidnummer GetKidnummer(string kidnummer) { - ValidateSyntax(kidnummer); - ValidateChecksum(kidnummer); - return new Kidnummer(kidnummer); + catch (ArgumentException) + { + return false; } + } - internal static void ValidateSyntax(string kidnummer) { - ValidateAllDigits(kidnummer); - ValidateLengthInRange(kidnummer, 2, 25); - } + /** + * Returns an object that represents a Kidnummer. + * + * @param kidnummer + * A string containing a Kidnummer + * @return A Kidnummer instance + * @throws IllegalArgumentException + * thrown if string contains an invalid Kidnummer + */ + public static Kidnummer GetKidnummer(string kidnummer) + { + ValidateSyntax(kidnummer); + ValidateChecksum(kidnummer); + return new Kidnummer(kidnummer); + } - private static void ValidateLengthInRange(string kidnummer, int i, int j) { - if (kidnummer == null || kidnummer.Length < i || kidnummer.Length > j) { - throw new ArgumentException(ERROR_LENGTH); - } - } + internal static void ValidateSyntax(string kidnummer) + { + ValidateAllDigits(kidnummer); + ValidateLengthInRange(kidnummer, 2, 25); + } - internal static void ValidateChecksum(string kidnummer) { - StringNumber k = new Kidnummer(kidnummer); - int kMod10 = CalculateMod10CheckSum(GetMod10Weights(k), k); - int kMod11 = CalculateMod11CheckSum(GetMod11Weights(k), k); - if (kMod10 != k.GetChecksumDigit() && kMod11 != k.GetChecksumDigit()) { - throw new ArgumentException(ERROR_INVALID_CHECKSUM + kidnummer); - } + private static void ValidateLengthInRange(string kidnummer, int i, int j) + { + if (kidnummer == null || kidnummer.Length < i || kidnummer.Length > j) + { + throw new ArgumentException(ERROR_LENGTH); } + } + internal static void ValidateChecksum(string kidnummer) + { + StringNumber k = new Kidnummer(kidnummer); + int kMod10 = CalculateMod10CheckSum(GetMod10Weights(k), k); + int kMod11 = CalculateMod11CheckSum(GetMod11Weights(k), k); + if (kMod10 != k.GetChecksumDigit() && kMod11 != k.GetChecksumDigit()) + { + throw new ArgumentException(ERROR_INVALID_CHECKSUM + kidnummer); + } } -} \ No newline at end of file +} diff --git a/source/NoCommons/Banking/Kontonummer.cs b/source/NoCommons/Banking/Kontonummer.cs index 9355ae8..6d0d63c 100644 --- a/source/NoCommons/Banking/Kontonummer.cs +++ b/source/NoCommons/Banking/Kontonummer.cs @@ -1,39 +1,41 @@ using System.Text; using NoCommons.Common; -namespace NoCommons.Banking -{ - public class Kontonummer : StringNumber { - - public Kontonummer(string kontonummer) : base(kontonummer) { - - } - - public string GetRegisternummer() { - return GetValue().Substring(0, 4); - } +namespace NoCommons.Banking; - public string GetAccountType() { - return GetValue().Substring(4, 2); - } +public record Kontonummer(string value) : StringNumber(value) +{ + public string GetRegisternummer() + { + return GetValue().Substring(0, 4); + } - public string GetKonto() { - return GetValue().Substring(4, 6); - } + public string GetAccountType() + { + return GetValue().Substring(4, 2); + } - public string GetGroupedValue() { - var sb = new StringBuilder(); - sb.Append(GetRegisternummer()).Append(Constants.DOT); - sb.Append(GetAccountType()).Append(Constants.DOT); - sb.Append(GetPartAfterAccountType()); - return sb.ToString(); - } + public string GetKonto() + { + return GetValue().Substring(4, 6); + } - private string GetPartAfterAccountType() { - return GetValue().Substring(6); - } + public string GetGroupedValue() + { + StringBuilder sb = new(); + sb.Append(GetRegisternummer()).Append(Constants.DOT); + sb.Append(GetAccountType()).Append(Constants.DOT); + sb.Append(GetPartAfterAccountType()); + return sb.ToString(); + } + private string GetPartAfterAccountType() + { + return GetValue().Substring(6); } - -} \ No newline at end of file + public override string ToString() + { + return GetValue(); + } +} diff --git a/source/NoCommons/Banking/KontonummerCalculator.cs b/source/NoCommons/Banking/KontonummerCalculator.cs index 0037a66..83abf2a 100644 --- a/source/NoCommons/Banking/KontonummerCalculator.cs +++ b/source/NoCommons/Banking/KontonummerCalculator.cs @@ -1,175 +1,176 @@ -using System; -using System.Collections.Generic; -using System.Text; +using System.Text; -namespace NoCommons.Banking +namespace NoCommons.Banking; + +/** + * This class calculates valid Kontonummer instances. + */ +public class KontonummerCalculator { - /** - * This class calculates valid Kontonummer instances. - */ - public class KontonummerCalculator + private static List GetKontonummerListUsingGenerator(KontonummerDigitGenerator generator, int length) { - private static List GetKontonummerListUsingGenerator(KontonummerDigitGenerator generator, int length) + List result = new(); + int numAddedToList = 0; + while (numAddedToList < length) { - var result = new List(); - int numAddedToList = 0; - while (numAddedToList < length) + Kontonummer kontoNr; + try { - Kontonummer kontoNr; - try - { - kontoNr = KontonummerValidator.GetAndForceValidKontonummer(generator.GenerateKontonummer()); - } - catch (ArgumentException) - { - // this number has no valid checksum - continue; - } - result.Add(kontoNr); - numAddedToList++; + kontoNr = KontonummerValidator.GetAndForceValidKontonummer(generator.GenerateKontonummer()); + } + catch (ArgumentException) + { + // this number has no valid checksum + continue; } - return result; - } - - /** - * Returns a List with random but syntactically valid Kontonummer instances - * for a given AccountType. - * - * @param accountType - * A string representing the AccountType to use for all - * Kontonummer instances - * @param length - * Specifies the number of Kontonummer instances to create in the - * returned List - * @return A List with Kontonummer instances - */ - public static List GetKontonummerListForAccountType(string accountType, int length) - { - KontonummerValidator.ValidateAccountTypeSyntax(accountType); - return GetKontonummerListUsingGenerator(new AccountTypeKontonrDigitGenerator(accountType), length); + result.Add(kontoNr); + numAddedToList++; } - /** - * Returns a List with random but syntactically valid Kontonummer instances - * for a given Registernummer. - * - * @param registernummer - * A string representing the Registernummer to use for all - * Kontonummer instances - * @param length - * Specifies the number of Kontonummer instances to create in the - * returned List - * @return A List with Kontonummer instances - */ - public static List GetKontonummerListForRegisternummer(string registernummer, int length) - { - KontonummerValidator.ValidateRegisternummerSyntax(registernummer); + return result; + } - return GetKontonummerListUsingGenerator(new RegisternummerKontonrDigitGenerator(registernummer), length); - } + /** + * Returns a List with random but syntactically valid Kontonummer instances + * for a given AccountType. + * + * @param accountType + * A string representing the AccountType to use for all + * Kontonummer instances + * @param length + * Specifies the number of Kontonummer instances to create in the + * returned List + * @return A List with Kontonummer instances + */ + public static List GetKontonummerListForAccountType(string accountType, int length) + { + KontonummerValidator.ValidateAccountTypeSyntax(accountType); - /** - * Returns a List with completely random but syntactically valid Kontonummer - * instances. - * - * @param length - * Specifies the number of Kontonummer instances to create in the - * returned List - * - * @return A List with random valid Kontonummer instances - */ - public static List GetKontonummerList(int length) - { - return GetKontonummerListUsingGenerator(new NormalKontonrDigitGenerator(), length); - } + return GetKontonummerListUsingGenerator(new AccountTypeKontonrDigitGenerator(accountType), length); } - internal abstract class KontonummerDigitGenerator + /** + * Returns a List with random but syntactically valid Kontonummer instances + * for a given Registernummer. + * + * @param registernummer + * A string representing the Registernummer to use for all + * Kontonummer instances + * @param length + * Specifies the number of Kontonummer instances to create in the + * returned List + * @return A List with Kontonummer instances + */ + public static List GetKontonummerListForRegisternummer(string registernummer, int length) { - protected const int REGISTERNUMMER_START_DIGIT = 0; - protected const int LENGTH = 11; - internal abstract string GenerateKontonummer(); + KontonummerValidator.ValidateRegisternummerSyntax(registernummer); + + return GetKontonummerListUsingGenerator(new RegisternummerKontonrDigitGenerator(registernummer), length); } - internal class AccountTypeKontonrDigitGenerator : KontonummerDigitGenerator + /** + * Returns a List with completely random but syntactically valid Kontonummer + * instances. + * + * @param length + * Specifies the number of Kontonummer instances to create in the + * returned List + * + * @return A List with random valid Kontonummer instances + */ + public static List GetKontonummerList(int length) { - private const int ACCOUNTTYPE_START_DIGIT = 4; + return GetKontonummerListUsingGenerator(new NormalKontonrDigitGenerator(), length); + } +} - private readonly string _accountType; +internal abstract class KontonummerDigitGenerator +{ + protected const int REGISTERNUMMER_START_DIGIT = 0; + protected const int LENGTH = 11; + internal abstract string GenerateKontonummer(); +} - internal AccountTypeKontonrDigitGenerator(string accountType) - { - _accountType = accountType; - } +internal class AccountTypeKontonrDigitGenerator : KontonummerDigitGenerator +{ + private const int ACCOUNTTYPE_START_DIGIT = 4; - internal override string GenerateKontonummer() + private readonly string _accountType; + + internal AccountTypeKontonrDigitGenerator(string accountType) + { + _accountType = accountType; + } + + internal override string GenerateKontonummer() + { + StringBuilder kontonrBuffer = new(LENGTH); + for (int i = 0; i < LENGTH;) { - var kontonrBuffer = new StringBuilder(LENGTH); - for (var i = 0; i < LENGTH; ) + if (i == ACCOUNTTYPE_START_DIGIT) { - if (i == ACCOUNTTYPE_START_DIGIT) - { - kontonrBuffer.Append(_accountType); - i += _accountType.Length; - } - else - { - var randomNum = new Random(); - var ran = randomNum.Next(0, 10); - kontonrBuffer.Append(ran); - i++; - } + kontonrBuffer.Append(_accountType); + i += _accountType.Length; + } + else + { + Random randomNum = new(); + int ran = randomNum.Next(0, 10); + kontonrBuffer.Append(ran); + i++; } - return kontonrBuffer.ToString(); } + + return kontonrBuffer.ToString(); } +} - internal class RegisternummerKontonrDigitGenerator : KontonummerDigitGenerator - { - private readonly string _registerNr; +internal class RegisternummerKontonrDigitGenerator : KontonummerDigitGenerator +{ + private readonly string _registerNr; - internal RegisternummerKontonrDigitGenerator(string registerNr) - { - _registerNr = registerNr; - } + internal RegisternummerKontonrDigitGenerator(string registerNr) + { + _registerNr = registerNr; + } - internal override string GenerateKontonummer() + internal override string GenerateKontonummer() + { + StringBuilder kontonrBuffer = new(LENGTH); + for (int i = 0; i < LENGTH;) { - var kontonrBuffer = new StringBuilder(LENGTH); - for (int i = 0; i < LENGTH; ) + if (i == REGISTERNUMMER_START_DIGIT) { - if (i == REGISTERNUMMER_START_DIGIT) - { - kontonrBuffer.Append(_registerNr); - i += _registerNr.Length; - } - else - { - var rand = new Random(); - var ran = rand.Next(0, 10); - kontonrBuffer.Append(ran); - i++; - } + kontonrBuffer.Append(_registerNr); + i += _registerNr.Length; + } + else + { + Random rand = new(); + int ran = rand.Next(0, 10); + kontonrBuffer.Append(ran); + i++; } - return kontonrBuffer.ToString(); } + + return kontonrBuffer.ToString(); } +} - internal class NormalKontonrDigitGenerator : KontonummerDigitGenerator +internal class NormalKontonrDigitGenerator : KontonummerDigitGenerator +{ + internal override string GenerateKontonummer() { - internal override string GenerateKontonummer() + StringBuilder kontonrBuffer = new(LENGTH); + for (int i = 0; i < LENGTH; i++) { - var kontonrBuffer = new StringBuilder(LENGTH); - for (int i = 0; i < LENGTH; i++) - { - var random = new Random(); - var ran = random.Next(0, 10); - kontonrBuffer.Append(ran); - } - return kontonrBuffer.ToString(); + Random random = new(); + int ran = random.Next(0, 10); + kontonrBuffer.Append(ran); } - } -} \ No newline at end of file + return kontonrBuffer.ToString(); + } +} diff --git a/source/NoCommons/Banking/KontonummerValidator.cs b/source/NoCommons/Banking/KontonummerValidator.cs index a290ce9..a7bc5f8 100644 --- a/source/NoCommons/Banking/KontonummerValidator.cs +++ b/source/NoCommons/Banking/KontonummerValidator.cs @@ -1,63 +1,72 @@ -using System; -using NoCommons.Common; +using NoCommons.Common; -namespace NoCommons.Banking +namespace NoCommons.Banking; + +public class KontonummerValidator : StringNumberValidator { - public class KontonummerValidator : StringNumberValidator { - - private const int LENGTH = 11; - public static int ACCOUNTTYPE_NUM_DIGITS = 2; - public static int REGISTERNUMMER_NUM_DIGITS = 4; - - public static bool IsValid(string kontonummer) { - try { - GetKontonummer(kontonummer); - return true; - } catch (ArgumentException) { - return false; - } - } - - public static Kontonummer GetKontonummer(string kontonummer){ - ValidateSyntax(kontonummer); - ValidateChecksum(kontonummer); - return new Kontonummer(kontonummer); - } - - public static Kontonummer GetAndForceValidKontonummer(string kontonummer) { - ValidateSyntax(kontonummer); - try { - ValidateChecksum(kontonummer); - } catch (ArgumentException) { - var k = new Kontonummer(kontonummer); - int checksum = CalculateMod11CheckSum(GetMod11Weights(k), k); - kontonummer = kontonummer.Substring(0, LENGTH - 1) + checksum; - } - return new Kontonummer(kontonummer); - } - - internal static void ValidateSyntax(string kontonummer) { - ValidateLengthAndAllDigits(kontonummer, LENGTH); - } - - internal static void ValidateAccountTypeSyntax(string accountType) { - ValidateLengthAndAllDigits(accountType, ACCOUNTTYPE_NUM_DIGITS); - } - - internal static void ValidateRegisternummerSyntax(string registernummer) { - ValidateLengthAndAllDigits(registernummer, REGISTERNUMMER_NUM_DIGITS); - } - - internal static void ValidateChecksum(string kontonummer) { - var k = new Kontonummer(kontonummer); - int k1 = CalculateMod11CheckSum(GetMod11Weights(k), k); - if (k1 != k.GetChecksumDigit()) { - throw new ArgumentException(ERROR_INVALID_CHECKSUM + kontonummer); - } - } + private const int LENGTH = 11; + public static int ACCOUNTTYPE_NUM_DIGITS = 2; + public static int REGISTERNUMMER_NUM_DIGITS = 4; + + public static bool IsValid(string kontonummer) + { + try + { + GetKontonummer(kontonummer); + return true; + } + catch (ArgumentException) + { + return false; + } + } + public static Kontonummer GetKontonummer(string kontonummer) + { + ValidateSyntax(kontonummer); + ValidateChecksum(kontonummer); + return new Kontonummer(kontonummer); } + public static Kontonummer GetAndForceValidKontonummer(string kontonummer) + { + ValidateSyntax(kontonummer); + try + { + ValidateChecksum(kontonummer); + } + catch (ArgumentException) + { + Kontonummer? k = new(kontonummer); + int checksum = CalculateMod11CheckSum(GetMod11Weights(k), k); + kontonummer = kontonummer.Substring(0, LENGTH - 1) + checksum; + } + return new Kontonummer(kontonummer); + } + + internal static void ValidateSyntax(string kontonummer) + { + ValidateLengthAndAllDigits(kontonummer, LENGTH); + } + internal static void ValidateAccountTypeSyntax(string accountType) + { + ValidateLengthAndAllDigits(accountType, ACCOUNTTYPE_NUM_DIGITS); + } + + internal static void ValidateRegisternummerSyntax(string registernummer) + { + ValidateLengthAndAllDigits(registernummer, REGISTERNUMMER_NUM_DIGITS); + } + + internal static void ValidateChecksum(string kontonummer) + { + Kontonummer? k = new(kontonummer); + int k1 = CalculateMod11CheckSum(GetMod11Weights(k), k); + if (k1 != k.GetChecksumDigit()) + { + throw new ArgumentException(ERROR_INVALID_CHECKSUM + kontonummer); + } + } } diff --git a/source/NoCommons/Common/Constants.cs b/source/NoCommons/Common/Constants.cs index 48f80f6..ed0d235 100644 --- a/source/NoCommons/Common/Constants.cs +++ b/source/NoCommons/Common/Constants.cs @@ -1,7 +1,6 @@ -namespace NoCommons.Common +namespace NoCommons.Common; + +public static class Constants { - public static class Constants - { - public static char DOT = '.'; - } -} \ No newline at end of file + public static char DOT = '.'; +} diff --git a/source/NoCommons/Common/StringNumber.cs b/source/NoCommons/Common/StringNumber.cs index eb10652..5ffeeb1 100644 --- a/source/NoCommons/Common/StringNumber.cs +++ b/source/NoCommons/Common/StringNumber.cs @@ -1,63 +1,29 @@ -using System; +namespace NoCommons.Common; -namespace NoCommons.Common +public abstract record StringNumber(string value) { - public abstract class StringNumber { - - private readonly string value; - - protected StringNumber(string value) { - this.value = value; - } - - public string GetValue() { - return value; - } - - public int GetAt(int i) { - return GetValue()[i] - '0'; - } - - public override string ToString() { - return GetValue(); - } - - public override int GetHashCode() { - const int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.GetHashCode()); - return result; - } + public string GetValue() + { + return value; + } - public override bool Equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (GetType() != obj.GetType()) { - return false; - } - var other = (StringNumber) obj; - if (value == null) { - if (other.value != null) { - return false; - } - } else if (!value.Equals(other.value)) { - return false; - } - return true; - } + public int GetAt(int i) + { + return GetValue()[i] - '0'; + } - public int GetLength() { - return GetValue().Length; - } + public override string ToString() + { + return GetValue(); + } - public int GetChecksumDigit() { - return GetAt(GetLength()-1); - } + public int GetLength() + { + return GetValue().Length; + } - + public int GetChecksumDigit() + { + return GetAt(GetLength() - 1); } -} \ No newline at end of file +} diff --git a/source/NoCommons/Common/StringNumberValidator.cs b/source/NoCommons/Common/StringNumberValidator.cs index d5a21c1..2f9cd5f 100644 --- a/source/NoCommons/Common/StringNumberValidator.cs +++ b/source/NoCommons/Common/StringNumberValidator.cs @@ -1,79 +1,100 @@ -using System; -using System.Linq; +namespace NoCommons.Common; -namespace NoCommons.Common +public abstract class StringNumberValidator { - public abstract class StringNumberValidator { - - public static string ERROR_INVALID_CHECKSUM = "Invalid checksum : "; - - public static string ERROR_SYNTAX = "Only digits are allowed : "; - - private static readonly int[] BASE_MOD11_WEIGHTS = new []{2, 3, 4, 5, 6, 7}; - - protected static int CalculateMod11CheckSum(int[] weights, StringNumber number) { - int c = CalculateChecksum(weights, number, false) % 11; - if (c == 1) { - throw new ArgumentException(ERROR_INVALID_CHECKSUM + number); - } - return c == 0 ? 0 : 11 - c; - } - - protected static int CalculateMod10CheckSum(int[] weights, StringNumber number) { - int c = CalculateChecksum(weights, number, true) % 10; - return c == 0 ? 0 : 10 - c; - } - - private static int CalculateChecksum(int[] weights, StringNumber number, bool tverrsum) { - int checkSum = 0; - for (int i = 0; i < weights.Length; i++) { - int product = weights[i] * number.GetAt(weights.Length - 1 - i); - if (tverrsum) { - checkSum += (product > 9 ? product - 9 : product); - } else { + public const string ERROR_INVALID_CHECKSUM = "Invalid checksum : "; + + public const string ERROR_SYNTAX = "Only digits are allowed : "; + + private static readonly int[] BASE_MOD11_WEIGHTS = [2, 3, 4, 5, 6, 7]; + + protected static int CalculateMod11CheckSum(int[] weights, StringNumber number) + { + int c = CalculateChecksum(weights, number, false) % 11; + if (c == 1) + { + throw new ArgumentException(ERROR_INVALID_CHECKSUM + number); + } + + return c == 0 ? 0 : 11 - c; + } + + protected static int CalculateMod10CheckSum(int[] weights, StringNumber number) + { + int c = CalculateChecksum(weights, number, true) % 10; + return c == 0 ? 0 : 10 - c; + } + + private static int CalculateChecksum(int[] weights, StringNumber number, bool tverrsum) + { + int checkSum = 0; + for (int i = 0; i < weights.Length; i++) + { + int product = weights[i] * number.GetAt(weights.Length - 1 - i); + if (tverrsum) + { + checkSum += product > 9 ? product - 9 : product; + } + else + { checkSum += product; - } - } - return checkSum; - } - - protected static void ValidateLengthAndAllDigits(string numberString, - int length) { - if (numberString == null || numberString.Length != length) { - throw new ArgumentException(ERROR_SYNTAX + numberString); - } - ValidateAllDigits(numberString); - } - - protected static void ValidateAllDigits(string numberString) { - if (numberString == null || numberString.Length <= 0) { - throw new ArgumentException(ERROR_SYNTAX + numberString); - } - if (numberString.Any(t => !char.IsDigit((t)))) { - throw new ArgumentException(ERROR_SYNTAX + numberString); - } - } - - protected static int[] GetMod10Weights(StringNumber k) { - var weights = new int[k.GetLength() - 1]; - for (int i = 0; i < weights.Length; i++) { - if ((i % 2) == 0) { + } + } + + return checkSum; + } + + protected static void ValidateLengthAndAllDigits(string numberString, + int length) + { + if (numberString == null || numberString.Length != length) + { + throw new ArgumentException(ERROR_SYNTAX + numberString); + } + + ValidateAllDigits(numberString); + } + + protected static void ValidateAllDigits(string numberString) + { + if (numberString == null || numberString.Length <= 0) + { + throw new ArgumentException(ERROR_SYNTAX + numberString); + } + + if (numberString.Any(t => !char.IsDigit(t))) + { + throw new ArgumentException(ERROR_SYNTAX + numberString); + } + } + + protected static int[] GetMod10Weights(StringNumber k) + { + int[] weights = new int[k.GetLength() - 1]; + for (int i = 0; i < weights.Length; i++) + { + if (i % 2 == 0) + { weights[i] = 2; - } else { + } + else + { weights[i] = 1; - } - } - return weights; - } - - protected static int[] GetMod11Weights(StringNumber k) { - var weights = new int[k.GetLength() - 1]; - for (int i = 0; i < weights.Length; i++) { - int j = i % BASE_MOD11_WEIGHTS.Length; - weights[i] = BASE_MOD11_WEIGHTS[j]; - } - return weights; - } + } + } + + return weights; + } + + protected static int[] GetMod11Weights(StringNumber k) + { + int[] weights = new int[k.GetLength() - 1]; + for (int i = 0; i < weights.Length; i++) + { + int j = i % BASE_MOD11_WEIGHTS.Length; + weights[i] = BASE_MOD11_WEIGHTS[j]; + } + return weights; } } diff --git a/source/NoCommons/Date/NorwegianDateUtil.cs b/source/NoCommons/Date/NorwegianDateUtil.cs index 272e27a..e089ba2 100644 --- a/source/NoCommons/Date/NorwegianDateUtil.cs +++ b/source/NoCommons/Date/NorwegianDateUtil.cs @@ -1,179 +1,173 @@ -using System; -using System.Collections.Generic; +namespace NoCommons.Date; -namespace NoCommons.Date +public class NorwegianDateUtil { - public class NorwegianDateUtil + private static readonly object Lock = new(); + private static Dictionary>? holidays; + + /// + /// Adds the given number of working days to the given date. A working day is + /// specified as a regular Norwegian working day, excluding weekends and all + /// national holidays. + /// Example 1: + /// - Add 5 working days to Wednesday 21.03.2007 -> Yields Wednesday + /// 28.03.2007. (skipping saturday and sunday) + /// Example 2: + /// - Add 5 working days to Wednesday 04.04.2007 (day before + /// easter-long-weekend) -> yields Monday 16.04.2007 (skipping 2 weekends and + /// 3 weekday holidays). + /// + /// The original date + /// The number of working days to add + /// The new date + public static DateTime AddWorkingDaysToDate(DateTime date, int days) { - private static readonly object Lock = new object(); - private static Dictionary> holidays; - - /// - /// Adds the given number of working days to the given date. A working day is - /// specified as a regular Norwegian working day, excluding weekends and all - /// national holidays. - /// - /// Example 1: - /// - Add 5 working days to Wednesday 21.03.2007 -> Yields Wednesday - /// 28.03.2007. (skipping saturday and sunday) - /// - /// Example 2: - /// - Add 5 working days to Wednesday 04.04.2007 (day before - /// easter-long-weekend) -> yields Monday 16.04.2007 (skipping 2 weekends and - /// 3 weekday holidays). - /// - /// The original date - /// The number of working days to add - /// The new date - public static DateTime AddWorkingDaysToDate(DateTime date, int days) + DateTime localDate = date; + for (int i = 0; i < days; i++) { - - var localDate = date; - for (var i = 0; i < days; i++) + localDate = localDate.AddDays(1); + while (!IsWorkingDay(localDate)) { localDate = localDate.AddDays(1); - while (!IsWorkingDay(localDate)) - { - localDate = localDate.AddDays(1); - } } - - return localDate; } - /// - /// Will check if the given date is a working day. That is check if the given - /// date is a weekend day or a national holiday. - /// - /// The date to check - /// true if the given date is a working day, false otherwise - public static bool IsWorkingDay(DateTime date) - { - return date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday - && !IsHoliday(date); - } + return localDate; + } + + /// + /// Will check if the given date is a working day. That is check if the given + /// date is a weekend day or a national holiday. + /// + /// The date to check + /// true if the given date is a working day, false otherwise + public static bool IsWorkingDay(DateTime date) + { + return date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday + && !IsHoliday(date); + } - /// - /// Check if given Date object is a holiday. - /// - /// date to check if is a holiday - /// true if holiday, false otherwise - public static bool IsHoliday(DateTime date) + /// + /// Check if given Date object is a holiday. + /// + /// date to check if is a holiday + /// true if holiday, false otherwise + public static bool IsHoliday(DateTime date) + { + int year = date.Year; + IEnumerable? holidaysForYear = GetHolidaySet(year); + foreach (DateTime holiday in holidaysForYear) { - var year = date.Year; - var holidaysForYear = GetHolidaySet(year); - foreach (var holiday in holidaysForYear) - { - if (CheckDate(date, holiday)) - { - return true; - } + if (CheckDate(date, holiday)) + { + return true; } - return false; } - /// - /// Return a sorted array of holidays for a given year. - /// - /// The year to get holidays for - /// Holidays, sorted by date - public static IEnumerable GetHolidays(int year) - { - var days = GetHolidaySet(year); - var listOfHolidays = new List(days); - listOfHolidays.Sort((date1, date2) => date1.CompareTo(date2)); - return listOfHolidays; - } - - /// - /// Get a set of holidays for a given year - /// - /// The year to get holidays for - /// Holidays for year - private static IEnumerable GetHolidaySet(int year) + return false; + } + + /// + /// Return a sorted array of holidays for a given year. + /// + /// The year to get holidays for + /// Holidays, sorted by date + public static IEnumerable GetHolidays(int year) + { + IEnumerable days = GetHolidaySet(year); + List listOfHolidays = new(days); + listOfHolidays.Sort((date1, date2) => date1.CompareTo(date2)); + return listOfHolidays; + } + + /// + /// Get a set of holidays for a given year + /// + /// The year to get holidays for + /// Holidays for year + private static IEnumerable GetHolidaySet(int year) + { + lock (Lock) { - lock (Lock) + if (holidays == null) + { + holidays = new Dictionary>(); + } + + if (!holidays.ContainsKey(year)) { - if (holidays == null) - { - holidays = new Dictionary>(); - } - if (!holidays.ContainsKey(year)) - { - var yearSet = new HashSet(); + HashSet yearSet = new(); - // Add set holidays. - yearSet.Add(new DateTime(year, 1, 1)); - yearSet.Add(new DateTime(year, 5, 1)); - yearSet.Add(new DateTime(year, 5, 17)); - yearSet.Add(new DateTime(year, 12, 25)); - yearSet.Add(new DateTime(year, 12, 26)); + // Add set holidays. + yearSet.Add(new DateTime(year, 1, 1)); + yearSet.Add(new DateTime(year, 5, 1)); + yearSet.Add(new DateTime(year, 5, 17)); + yearSet.Add(new DateTime(year, 12, 25)); + yearSet.Add(new DateTime(year, 12, 26)); - // Add movable holidays - based on easter day. - var easterDay = GetEasterDay(year); + // Add movable holidays - based on easter day. + DateTime easterDay = GetEasterDay(year); - // Sunday before easter. - yearSet.Add(easterDay.AddDays(-7)); + // Sunday before easter. + yearSet.Add(easterDay.AddDays(-7)); - // Thurday before easter. - yearSet.Add(easterDay.AddDays(-3)); + // Thurday before easter. + yearSet.Add(easterDay.AddDays(-3)); - // Friday before easter. - yearSet.Add(easterDay.AddDays(-2)); + // Friday before easter. + yearSet.Add(easterDay.AddDays(-2)); - // Easter day. - yearSet.Add(easterDay); + // Easter day. + yearSet.Add(easterDay); - // Second easter day. - yearSet.Add(easterDay.AddDays(1)); + // Second easter day. + yearSet.Add(easterDay.AddDays(1)); - // "Kristi himmelfart" day. - yearSet.Add(easterDay.AddDays(39)); + // "Kristi himmelfart" day. + yearSet.Add(easterDay.AddDays(39)); - // "Pinse" day. - yearSet.Add(easterDay.AddDays(49)); + // "Pinse" day. + yearSet.Add(easterDay.AddDays(49)); - // Second "Pinse" day. - yearSet.Add(easterDay.AddDays(50)); + // Second "Pinse" day. + yearSet.Add(easterDay.AddDays(50)); - holidays.Add(year, yearSet); - } + holidays.Add(year, yearSet); } - return holidays[year]; } - - - - /// - /// Calculates easter day (sunday) by using Spencer Jones formula found here: - /// http://no.wikipedia.org/wiki/P%C3%A5skeformelen - /// - /// year - /// easterday for year - private static DateTime GetEasterDay(int year) - { - int a = year%19; - int b = year/100; - int c = year%100; - int d = b/4; - int e = b%4; - int f = (b + 8)/25; - int g = (b - f + 1)/3; - int h = ((19*a) + b - d - g + 15)%30; - int i = c/4; - int k = c%4; - int l = (32 + (2*e) + (2*i) - h - k)%7; - int m = (a + (11*h) + (22*l))/451; - int n = (h + l - (7*m) + 114)/31; // This is the month number. - int p = (h + l - (7*m) + 114)%31; // This is the date minus one. - - return new DateTime(year, n, p + 1); - } + return holidays[year]; + } - private static bool CheckDate(DateTime date, DateTime other) - { - return date.Day == other.Day && date.Month == other.Month; - } + + /// + /// Calculates easter day (sunday) by using Spencer Jones formula found here: + /// http://no.wikipedia.org/wiki/P%C3%A5skeformelen + /// + /// year + /// easterday for year + private static DateTime GetEasterDay(int year) + { + int a = year % 19; + int b = year / 100; + int c = year % 100; + int d = b / 4; + int e = b % 4; + int f = (b + 8) / 25; + int g = (b - f + 1) / 3; + int h = ((19 * a) + b - d - g + 15) % 30; + int i = c / 4; + int k = c % 4; + int l = (32 + (2 * e) + (2 * i) - h - k) % 7; + int m = (a + (11 * h) + (22 * l)) / 451; + int n = (h + l - (7 * m) + 114) / 31; // This is the month number. + int p = (h + l - (7 * m) + 114) % 31; // This is the date minus one. + + return new DateTime(year, n, p + 1); + } + + private static bool CheckDate(DateTime date, DateTime other) + { + return date.Day == other.Day && date.Month == other.Month; } -} \ No newline at end of file +} diff --git a/source/NoCommons/NoCommons.csproj b/source/NoCommons/NoCommons.csproj index ac125b2..f879095 100644 --- a/source/NoCommons/NoCommons.csproj +++ b/source/NoCommons/NoCommons.csproj @@ -1,6 +1,8 @@  - net8.0;net7.0 + net8.0;net9.0 + enable + enable NoCommons NoCommons John Korsnes @@ -13,7 +15,7 @@ https://github.com/johnkors/NoCommonsNET - - + + diff --git a/source/NoCommons/Org/Organisasjonsnummer.cs b/source/NoCommons/Org/Organisasjonsnummer.cs index be9a4c1..ca50dae 100644 --- a/source/NoCommons/Org/Organisasjonsnummer.cs +++ b/source/NoCommons/Org/Organisasjonsnummer.cs @@ -1,16 +1,13 @@ using NoCommons.Common; -namespace NoCommons.Org +namespace NoCommons.Org; + +/** + * This class represent a Norwegian organization number - an + * Organisasjonsnummer. An Organisasjonsnummer consists of 9 digits, and the + * last digit is a checksum digit. + */ +public record Organisasjonsnummer(string value) : StringNumber(value) { - /** - * This class represent a Norwegian organization number - an - * Organisasjonsnummer. An Organisasjonsnummer consists of 9 digits, and the - * last digit is a checksum digit. - */ - public class Organisasjonsnummer : StringNumber - { - internal Organisasjonsnummer(string organisasjonsnummer) : base(organisasjonsnummer) - { - } - } -} \ No newline at end of file + public override string ToString() => base.ToString(); +} diff --git a/source/NoCommons/Org/OrganisasjonsnummerCalculator.cs b/source/NoCommons/Org/OrganisasjonsnummerCalculator.cs index 7ebd6e5..32763ce 100644 --- a/source/NoCommons/Org/OrganisasjonsnummerCalculator.cs +++ b/source/NoCommons/Org/OrganisasjonsnummerCalculator.cs @@ -1,54 +1,57 @@ -using System; -using System.Collections.Generic; using System.Text; -namespace NoCommons.Org +namespace NoCommons.Org; + +/** + * This class calculates valid Organisasjonsnummer instances. + */ +public class OrganisasjonsnummerCalculator { + private const int LENGTH = 9; + + private OrganisasjonsnummerCalculator() + { + } /** - * This class calculates valid Organisasjonsnummer instances. + * Returns a List with completely random but syntactically valid + * Organisasjonsnummer instances. + * + * @param length + * Specifies the number of Organisasjonsnummer instances to + * create in the returned List + * + * @return A List with random valid Organisasjonsnummer instances */ - public class OrganisasjonsnummerCalculator { - - private const int LENGTH = 9; + public static List GetOrganisasjonsnummerList(int length) + { + List result = new(); + int numAddedToList = 0; + while (numAddedToList < length) + { + StringBuilder orgnrBuffer = new(LENGTH); + for (int i = 0; i < LENGTH; i++) + { + Random rand = new(); + int rand10 = rand.Next(0, 10); + orgnrBuffer.Append(rand10); + } - private OrganisasjonsnummerCalculator() { - - } + Organisasjonsnummer orgNr; + try + { + orgNr = OrganisasjonsnummerValidator.GetAndForceValidOrganisasjonsnummer(orgnrBuffer.ToString()); + } + catch (ArgumentException) + { + // this number has no valid checksum + continue; + } - /** - * Returns a List with completely random but syntactically valid - * Organisasjonsnummer instances. - * - * @param length - * Specifies the number of Organisasjonsnummer instances to - * create in the returned List - * - * @return A List with random valid Organisasjonsnummer instances - */ - public static List GetOrganisasjonsnummerList(int length) { - var result = new List(); - int numAddedToList = 0; - while (numAddedToList < length) { - var orgnrBuffer = new StringBuilder(LENGTH); - for (int i = 0; i < LENGTH; i++) - { - var rand = new Random(); - var rand10 = rand.Next(0, 10); - orgnrBuffer.Append(rand10); - } - Organisasjonsnummer orgNr; - try { - orgNr = OrganisasjonsnummerValidator.GetAndForceValidOrganisasjonsnummer(orgnrBuffer.ToString()); - } catch (ArgumentException) { - // this number has no valid checksum - continue; - } - result.Add(orgNr); - numAddedToList++; - } - return result; - } + result.Add(orgNr); + numAddedToList++; + } + return result; } -} \ No newline at end of file +} diff --git a/source/NoCommons/Org/OrganisasjonsnummerValidator.cs b/source/NoCommons/Org/OrganisasjonsnummerValidator.cs index 7bd9fa7..60db480 100644 --- a/source/NoCommons/Org/OrganisasjonsnummerValidator.cs +++ b/source/NoCommons/Org/OrganisasjonsnummerValidator.cs @@ -1,94 +1,93 @@ -using System; -using NoCommons.Common; +using NoCommons.Common; -namespace NoCommons.Org +namespace NoCommons.Org; + +/** + * Provides methods that validates if an Organisasjonsnummer is valid with + * respect to syntax (length and digits only) and that the checksum digit is + * correct. + */ +public class OrganisasjonsnummerValidator : StringNumberValidator { + private const int LENGTH = 9; + /** - * Provides methods that validates if an Organisasjonsnummer is valid with - * respect to syntax (length and digits only) and that the checksum digit is - * correct. + * Return true if the provided string is a valid Organisasjonsnummer. + * + * @param organisasjonsnummer + * A string containing a Organisasjonsnummer + * @return true or false */ - public class OrganisasjonsnummerValidator : StringNumberValidator + public static bool IsValid(string organisasjonsnummer) { - private const int LENGTH = 9; - - /** - * Return true if the provided string is a valid Organisasjonsnummer. - * - * @param organisasjonsnummer - * A string containing a Organisasjonsnummer - * @return true or false - */ - public static bool IsValid(string organisasjonsnummer) + try { - try - { - GetOrganisasjonsnummer(organisasjonsnummer); - return true; - } - catch (ArgumentException) - { - return false; - } + GetOrganisasjonsnummer(organisasjonsnummer); + return true; } - - /** - * Returns an object that represents an Organisasjonsnummer. - * - * @param organisasjonsnummer - * A string containing an Organisasjonsnummer - * @return An Organisasjonsnummer instance - * @throws ArgumentException - * thrown if string contains an invalid Organisasjonsnummer - */ - public static Organisasjonsnummer GetOrganisasjonsnummer(string organisasjonsnummer) + catch (ArgumentException) { - ValidateSyntax(organisasjonsnummer); - ValidateChecksum(organisasjonsnummer); - return new Organisasjonsnummer(organisasjonsnummer); + return false; } + } + + /** + * Returns an object that represents an Organisasjonsnummer. + * + * @param organisasjonsnummer + * A string containing an Organisasjonsnummer + * @return An Organisasjonsnummer instance + * @throws ArgumentException + * thrown if string contains an invalid Organisasjonsnummer + */ + public static Organisasjonsnummer GetOrganisasjonsnummer(string organisasjonsnummer) + { + ValidateSyntax(organisasjonsnummer); + ValidateChecksum(organisasjonsnummer); + return new Organisasjonsnummer(organisasjonsnummer); + } - /** - * Returns an object that represents a Organisasjonsnummer. The checksum of - * the supplied organisasjonsnummer is changed to a valid checksum if the - * original organisasjonsnummer has an invalid checksum. - * - * @param organisasjonsnummer - * A string containing a Organisasjonsnummer - * @return A Organisasjonsnummer instance - * @throws ArgumentException - * thrown if string contains an invalid Organisasjonsnummer, ie. - * a number which for one cannot calculate a valid checksum. - */ - public static Organisasjonsnummer GetAndForceValidOrganisasjonsnummer(string organisasjonsnummer) + /** + * Returns an object that represents a Organisasjonsnummer. The checksum of + * the supplied organisasjonsnummer is changed to a valid checksum if the + * original organisasjonsnummer has an invalid checksum. + * + * @param organisasjonsnummer + * A string containing a Organisasjonsnummer + * @return A Organisasjonsnummer instance + * @throws ArgumentException + * thrown if string contains an invalid Organisasjonsnummer, ie. + * a number which for one cannot calculate a valid checksum. + */ + public static Organisasjonsnummer GetAndForceValidOrganisasjonsnummer(string organisasjonsnummer) + { + ValidateSyntax(organisasjonsnummer); + try { - ValidateSyntax(organisasjonsnummer); - try - { - ValidateChecksum(organisasjonsnummer); - } - catch (ArgumentException) - { - var onr = new Organisasjonsnummer(organisasjonsnummer); - int checksum = CalculateMod11CheckSum(GetMod11Weights(onr), onr); - organisasjonsnummer = organisasjonsnummer.Substring(0, LENGTH - 1) + checksum; - } - return new Organisasjonsnummer(organisasjonsnummer); + ValidateChecksum(organisasjonsnummer); } - - internal static void ValidateSyntax(string fodselsnummer) + catch (ArgumentException) { - ValidateLengthAndAllDigits(fodselsnummer, LENGTH); + Organisasjonsnummer onr = new(organisasjonsnummer); + int checksum = CalculateMod11CheckSum(GetMod11Weights(onr), onr); + organisasjonsnummer = organisasjonsnummer.Substring(0, LENGTH - 1) + checksum; } - internal static void ValidateChecksum(string organisasjonsnummer) + return new Organisasjonsnummer(organisasjonsnummer); + } + + internal static void ValidateSyntax(string fodselsnummer) + { + ValidateLengthAndAllDigits(fodselsnummer, LENGTH); + } + + internal static void ValidateChecksum(string organisasjonsnummer) + { + Organisasjonsnummer onr = new(organisasjonsnummer); + int k1 = CalculateMod11CheckSum(GetMod11Weights(onr), onr); + if (k1 != onr.GetChecksumDigit()) { - var onr = new Organisasjonsnummer(organisasjonsnummer); - int k1 = CalculateMod11CheckSum(GetMod11Weights(onr), onr); - if (k1 != onr.GetChecksumDigit()) - { - throw new ArgumentException(ERROR_INVALID_CHECKSUM + organisasjonsnummer); - } + throw new ArgumentException(ERROR_INVALID_CHECKSUM + organisasjonsnummer); } } -} \ No newline at end of file +} diff --git a/source/NoCommons/Person/Fodselsnummer.cs b/source/NoCommons/Person/Fodselsnummer.cs index 9442d75..c003643 100644 --- a/source/NoCommons/Person/Fodselsnummer.cs +++ b/source/NoCommons/Person/Fodselsnummer.cs @@ -1,198 +1,212 @@ -using System; -using NoCommons.Common; +using NoCommons.Common; -namespace NoCommons.Person +namespace NoCommons.Person; + +/** + * This class represent a Norwegian social security number - a Fodselsnummer. A + * Fodselsnummer consists of 11 digits, where the first 6 digits contains the + * date of birth and the last 5 consists of an Individnummer (3 digits) and two + * checksum digits. + */ +public record Fodselsnummer(string value) : StringNumber(value) { /** - * This class represent a Norwegian social security number - a Fodselsnummer. A - * Fodselsnummer consists of 11 digits, where the first 6 digits contains the - * date of birth and the last 5 consists of an Individnummer (3 digits) and two - * checksum digits. - */ - public class Fodselsnummer : StringNumber { - - public Fodselsnummer(string fodselsnummer) : base(fodselsnummer) { - - } + * Returns the first 4 digits of the Fodselsnummer that contains the date + * (01-31) and month(01-12) of birth. + * + * @return A string containing the date and month of birth. + */ + public string GetDateAndMonth() + { + return ParseDNumber(GetValue()).Substring(0, 4); + } - /** - * Returns the first 4 digits of the Fodselsnummer that contains the date - * (01-31) and month(01-12) of birth. - * - * @return A string containing the date and month of birth. - */ - public string GetDateAndMonth() { - return ParseDNumber(GetValue()).Substring(0, 4); - } + /** + * Returns the first 2 digits of the Fodselsnummer that contains the date + * (01-31), stripped for eventual d-numbers. + * + * @return A string containing the date of birth + */ + public string GetDayInMonth() + { + return ParseDNumber(GetValue()).Substring(0, 2); + } - /** - * Returns the first 2 digits of the Fodselsnummer that contains the date - * (01-31), stripped for eventual d-numbers. - * - * @return A string containing the date of birth - */ - public string GetDayInMonth() { - return ParseDNumber(GetValue()).Substring(0, 2); - } + /** + * Returns the digits 3 and 4 of the Fodselsnummer that contains the month + * (01-12), stripped for eventual d-numbers. + * + * @return A string containing the date of birth + */ + public string GetMonth() + { + return ParseDNumber(GetValue()).Substring(2, 2); + } - /** - * Returns the digits 3 and 4 of the Fodselsnummer that contains the month - * (01-12), stripped for eventual d-numbers. - * - * @return A string containing the date of birth - */ - public string GetMonth() { - return ParseDNumber(GetValue()).Substring(2, 2); - } + /** + * Returns the birthyear of the Fodselsnummer + * + * @return A string containing the year of birth. + */ + public string GetBirthYear() + { + return GetCentury() + Get2DigitBirthYear(); + } - /** - * Returns the birthyear of the Fodselsnummer - * - * @return A string containing the year of birth. - */ - public string GetBirthYear() { - return GetCentury() + Get2DigitBirthYear(); - } + public string? GetCentury() + { + int individnummerInt = int.Parse(GetIndividnummer()); + int birthYear = int.Parse(Get2DigitBirthYear()); + return individnummerInt switch + { + <= 499 => "19", + >= 500 when birthYear < 40 => "20", + <= 749 when birthYear >= 54 => "18", + >= 900 => "19", + _ => null + }; + } - public string GetCentury() { - string result = null; - int individnummerInt = int.Parse(GetIndividnummer()); - int birthYear = int.Parse(Get2DigitBirthYear()); - if (individnummerInt <= 499) { - result = "19"; - } else if (individnummerInt >= 500 && birthYear < 40) { - result = "20"; - } else if (individnummerInt >= 500 && individnummerInt <= 749 && birthYear >= 54) { - result = "18"; - } else if (individnummerInt >= 900 && birthYear > 39) { - result = "19"; - } - return result; - } + /** + * Returns the two digits of the Fodselsnummer that contains the year birth + * (00-99). + * + * @return A string containing the year of birth. + */ + public string Get2DigitBirthYear() + { + return GetValue().Substring(4, 2); + } - /** - * Returns the two digits of the Fodselsnummer that contains the year birth - * (00-99). - * - * @return A string containing the year of birth. - */ - public string Get2DigitBirthYear() { - return GetValue().Substring(4, 2); - } + /** + * Returns the first 6 digits of the Fodselsnummer that contains the date + * (01-31), month(01-12) and year(00-99) of birth. + * + * @return A string containing the date and month of birth. + */ + public string GetDateOfBirth() + { + return ParseDNumber(GetValue()).Substring(0, 6); + } - /** - * Returns the first 6 digits of the Fodselsnummer that contains the date - * (01-31), month(01-12) and year(00-99) of birth. - * - * @return A string containing the date and month of birth. - */ - public string GetDateOfBirth() { - return ParseDNumber(GetValue()).Substring(0, 6); - } + /** + * Returns the last 5 digits of the Fodselsnummer, also referred to as the + * Personnummer. The Personnummer consists of the Individnummer (3 digits) + * and two checksum digits. + * + * @return A string containing the Personnummer. + */ + public string GetPersonnummer() + { + return GetValue().Substring(6); + } - /** - * Returns the last 5 digits of the Fodselsnummer, also referred to as the - * Personnummer. The Personnummer consists of the Individnummer (3 digits) - * and two checksum digits. - * - * @return A string containing the Personnummer. - */ - public string GetPersonnummer() { - return GetValue().Substring(6); - } + /** + * Returns the first three digits of the Personnummer, also known as the + * Individnummer. + * + * @return A string containing the Individnummer. + */ + public string GetIndividnummer() + { + return GetValue().Substring(6, 3); + } - /** - * Returns the first three digits of the Personnummer, also known as the - * Individnummer. - * - * @return A string containing the Individnummer. - */ - public string GetIndividnummer() { - return GetValue().Substring(6, 3); - } + /** + * Returns the digit that decides the gender - the 9th in the Fodselsnummer. + * + * @return The digit. + */ + public int GetGenderDigit() + { + return GetAt(8); + } - /** - * Returns the digit that decides the gender - the 9th in the Fodselsnummer. - * - * @return The digit. - */ - public int GetGenderDigit() { - return GetAt(8); - } + /** + * Returns the first checksum digit - the 10th in the Fodselsnummer. + * + * @return The digit. + */ + public int GetChecksumDigit1() + { + return GetAt(9); + } - /** - * Returns the first checksum digit - the 10th in the Fodselsnummer. - * - * @return The digit. - */ - public int GetChecksumDigit1() { - return GetAt(9); - } + /** + * Returns the second checksum digit - the 11th in the Fodselsnummer. + * + * @return The digit. + */ + public int GetChecksumDigit2() + { + return GetAt(10); + } - /** - * Returns the second checksum digit - the 11th in the Fodselsnummer. - * - * @return The digit. - */ - public int GetChecksumDigit2() { - return GetAt(10); - } + /** + * Returns true if the Fodselsnummer represents a man. + * + * @return true or false. + */ + public bool IsMale() + { + return GetGenderDigit() % 2 != 0; + } - /** - * Returns true if the Fodselsnummer represents a man. - * - * @return true or false. - */ - public bool IsMale() { - return GetGenderDigit() % 2 != 0; - } + /** + * Returns true if the Fodselsnummer represents a woman. + * + * @return true or false. + */ + public bool IsFemale() + { + return !IsMale(); + } - /** - * Returns true if the Fodselsnummer represents a woman. - * - * @return true or false. - */ - public bool IsFemale() { - return !IsMale(); + public static bool IsDNumber(string fodselsnummer) + { + try + { + int firstDigit = GetFirstDigit(fodselsnummer); + if (firstDigit > 3 && firstDigit < 8) + { + return true; + } } - - public static bool IsDNumber(string fodselsnummer) { - try { - int firstDigit = GetFirstDigit(fodselsnummer); - if (firstDigit > 3 && firstDigit < 8) { - return true; - } - } catch (ArgumentException) { - // ignore - } - return false; + catch (ArgumentException) + { + // ignore } - public static string ParseDNumber(string fodselsnummer) { - if (!IsDNumber(fodselsnummer)) { - return fodselsnummer; - } else { - return (GetFirstDigit(fodselsnummer) - 4) + fodselsnummer.Substring(1); - } - } + return false; + } - private static int GetFirstDigit(string fodselsnummer) { - return int.Parse(fodselsnummer.Substring(0, 1)); + public static string ParseDNumber(string fodselsnummer) + { + if (!IsDNumber(fodselsnummer)) + { + return fodselsnummer; } - public KJONN GetKjonn() { - if (IsFemale()) { - return KJONN.KVINNE; - } else { - return KJONN.MANN; - } - } - - public override string ToString(){ - return GetValue(); - } + return GetFirstDigit(fodselsnummer) - 4 + fodselsnummer.Substring(1); } + private static int GetFirstDigit(string fodselsnummer) + { + return int.Parse(fodselsnummer.Substring(0, 1)); + } + + public KJONN GetKjonn() + { + if (IsFemale()) + { + return KJONN.KVINNE; + } - + return KJONN.MANN; + } + + public override string ToString() + { + return GetValue(); + } } diff --git a/source/NoCommons/Person/FodselsnummerCalculator.cs b/source/NoCommons/Person/FodselsnummerCalculator.cs index c5b9b21..040ce88 100644 --- a/source/NoCommons/Person/FodselsnummerCalculator.cs +++ b/source/NoCommons/Person/FodselsnummerCalculator.cs @@ -1,99 +1,94 @@ -using System; -using System.Collections.Generic; -using System.Linq; using System.Text; -namespace NoCommons.Person +namespace NoCommons.Person; + +/** + * This class calculates valid Fodselsnummer instances for a given date. + */ +public class FodselsnummerCalculator { /** - * This class calculates valid Fodselsnummer instances for a given date. + * Returns a List with valid Fodselsnummer instances for a given Date and gender. */ - public class FodselsnummerCalculator + public static List GetFodselsnummerForDateAndGender(DateTime date, KJONN kjonn) { + List result = GetManyFodselsnummerForDate(date); + result = SplitByGender(kjonn, result); + return result; + } - /** - * Returns a List with valid Fodselsnummer instances for a given Date and gender. - */ - public static List GetFodselsnummerForDateAndGender(DateTime date, KJONN kjonn) - { - List result = GetManyFodselsnummerForDate(date); - result = SplitByGender(kjonn, result); - return result; - } + /** + * Return one random valid fodselsnummer on a given date + */ + public static Fodselsnummer GetFodselsnummerForDate(DateTime date) + { + List fodselsnummerList = GetManyFodselsnummerForDate(date); + //Collections.shuffle(fodselsnummerList); + return fodselsnummerList[0]; + } - /** - * Return one random valid fodselsnummer on a given date - */ - public static Fodselsnummer GetFodselsnummerForDate(DateTime date) + /** + * Returns a List with with VALID Fodselsnummer instances for a given Date. + * + * @param date The Date instance + * @return A List with Fodelsnummer instances + */ + public static List GetManyFodselsnummerForDate(DateTime date, bool dNumber = false) + { + string century = GetCentury(date); + + string dateString = date.ToString("ddMMyy"); + if (dNumber) { - List fodselsnummerList = GetManyFodselsnummerForDate(date); - //Collections.shuffle(fodselsnummerList); - return fodselsnummerList[0]; + int day = date.Day + 40; + dateString = $"{day}{date.ToString("MMyy")}"; } - /** - * Returns a List with with VALID Fodselsnummer instances for a given Date. - * - * @param date The Date instance - * @return A List with Fodelsnummer instances - */ - public static List GetManyFodselsnummerForDate(DateTime date, bool dNumber = false) - { - var century = GetCentury(date); - - var dateString = date.ToString("ddMMyy"); - if (dNumber) + List result = new(); + for (int i = 999; i >= 0; i--) + { + StringBuilder sb = new(dateString); + if (i < 10) + { + sb.Append("00"); + } + else if (i < 100) { - var day = date.Day + 40; - dateString = $"{day}{date.ToString("MMyy")}"; + sb.Append("0"); } - var result = new List(); - for (int i = 999; i >= 0; i--) + sb.Append(i); + Fodselsnummer fodselsnummer = new(sb.ToString()); + try { - var sb = new StringBuilder(dateString); - if (i < 10) - { - sb.Append("00"); - } - else if (i < 100) - { - sb.Append("0"); - } - sb.Append(i); - var fodselsnummer = new Fodselsnummer(sb.ToString()); - try - { - sb.Append(FodselsnummerValidator.CalculateFirstChecksumDigit(fodselsnummer)); - fodselsnummer = new Fodselsnummer(sb.ToString()); + sb.Append(FodselsnummerValidator.CalculateFirstChecksumDigit(fodselsnummer)); + fodselsnummer = new Fodselsnummer(sb.ToString()); - sb.Append(FodselsnummerValidator.CalculateSecondChecksumDigit(fodselsnummer)); - fodselsnummer = new Fodselsnummer(sb.ToString()); + sb.Append(FodselsnummerValidator.CalculateSecondChecksumDigit(fodselsnummer)); + fodselsnummer = new Fodselsnummer(sb.ToString()); - var centuryByIndividnummer = fodselsnummer.GetCentury(); - if (centuryByIndividnummer != null && centuryByIndividnummer.Equals(century) && FodselsnummerValidator.IsValid(fodselsnummer.GetValue())) - { - result.Add(fodselsnummer); - } - } - catch (ArgumentException) + string? centuryByIndividnummer = fodselsnummer.GetCentury(); + if (centuryByIndividnummer != null && centuryByIndividnummer.Equals(century) && + FodselsnummerValidator.IsValid(fodselsnummer.GetValue())) { - continue; + result.Add(fodselsnummer); } } - return result; + catch (ArgumentException) + { + } } - private static string GetCentury(DateTime date) - { - return Convert.ToString(date.Year).Substring(0, 2); - } + return result; + } - private static List SplitByGender(KJONN kjonn, List result) - { - return (from f in result where f.GetKjonn() == kjonn select f).ToList(); - - } + private static string GetCentury(DateTime date) + { + return Convert.ToString(date.Year).Substring(0, 2); + } + private static List SplitByGender(KJONN kjonn, List result) + { + return (from f in result where f.GetKjonn() == kjonn select f).ToList(); } } diff --git a/source/NoCommons/Person/FodselsnummerValidator.cs b/source/NoCommons/Person/FodselsnummerValidator.cs index 10f3986..247cf0f 100644 --- a/source/NoCommons/Person/FodselsnummerValidator.cs +++ b/source/NoCommons/Person/FodselsnummerValidator.cs @@ -1,95 +1,109 @@ -using System; using System.Globalization; using NoCommons.Common; -namespace NoCommons.Person +namespace NoCommons.Person; + +/** +* Provides methods that validates if a Fodselsnummer is valid with respect to +* syntax, Individnummer, Date and checksum digits. +*/ +public class FodselsnummerValidator : StringNumberValidator { - /** - * Provides methods that validates if a Fodselsnummer is valid with respect to - * syntax, Individnummer, Date and checksum digits. - */ - public class FodselsnummerValidator : StringNumberValidator { + private const int LENGTH = 11; - private const int LENGTH = 11; + private const string DATE_FORMAT = "ddMMyyyy"; - private const string DATE_FORMAT = "ddMMyyyy"; + public const string ERROR_INVALID_DATE = "Invalid date in f�dselsnummer : "; - private static readonly int[] K1_WEIGHTS = new [] { 2, 5, 4, 9, 8, 1, 6, 7, 3 }; - private static readonly int[] K2_WEIGHTS = new int[] { 2, 3, 4, 5, 6, 7, 2, 3, 4, 5 }; + public const string ERROR_INVALID_INDIVIDNUMMER = "Invalid individnummer in f�dselsnummer : "; - public const string ERROR_INVALID_DATE = "Invalid date in f�dselsnummer : "; + private static readonly int[] K1_WEIGHTS = new[] { 2, 5, 4, 9, 8, 1, 6, 7, 3 }; + private static readonly int[] K2_WEIGHTS = new[] { 2, 3, 4, 5, 6, 7, 2, 3, 4, 5 }; - public const string ERROR_INVALID_INDIVIDNUMMER = "Invalid individnummer in f�dselsnummer : "; + /** + * Returns an object that represents a Fodselsnummer. + * + * @param fodselsnummer + * A string containing a Fodselsnummer + * @return A Fodselsnummer instance + * @throws ArgumentException + * thrown if string contains an invalid Fodselsnummer + */ + public static Fodselsnummer getFodselsnummer(string fodselsnummer) + { + ValidateSyntax(fodselsnummer); + validateIndividnummer(fodselsnummer); + validateDate(fodselsnummer); + validateChecksums(fodselsnummer); + return new Fodselsnummer(fodselsnummer); + } - /** - * Returns an object that represents a Fodselsnummer. - * - * @param fodselsnummer - * A string containing a Fodselsnummer - * @return A Fodselsnummer instance - * @throws ArgumentException - * thrown if string contains an invalid Fodselsnummer - */ - public static Fodselsnummer getFodselsnummer(string fodselsnummer) { - ValidateSyntax(fodselsnummer); - validateIndividnummer(fodselsnummer); - validateDate(fodselsnummer); - validateChecksums(fodselsnummer); - return new Fodselsnummer(fodselsnummer); + /** + * Return true if the provided string is a valid Fodselsnummer. + * + * @param fodselsnummer + * A string containing a Fodselsnummer + * @return true or false + */ + public static bool IsValid(string fodselsnummer) + { + try + { + getFodselsnummer(fodselsnummer); + return true; } - - /** - * Return true if the provided string is a valid Fodselsnummer. - * - * @param fodselsnummer - * A string containing a Fodselsnummer - * @return true or false - */ - public static bool IsValid(string fodselsnummer) { - try { - getFodselsnummer(fodselsnummer); - return true; - } catch (ArgumentException) { - return false; - } + catch (ArgumentException) + { + return false; } + } - public static void ValidateSyntax(string fodselsnummer) { - ValidateLengthAndAllDigits(fodselsnummer, LENGTH); - } + public static void ValidateSyntax(string fodselsnummer) + { + ValidateLengthAndAllDigits(fodselsnummer, LENGTH); + } - public static void validateIndividnummer(string fodselsnummer) { - var fnr = new Fodselsnummer(fodselsnummer); - if (fnr.GetCentury() == null) { - throw new ArgumentException(ERROR_INVALID_INDIVIDNUMMER + fodselsnummer); - } + public static void validateIndividnummer(string fodselsnummer) + { + Fodselsnummer fnr = new(fodselsnummer); + if (fnr.GetCentury() == null) + { + throw new ArgumentException(ERROR_INVALID_INDIVIDNUMMER + fodselsnummer); } + } - public static void validateDate(string fodselsnummer) { - var fnr = new Fodselsnummer(fodselsnummer); - try { - var dateString = fnr.GetDateAndMonth() + fnr.GetCentury() + fnr.Get2DigitBirthYear(); - DateTime.ParseExact(dateString, DATE_FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None); - } catch (Exception) { - throw new ArgumentException(ERROR_INVALID_DATE + fodselsnummer); - } + public static void validateDate(string fodselsnummer) + { + Fodselsnummer fnr = new(fodselsnummer); + try + { + string dateString = fnr.GetDateAndMonth() + fnr.GetCentury() + fnr.Get2DigitBirthYear(); + DateTime.ParseExact(dateString, DATE_FORMAT, CultureInfo.InvariantCulture, DateTimeStyles.None); } - - public static void validateChecksums(string fodselsnummer) { - var fnr = new Fodselsnummer(fodselsnummer); - int k1 = CalculateFirstChecksumDigit(fnr); - int k2 = CalculateSecondChecksumDigit(fnr); - if (k1 != fnr.GetChecksumDigit1() || k2 != fnr.GetChecksumDigit2()) { - throw new ArgumentException(ERROR_INVALID_CHECKSUM + fodselsnummer); - } + catch (Exception) + { + throw new ArgumentException(ERROR_INVALID_DATE + fodselsnummer); } + } - internal static int CalculateFirstChecksumDigit(Fodselsnummer fodselsnummer) { - return CalculateMod11CheckSum(K1_WEIGHTS, fodselsnummer); + public static void validateChecksums(string fodselsnummer) + { + Fodselsnummer fnr = new(fodselsnummer); + int k1 = CalculateFirstChecksumDigit(fnr); + int k2 = CalculateSecondChecksumDigit(fnr); + if (k1 != fnr.GetChecksumDigit1() || k2 != fnr.GetChecksumDigit2()) + { + throw new ArgumentException(ERROR_INVALID_CHECKSUM + fodselsnummer); } + } - internal static int CalculateSecondChecksumDigit(Fodselsnummer fodselsnummer) { - return CalculateMod11CheckSum(K2_WEIGHTS, fodselsnummer); - } + internal static int CalculateFirstChecksumDigit(Fodselsnummer fodselsnummer) + { + return CalculateMod11CheckSum(K1_WEIGHTS, fodselsnummer); + } + + internal static int CalculateSecondChecksumDigit(Fodselsnummer fodselsnummer) + { + return CalculateMod11CheckSum(K2_WEIGHTS, fodselsnummer); } -} \ No newline at end of file +} diff --git a/source/NoCommons/Person/KJONN.cs b/source/NoCommons/Person/KJONN.cs index 442d704..032b031 100644 --- a/source/NoCommons/Person/KJONN.cs +++ b/source/NoCommons/Person/KJONN.cs @@ -1,9 +1,8 @@ -namespace NoCommons.Person +namespace NoCommons.Person; + +public enum KJONN { - public enum KJONN - { - MANN, - KVINNE, - BEGGE - } -} \ No newline at end of file + MANN, + KVINNE, + BEGGE +}