diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..72d712e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,277 @@ + +[*.proto] +indent_style=tab +indent_size=tab +tab_width=4 + +[*.{asax,ascx,aspx,cs,cshtml,css,htm,html,js,jsx,master,razor,skin,ts,tsx,vb,xaml,xamlx,xoml}] +indent_style=space +indent_size=4 +tab_width=4 + +[*.{json,resjson}] +indent_style=space +indent_size=2 +tab_width=2 + +[*.{appxmanifest,axml,build,config,csproj,dbml,discomap,dtd,jsproj,lsproj,njsproj,nuspec,proj,props,resw,resx,StyleCop,targets,tasks,vbproj,xml,xsd}] +indent_style=space +indent_size=2 +tab_width=4 + +[*] + +# Standard properties +end_of_line=crlf + +# Microsoft .NET properties +csharp_new_line_before_open_brace=none +csharp_preferred_modifier_order=private, protected, public, internal, new, abstract, virtual, sealed, override, static, readonly, extern, unsafe, volatile, async:suggestion +csharp_prefer_braces=true:error +csharp_space_between_method_call_parameter_list_parentheses=true +csharp_space_between_method_declaration_parameter_list_parentheses=true +csharp_space_between_parentheses=control_flow_statements,expressions,type_casts +csharp_style_var_elsewhere=true:error +csharp_style_var_for_built_in_types=true:error +csharp_style_var_when_type_is_apparent=true:error +csharp_using_directive_placement=inside_namespace:silent +dotnet_style_parentheses_in_arithmetic_binary_operators=never_if_unnecessary:warning +dotnet_style_parentheses_in_other_binary_operators=never_if_unnecessary:warning +dotnet_style_parentheses_in_relational_binary_operators=never_if_unnecessary:warning +dotnet_style_predefined_type_for_locals_parameters_members=false:none +dotnet_style_predefined_type_for_member_access=false:error +dotnet_style_qualification_for_event=true:warning +dotnet_style_qualification_for_field=true:warning +dotnet_style_qualification_for_method=true:warning +dotnet_style_qualification_for_property=true:warning +dotnet_style_require_accessibility_modifiers=for_non_interface_members:suggestion + +# ReSharper properties +resharper_arguments_anonymous_function=named +resharper_arguments_literal=named +resharper_arguments_named=named +resharper_arguments_other=named +resharper_arguments_string_literal=named +resharper_autodetect_indent_settings=true +resharper_blank_lines_after_multiline_statements=1 +resharper_blank_lines_around_single_line_auto_property=1 +resharper_blank_lines_around_single_line_local_method=1 +resharper_blank_lines_around_single_line_property=1 +resharper_blank_lines_before_block_statements=1 +resharper_blank_lines_before_control_transfer_statements=1 +resharper_blank_lines_before_multiline_statements=1 +resharper_blank_lines_before_single_line_comment=1 +resharper_blank_lines_inside_namespace=1 +resharper_blank_lines_inside_type=1 +resharper_braces_redundant=true +resharper_brace_style=end_of_line +resharper_constructor_or_destructor_body=expression_body +resharper_csharp_blank_lines_around_single_line_field=1 +resharper_csharp_blank_lines_around_single_line_invocable=1 +resharper_csharp_empty_block_style=together +resharper_csharp_keep_blank_lines_in_code=1 +resharper_csharp_keep_blank_lines_in_declarations=1 +resharper_csharp_max_line_length=175 +resharper_csharp_space_within_array_access_brackets=true +resharper_csharp_use_indent_from_vs=false +resharper_csharp_wrap_before_ternary_opsigns=false +resharper_enforce_line_ending_style=true +resharper_indent_nested_fixed_stmt=true +resharper_indent_nested_foreach_stmt=true +resharper_indent_nested_for_stmt=true +resharper_indent_nested_lock_stmt=true +resharper_indent_nested_usings_stmt=true +resharper_indent_nested_while_stmt=true +resharper_keep_existing_embedded_arrangement=false +resharper_keep_existing_expr_member_arrangement=false +resharper_keep_existing_initializer_arrangement=false +resharper_keep_existing_invocation_parens_arrangement=false +resharper_keep_existing_linebreaks=false +resharper_local_function_body=expression_body +resharper_max_enum_members_on_line=1 +resharper_max_initializer_elements_on_line=5 +resharper_method_or_operator_body=expression_body +resharper_place_accessorholder_attribute_on_same_line=false +resharper_place_field_attribute_on_same_line=false +resharper_place_simple_anonymousmethod_on_single_line=false +resharper_place_simple_case_statement_on_same_line=if_owner_is_single_line +resharper_place_simple_initializer_on_single_line=false +resharper_remove_blank_lines_near_braces_in_code=false +resharper_space_around_arrow_op=true +resharper_space_within_array_rank_brackets=true +resharper_space_within_checked_parentheses=true +resharper_space_within_default_parentheses=true +resharper_space_within_nameof_parentheses=true +resharper_space_within_single_line_array_initializer_braces=true +resharper_space_within_sizeof_parentheses=true +resharper_space_within_typeof_parentheses=true +resharper_wrap_before_linq_expression=true +resharper_xmldoc_attribute_indent=align_by_first_attribute +resharper_xmldoc_attribute_style=on_single_line +resharper_xmldoc_blank_line_after_pi=false +resharper_xmldoc_indent_text=ZeroIndent +resharper_xmldoc_keep_user_linebreaks=false +resharper_xmldoc_max_line_length=180 +resharper_xmldoc_pi_attribute_style=on_single_line +resharper_xmldoc_wrap_tags_and_pi=false +resharper_xml_linebreaks_inside_tags_for_elements_longer_than=2147483645 +resharper_xml_max_blank_lines_between_tags=1 +resharper_xml_max_line_length=220 + +# ReSharper inspection severities +resharper_annotate_can_be_null_parameter_highlighting=warning +resharper_annotate_can_be_null_type_member_highlighting=warning +resharper_annotate_not_null_type_member_highlighting=warning +resharper_annotation_redundancy_at_value_type_highlighting=error +resharper_annotation_redundancy_in_hierarchy_highlighting=none +resharper_arguments_style_anonymous_function_highlighting=none +resharper_arguments_style_literal_highlighting=none +resharper_arguments_style_named_expression_highlighting=none +resharper_arguments_style_other_highlighting=none +resharper_arguments_style_string_literal_highlighting=none +resharper_arrange_accessor_owner_body_highlighting=error +resharper_arrange_attributes_highlighting=error +resharper_arrange_constructor_or_destructor_body_highlighting=suggestion +resharper_arrange_local_function_body_highlighting=error +resharper_arrange_method_or_operator_body_highlighting=error +resharper_arrange_redundant_parentheses_highlighting=none +resharper_arrange_this_qualifier_highlighting=error +resharper_arrange_type_member_modifiers_highlighting=hint +resharper_arrange_type_modifiers_highlighting=hint +resharper_assign_null_to_not_null_attribute_highlighting=error +resharper_auto_property_can_be_made_get_only_global_highlighting=hint +resharper_base_member_has_params_highlighting=error +resharper_check_namespace_highlighting=error +resharper_class_cannot_be_instantiated_highlighting=error +resharper_class_never_instantiated_global_highlighting=none +resharper_class_never_instantiated_local_highlighting=none +resharper_class_with_virtual_members_never_inherited_global_highlighting=none +resharper_collection_never_queried_global_highlighting=none +resharper_collection_never_queried_local_highlighting=none +resharper_comment_typo_highlighting=none +resharper_conditional_ternary_equal_branch_highlighting=error +resharper_condition_is_always_true_or_false_highlighting=error +resharper_consider_using_configure_await_highlighting=error +resharper_constant_conditional_access_qualifier_highlighting=error +resharper_constant_null_coalescing_condition_highlighting=error +resharper_convert_closure_to_method_group_highlighting=error +resharper_convert_nullable_to_short_form_highlighting=error +resharper_convert_switch_statement_to_switch_expression_highlighting=none +resharper_convert_to_auto_property_highlighting=error +resharper_convert_to_auto_property_when_possible_highlighting=error +resharper_convert_to_auto_property_with_private_setter_highlighting=error +resharper_convert_to_compound_assignment_highlighting=error +resharper_convert_to_constant_global_highlighting=error +resharper_convert_to_constant_local_highlighting=error +resharper_convert_to_lambda_expression_highlighting=error +resharper_convert_to_lambda_expression_when_possible_highlighting=error +resharper_convert_to_local_function_highlighting=error +resharper_convert_to_null_coalescing_compound_assignment_highlighting=error +resharper_convert_to_static_class_highlighting=error +resharper_convert_to_using_declaration_highlighting=none +resharper_c_sharp_warnings_cs1570_highlighting=error +resharper_c_sharp_warnings_cs1574_highlighting=error +resharper_c_sharp_warnings_cs1591_highlighting=none +resharper_c_sharp_warnings_cs1592_highlighting=error +resharper_c_sharp_warnings_cs8123_highlighting=error +resharper_c_sharp_warnings_wme006_highlighting=error +resharper_empty_constructor_highlighting=error +resharper_empty_general_catch_clause_highlighting=none +resharper_empty_statement_highlighting=error +resharper_event_unsubscription_via_anonymous_delegate_highlighting=error +resharper_field_can_be_made_read_only_global_highlighting=hint +resharper_field_can_be_made_read_only_local_highlighting=error +resharper_foreach_can_be_converted_to_query_using_another_get_enumerator_highlighting=error +resharper_for_can_be_converted_to_foreach_highlighting=error +resharper_function_recursive_on_all_paths_highlighting=error +resharper_heuristic_unreachable_code_highlighting=error +resharper_identifier_typo_highlighting=none +resharper_implicitly_captured_closure_highlighting=none +resharper_inconsistent_naming_highlighting=none +resharper_inline_out_variable_declaration_highlighting=error +resharper_invalid_xml_doc_comment_highlighting=error +resharper_invoke_as_extension_method_highlighting=error +resharper_join_declaration_and_initializer_highlighting=error +resharper_join_null_check_with_usage_highlighting=error +resharper_join_null_check_with_usage_when_possible_highlighting=error +resharper_localizable_element_highlighting=none +resharper_local_function_can_be_made_static_highlighting=error +resharper_loop_can_be_converted_to_query_highlighting=error +resharper_loop_can_be_partly_converted_to_query_highlighting=suggestion +resharper_member_can_be_made_static_global_highlighting=error +resharper_member_can_be_made_static_local_highlighting=error +resharper_member_can_be_private_global_highlighting=none +resharper_member_can_be_protected_global_highlighting=none +resharper_member_initializer_value_ignored_highlighting=error +resharper_merge_cast_with_type_check_highlighting=error +resharper_merge_conditional_expression_highlighting=error +resharper_merge_conditional_expression_when_possible_highlighting=error +resharper_merge_sequential_checks_highlighting=error +resharper_merge_sequential_checks_when_possible_highlighting=error +resharper_method_supports_cancellation_highlighting=error +resharper_multiple_order_by_highlighting=error +resharper_negative_equality_expression_highlighting=error +resharper_not_accessed_field_global_highlighting=none +resharper_not_resolved_in_text_highlighting=error +resharper_n_unit_method_with_parameters_and_test_attribute_highlighting=error +resharper_parameter_hides_member_highlighting=error +resharper_parameter_only_used_for_precondition_check_global_highlighting=none +resharper_parameter_only_used_for_precondition_check_local_highlighting=suggestion +resharper_partial_type_with_single_part_highlighting=error +resharper_possibly_impure_method_call_on_readonly_variable_highlighting=error +resharper_pure_attribute_on_void_method_highlighting=error +resharper_redundant_argument_default_value_highlighting=none +resharper_redundant_assignment_highlighting=error +resharper_redundant_base_constructor_call_highlighting=error +resharper_redundant_bool_compare_highlighting=error +resharper_redundant_cast_highlighting=error +resharper_redundant_default_member_initializer_highlighting=error +resharper_redundant_empty_finally_block_highlighting=error +resharper_redundant_extends_list_entry_highlighting=error +resharper_redundant_if_else_block_highlighting=error +resharper_redundant_overflow_checking_context_highlighting=error +resharper_redundant_query_order_by_ascending_keyword_highlighting=error +resharper_redundant_readonly_modifier_highlighting=error +resharper_redundant_to_string_call_for_value_type_highlighting=error +resharper_redundant_using_directive_highlighting=error +resharper_reference_equals_with_value_type_highlighting=error +resharper_return_type_can_be_enumerable_global_highlighting=suggestion +resharper_return_type_can_be_enumerable_local_highlighting=error +resharper_return_value_of_pure_method_is_not_used_highlighting=error +resharper_simplify_conditional_ternary_expression_highlighting=error +resharper_simplify_linq_expression_highlighting=error +resharper_specify_a_culture_in_string_conversion_explicitly_highlighting=none +resharper_string_literal_as_interpolation_argument_highlighting=error +resharper_string_literal_typo_highlighting=none +resharper_suggest_base_type_for_parameter_highlighting=none +resharper_too_wide_local_variable_scope_highlighting=error +resharper_try_cast_always_succeeds_highlighting=error +resharper_unassigned_field_global_highlighting=none +resharper_unused_auto_property_accessor_global_highlighting=none +resharper_unused_auto_property_accessor_local_highlighting=none +resharper_unused_label_highlighting=error +resharper_unused_local_function_parameter_highlighting=error +resharper_unused_member_global_highlighting=none +resharper_unused_member_in_super_global_highlighting=none +resharper_unused_member_local_highlighting=none +resharper_unused_method_return_value_global_highlighting=none +resharper_unused_method_return_value_local_highlighting=none +resharper_unused_parameter_global_highlighting=error +resharper_unused_parameter_in_partial_method_highlighting=error +resharper_unused_parameter_local_highlighting=hint +resharper_unused_type_global_highlighting=none +resharper_unused_type_parameter_highlighting=error +resharper_unused_variable_compiler_highlighting=error +resharper_use_collection_count_property_highlighting=error +resharper_use_format_specifier_in_interpolation_highlighting=error +resharper_use_index_from_end_expression_highlighting=error +resharper_use_nameof_expression_highlighting=error +resharper_use_negated_pattern_matching_highlighting=error +resharper_use_null_propagation_highlighting=error +resharper_use_null_propagation_when_possible_highlighting=error +resharper_use_object_or_collection_initializer_highlighting=error +resharper_use_pattern_matching_highlighting=error +resharper_use_string_interpolation_highlighting=error +resharper_vb_warnings_bc42358_highlighting=error +resharper_virtual_member_call_in_constructor_highlighting=error +resharper_virtual_member_never_overridden_global_highlighting=none diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index f3d5c41..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: bug -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - -**Additional context** -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 11fc491..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: enhancement -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/UnitTests.yml b/.github/workflows/UnitTests.yml deleted file mode 100644 index 9555683..0000000 --- a/.github/workflows/UnitTests.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: Unit Tests - -on: [push, pull_request, release] - -jobs: - test: - - runs-on: [windows-latest] - - steps: - - uses: actions/checkout@v2 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.0.100 - - name: Run Unit Tests - run: dotnet test diff --git a/.github/workflows/dotnetcore.yml b/.github/workflows/dotnetcore.yml deleted file mode 100644 index ffa5053..0000000 --- a/.github/workflows/dotnetcore.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: .NET Core - -on: [push, pull_request, release] - -jobs: - build: - - runs-on: ${{matrix.os}} - strategy: - matrix: - os: [ubuntu-latest, windows-latest] - - steps: - - uses: actions/checkout@v1 - - name: Setup .NET Core - uses: actions/setup-dotnet@v1 - with: - dotnet-version: 3.0.100 - - name: Build with dotnet - run: dotnet build --configuration Release diff --git a/ConsoleTest/ConsoleTest.csproj b/ConsoleTest/ConsoleTest.csproj index c56caf6..446507c 100644 --- a/ConsoleTest/ConsoleTest.csproj +++ b/ConsoleTest/ConsoleTest.csproj @@ -2,9 +2,20 @@ Exe - netcoreapp3.0 + netcoreapp3.1 + + DEBUG;TRACE + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/ConsoleTest/ConsoleTest.csproj.DotSettings b/ConsoleTest/ConsoleTest.csproj.DotSettings new file mode 100644 index 0000000..934da69 --- /dev/null +++ b/ConsoleTest/ConsoleTest.csproj.DotSettings @@ -0,0 +1,3 @@ + + CSharp80 + True \ No newline at end of file diff --git a/ConsoleTest/GlobalSuppressions.cs b/ConsoleTest/GlobalSuppressions.cs new file mode 100644 index 0000000..0d3e549 --- /dev/null +++ b/ConsoleTest/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( "Style", "IDE0049:Use framework type", Justification = "Samyeak prefers int and not Int32" )] \ No newline at end of file diff --git a/ConsoleTest/Program.cs b/ConsoleTest/Program.cs index fe1f2cd..09abfac 100644 --- a/ConsoleTest/Program.cs +++ b/ConsoleTest/Program.cs @@ -1,20 +1,21 @@ -using NumericWordsConversion; -using System; +namespace ConsoleTest { + + using System; + using NumericWordsConversion; + + public static class Program { + + public static void Main() { + + var converter = new CurrencyWordsConverter(); + const Decimal number = 123_000M; + var words = converter.ToWords( number ); -namespace ConsoleTest -{ - class Program - { - static void Main(string[] args) - { - - CurrencyWordsConverter converter = new CurrencyWordsConverter(); - decimal number = 123_000M; - string words = converter.ToWords(number); //words = number.To - Console.WriteLine(words); + Console.WriteLine( words ); Console.ReadKey(); } } -} + +} \ No newline at end of file diff --git a/LICENSE b/LICENSE.md similarity index 100% rename from LICENSE rename to LICENSE.md diff --git a/NumericWordsConversion.sln b/NumericWordsConversion.sln index bf6845f..3660928 100644 --- a/NumericWordsConversion.sln +++ b/NumericWordsConversion.sln @@ -9,6 +9,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests", "UnitTests\Unit EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConsoleTest", "ConsoleTest\ConsoleTest.csproj", "{1CD938FE-2CE9-483F-A4BB-9E099BA7D76F}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AE79A339-4701-418D-9516-2097ED979A52}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU diff --git a/NumericWordsConversion/ConversionFactory.cs b/NumericWordsConversion/ConversionFactory.cs index 57819ae..90e5e13 100644 --- a/NumericWordsConversion/ConversionFactory.cs +++ b/NumericWordsConversion/ConversionFactory.cs @@ -1,121 +1,133 @@ -using System; -using System.Globalization; -using System.Text; -using static System.String; - -namespace NumericWordsConversion -{ - /// - /// Used to simply map numbers with their respective words output as per the specified options - /// - internal class ConversionFactory - { - private readonly NumericWordsConversionOptions _options; +namespace NumericWordsConversion { + + using System; + using System.Globalization; + using System.Text; + using JetBrains.Annotations; + using static System.String; + + /// Used to simply map numbers with their respective words output as per the specified options + internal class ConversionFactory { + private readonly string[] _ones; - private readonly string[] _tens; + + internal readonly NumericWordsConversionOptions _options; + private readonly string[] _scale; - public ConversionFactory(NumericWordsConversionOptions options) - { - _options = options; - Utilities.ManageSuitableResources(out _ones, out _tens, out _scale, options); + private readonly string[] _tens; + + public ConversionFactory( NumericWordsConversionOptions options ) { + this._options = options; + Utilities.ManageSuitableResources( out this._ones, out this._tens, out this._scale, options ); } - public ConversionFactory(NumericWordsConversionOptions options, string[] ones, string[] tens, string[] scale) - { - _options = options; - _ones = ones; - _tens = tens; - _scale = scale; + + public ConversionFactory( NumericWordsConversionOptions options, string[] ones, string[] tens, string[] scale ) { + this._options = options; + this._ones = ones; + this._tens = tens; + this._scale = scale; } - internal string ToOnesWords(ushort digit) => _ones[digit]; + [NotNull] + internal string ToOnesWords( ushort digit ) => this._ones[ digit ]; + + [NotNull] + internal string ToTensWord( string tenth ) { + int dec = Convert.ToUInt16( tenth, CultureInfo.InvariantCulture ); + + if ( dec <= 0 ) { + return Empty; + } - internal string ToTensWord(string tenth) - { - int dec = Convert.ToUInt16(tenth, CultureInfo.InvariantCulture); - if (dec <= 0) return Empty; string words; - if (dec < _options.ResourceLimitIndex) - { - words = _ones[dec]; + if ( dec < this._options.ResourceLimitIndex ) { + words = this._ones[ dec ]; } - else - { - if (dec % 10 == 0) - { - words = _tens[dec / 10]; + else { + if ( dec % 10 == 0 ) { + words = this._tens[ dec / 10 ]; } - else - { - int first = Convert.ToUInt16(tenth.Substring(0, 1), CultureInfo.InvariantCulture); - int second = Convert.ToUInt16(tenth.Substring(1, 1), CultureInfo.InvariantCulture); - words = Concat(_tens[first], " ", _ones[second]); + else { + int first = Convert.ToUInt16( tenth.Substring( 0, 1 ), CultureInfo.InvariantCulture ); + int second = Convert.ToUInt16( tenth.Substring( 1, 1 ), CultureInfo.InvariantCulture ); + words = $"{this._tens[ first ]} {this._ones[ second ]}"; } } return words; } - internal string ToHundredthWords(string hundred) - { - string inWords = Empty; - if (hundred.Length == 3) - { - int hundredth = Convert.ToInt16(hundred.Substring(0, 1), CultureInfo.InvariantCulture); - inWords = hundredth > 0 ? Concat(_ones[hundredth], " ", _scale[1], " ") : Empty; - hundred = hundred.Substring(1, 2); + [NotNull] + internal string ToHundredthWords( string hundred ) { + var inWords = Empty; + + if ( hundred.Length == 3 ) { + int hundredth = Convert.ToInt16( hundred.Substring( 0, 1 ), CultureInfo.InvariantCulture ); + inWords = hundredth > 0 ? $"{this._ones[ hundredth ]} {this._scale[ 1 ]} " : Empty; + hundred = hundred.Substring( 1, 2 ); } - inWords += ToTensWord(hundred); + + inWords += this.ToTensWord( hundred ); + return inWords.Trim(); } - /// - /// Responsible for converting any input digits to words - /// + /// Responsible for converting any input digits to words /// - /// - internal string ConvertDigits(string digits) - { - if (digits == "0") return _ones[0]; - StringBuilder builder = new StringBuilder(); + internal string ConvertDigits( string digits ) { + if ( digits == "0" ) { + return this._ones[ 0 ]; + } + + var builder = new StringBuilder(); int scaleMapIndex; - if (_options.Culture == Culture.International) - scaleMapIndex = (int)Math.Ceiling((decimal)digits.Length / 3); - else - scaleMapIndex = (digits.Length - 3) < 1 ? 1 : digits.Length / 2; - for (int i = scaleMapIndex; i > 0; i--) - { + + if ( this._options.Culture == Culture.International ) { + scaleMapIndex = ( int ) Math.Ceiling( ( decimal ) digits.Length / 3 ); + } + else { + scaleMapIndex = digits.Length - 3 < 1 ? 1 : digits.Length / 2; + } + + for ( var i = scaleMapIndex; i > 0; i-- ) { string inWords; - switch (i) - { + + switch ( i ) { case 1: //For the Hundreds, tens and ones - inWords = ToHundredthWords(digits); - if (!IsNullOrEmpty(inWords)) - builder.Append(Concat(inWords.Trim(), " ")); + inWords = this.ToHundredthWords( digits ); + + if ( !IsNullOrEmpty( inWords ) ) { + builder.Append( $"{inWords.Trim()} " ); + } + break; default: //For Everything Greater than hundreds - if (_options.Culture == Culture.International) - { - int length = (digits.Length % ((i - 1) * 3 + 1)) + 1; - string hundreds = digits.Substring(0, length); - digits = digits.Remove(0, length); - inWords = ToHundredthWords(hundreds); + if ( this._options.Culture == Culture.International ) { + var length = (digits.Length % ( (( i - 1 ) * 3) + 1 )) + 1; //TODO magic numbers + var hundreds = digits.Substring( 0, length ); + digits = digits.Remove( 0, length ); + inWords = this.ToHundredthWords( hundreds ); } - else - { - int length = (digits.Length % 2 == 0) ? 1 : 2; - string hundreds = digits.Substring(0, length); - digits = digits.Remove(0, length); - inWords = ToTensWord(hundreds); + else { + var length = digits.Length % 2 == 0 ? 1 : 2; //TODO magic numbers + var hundreds = digits.Substring( 0, length ); + digits = digits.Remove( 0, length ); + inWords = this.ToTensWord( hundreds ); + } + + if ( !IsNullOrEmpty( inWords.Trim() ) ) { + builder.Append( $"{inWords.Trim()} {this._scale[ i ]} " ); } - if (!IsNullOrEmpty(inWords.Trim())) - builder.Append(Concat(inWords.Trim(), " ", _scale[i], " ")); break; } } + return builder.ToString().Trim(); } + } -} + +} \ No newline at end of file diff --git a/NumericWordsConversion/CurrencyWordsConversionOptions.cs b/NumericWordsConversion/CurrencyWordsConversionOptions.cs index 1b41904..714718c 100644 --- a/NumericWordsConversion/CurrencyWordsConversionOptions.cs +++ b/NumericWordsConversion/CurrencyWordsConversionOptions.cs @@ -1,79 +1,87 @@ -namespace NumericWordsConversion -{ - /// - /// Options to be used for converting currency number to words. - /// - public class CurrencyWordsConversionOptions : NumericWordsConversionOptions - { - /// - /// Unit of Currency to be concatenated with output - /// If null, uses the default unit as per specified culture if available +namespace NumericWordsConversion { + + using System; + + /// Options to be used for converting currency number to words. + public class CurrencyWordsConversionOptions : NumericWordsConversionOptions { + + private string? _currencyUnit; + + private string? _endOfWordsMarker; + + private string? _subCurrencyUnit; + + public int CacheLimit { get; set; } = 1024 * 1024; + + /// Defines whether the Currency Unit must be appended before or after the words
Default: Postfix + /// Example: Prefix => Rupees one; Postfix => One rupees + ///
+ public NotationType CurrencyNotationType { get; set; } = NotationType.Postfix; + + /// Unit of Currency to be concatenated with output If null, uses the default unit as per specified culture if available /// Example: Dollar, Rupees, रूपैंया, Pound, etc /// - public string CurrencyUnit - { - get - { - if (_currencyUnit != null) return _currencyUnit; - WordResources.CurrencyDefaults.TryGetValue((Culture, OutputFormat), out var units); - _currencyUnit = units.CurrencyUnit; - return _currencyUnit; + public string CurrencyUnit { + get { + if ( this._currencyUnit != null ) { + return this._currencyUnit; + } + + WordResources.CurrencyDefaults.TryGetValue( ( this.Culture, this.OutputFormat ), out var units ); + this._currencyUnit = units.CurrencyUnit; + + return this._currencyUnit; } - set => _currencyUnit = value; + + set => this._currencyUnit = value; } - private string _currencyUnit; - /// - /// Sub Unit of Currency to be concatenated with output - /// If null, uses the default unit as per specified culture if available - /// Example: Cents, Paisa, पैसा, penny, etc + /// Currency Unit Separator
Default: Empty + /// Example: One rupees and ten paisa only ///
- public string SubCurrencyUnit - { - get - { - if (_subCurrencyUnit != null) return _subCurrencyUnit; - WordResources.CurrencyDefaults.TryGetValue((Culture, OutputFormat), out var units); - _subCurrencyUnit = units.SubCurrencyUnit; - return _subCurrencyUnit; - } - set => _subCurrencyUnit = value; - } - private string _subCurrencyUnit; - /// - /// Word appended at end of the sentence. + public string CurrencyUnitSeparator { get; set; } = String.Empty; + + /// Word appended at end of the sentence. /// Example: One rupees only /// - public string EndOfWordsMarker - { - get - { - if (_endOfWordsMarker != null) return _endOfWordsMarker; - WordResources.CurrencyDefaults.TryGetValue((Culture, OutputFormat), out var units); - _endOfWordsMarker = units.EndOfWordsMarker; - return _endOfWordsMarker; + public string EndOfWordsMarker { + get { + if ( this._endOfWordsMarker != null ) { + return this._endOfWordsMarker; + } + + WordResources.CurrencyDefaults.TryGetValue( ( this.Culture, this.OutputFormat ), out var units ); + this._endOfWordsMarker = units.EndOfWordsMarker; + + return this._endOfWordsMarker; } - set => _endOfWordsMarker = value; + + set => this._endOfWordsMarker = value; } - private string _endOfWordsMarker; - /// - /// Defines whether the Currency Unit must be appended before or after the words - ///
Default: Postfix - /// Example: Prefix => Rupees one; Postfix => One rupees - ///
- public NotationType CurrencyNotationType { get; set; } = NotationType.Postfix; - /// - /// Defines whether the Sub Currency Unit must be appended before or after the words - ///
Default: Postfix + /// Defines whether the Sub Currency Unit must be appended before or after the words
Default: Postfix /// Example: Prefix => Paisa one; Postfix => One paisa ///
public NotationType SubCurrencyNotationType { get; set; } = NotationType.Postfix; - /// - /// Currency Unit Separator - ///
Default: Empty - /// Example: One rupees and ten paisa only + + /// Sub Unit of Currency to be concatenated with output If null, uses the default unit as per specified culture if available + /// Example: Cents, Paisa, पैसा, penny, etc /// - public string CurrencyUnitSeparator { get; set; } = string.Empty; + public string SubCurrencyUnit { + get { + if ( this._subCurrencyUnit != null ) { + return this._subCurrencyUnit; + } + + WordResources.CurrencyDefaults.TryGetValue( ( this.Culture, this.OutputFormat ), out var units ); + this._subCurrencyUnit = units.SubCurrencyUnit; + + return this._subCurrencyUnit; + } + + set => this._subCurrencyUnit = value; + } + } -} + +} \ No newline at end of file diff --git a/NumericWordsConversion/CurrencyWordsConverter.cs b/NumericWordsConversion/CurrencyWordsConverter.cs index a18c6b1..0449395 100644 --- a/NumericWordsConversion/CurrencyWordsConverter.cs +++ b/NumericWordsConversion/CurrencyWordsConverter.cs @@ -1,78 +1,87 @@ -namespace NumericWordsConversion -{ +namespace NumericWordsConversion { + + using System; + using System.Collections.Concurrent; using System.Globalization; using System.Linq; + using JetBrains.Annotations; using static System.String; - public class CurrencyWordsConverter - { - private readonly ConversionFactory _conversionFactory; - private readonly CurrencyWordsConversionOptions _options; - #region Constructors + public class CurrencyWordsConverter { /// - /// Creates an instance of NumberConverter with default options - ///
Culture: International, OutputFormat: English, DecimalPlaces : 2 + /// This cache seems to have cut the UnitTests run length in half (25ms instead of 54ms). ///
- public CurrencyWordsConverter() - { - this._options = GlobalOptions.CurrencyWordsOptions; - _conversionFactory = Utilities.InitializeConversionFactory(_options); - } + [NotNull] + private ConcurrentDictionary Cache { get; } = new ConcurrentDictionary(); - /// - /// Creates an instance of NumberConverter with specified options + [NotNull] + private ConversionFactory ConversionFactory { get; } + + [NotNull] + private CurrencyWordsConversionOptions Options { get; } + + /// Creates an instance of NumberConverter with specified options. + /// Default options: Culture: International, OutputFormat: English, DecimalPlaces : 2 /// - public CurrencyWordsConverter(CurrencyWordsConversionOptions options) - { - this._options = options; - _conversionFactory = Utilities.InitializeConversionFactory(_options); + public CurrencyWordsConverter( [CanBeNull] CurrencyWordsConversionOptions? options = null ) { + this.Options = options ?? GlobalOptions.CurrencyWordsOptions; + this.ConversionFactory = Utilities.InitializeConversionFactory( this.Options ); } - #endregion - /// - /// Converts to words as per defined option - /// + /// Converts to words as per defined option /// - /// - public string ToWords(decimal number) - { - if (number <= 0) return Empty; - decimal fractionalDigits = number % 1; - string integralDigitsString = number - .ToString(CultureInfo.InvariantCulture) - .Split('.') - .ElementAt(0); - string fractionalDigitsString = fractionalDigits.ToString(_options.DecimalPlaces > -1 ? $"F{_options.DecimalPlaces}" : "G", - CultureInfo.InvariantCulture) - .Split('.') - .ElementAtOrDefault(1) ?? Empty; - if (decimal.Parse(integralDigitsString) <= 0 && decimal.Parse(fractionalDigitsString) <= 0) return Empty; - - string integralWords = Empty; - if (decimal.Parse(integralDigitsString) > 0) - { - integralWords = _conversionFactory.ConvertDigits(integralDigitsString); - integralWords = _options.CurrencyNotationType == NotationType.Prefix - ? _options.CurrencyUnit + " " + integralWords - : integralWords + " " + _options.CurrencyUnit; + [NotNull] + public string ToWords( decimal number ) { + + //TODO Add in a ConcurrentDictionary cache, self-limiting so it doesn't eat up too much memory. + if ( this.Cache.TryGetValue( number, out var result ) && !IsNullOrWhiteSpace( result ) ) { + return result; + } + + if ( number <= 0 ) { + return Empty; //TODO Add support for negative numbers and zero! + } + + var fractionalDigits = number % 1; + var integralDigitsString = number.ToString( CultureInfo.InvariantCulture ).Split( '.' ).ElementAt( 0 ); + + var fractionalDigitsString = fractionalDigits.ToString( this.Options.DecimalPlaces > -1 ? $"F{this.Options.DecimalPlaces}" : "G", CultureInfo.InvariantCulture ) + .Split( '.' ).ElementAtOrDefault( 1 ) ?? Empty; + + if ( Decimal.Parse( integralDigitsString ) <= 0 && Decimal.Parse( fractionalDigitsString ) <= 0 ) { + return Empty; } - if (int.Parse(fractionalDigitsString) <= 0 || IsNullOrEmpty(fractionalDigitsString)) return Concat(integralWords, (IsNullOrEmpty(_options.EndOfWordsMarker) ? "" : " " + _options.EndOfWordsMarker)).CapitalizeFirstLetter(); + var integralWords = Empty; - string fractionalWords = _conversionFactory.ConvertDigits(fractionalDigitsString); - fractionalWords = _options.SubCurrencyNotationType == NotationType.Prefix - ? _options.SubCurrencyUnit + " " + fractionalWords - : fractionalWords + " " + _options.SubCurrencyUnit; + if ( Decimal.Parse( integralDigitsString ) > 0 ) { + integralWords = this.ConversionFactory.ConvertDigits( integralDigitsString ); - fractionalWords = ( - $"{integralWords} " + - $"{(IsNullOrEmpty(_options.CurrencyUnitSeparator) ? "" : _options.CurrencyUnitSeparator + " ")}" + - $"{fractionalWords.TrimEnd()}{(IsNullOrEmpty(_options.EndOfWordsMarker) ? "" : " " + _options.EndOfWordsMarker)}") - .Trim().CapitalizeFirstLetter(); + integralWords = this.Options.CurrencyNotationType == NotationType.Prefix ? + $"{this.Options.CurrencyUnit} {integralWords}" : + $"{integralWords} {this.Options.CurrencyUnit}"; + } + + if ( Int32.Parse( fractionalDigitsString ) <= 0 || IsNullOrEmpty( fractionalDigitsString ) ) { + result = Concat( integralWords, IsNullOrEmpty( this.Options.EndOfWordsMarker ) ? "" : $" {this.Options.EndOfWordsMarker}" ).CapitalizeFirstLetter(); - return fractionalWords; + return this.Cache[ number ] = result; + } + var fractionalWords = this.ConversionFactory.ConvertDigits( fractionalDigitsString ); + + fractionalWords = this.Options.SubCurrencyNotationType == NotationType.Prefix ? + $"{this.Options.SubCurrencyUnit} {fractionalWords}" : + $"{fractionalWords} {this.Options.SubCurrencyUnit}"; + + fractionalWords = ( $"{integralWords} " + $"{( IsNullOrEmpty( this.Options.CurrencyUnitSeparator ) ? "" : $"{this.Options.CurrencyUnitSeparator} " )}" + + $"{fractionalWords.TrimEnd()}{( IsNullOrEmpty( this.Options.EndOfWordsMarker ) ? "" : $" {this.Options.EndOfWordsMarker}" )}" ).Trim() + .CapitalizeFirstLetter(); + + return this.Cache[ number ] = fractionalWords; } + } + } \ No newline at end of file diff --git a/NumericWordsConversion/ExtensionHelper.cs b/NumericWordsConversion/ExtensionHelper.cs index b8b04f1..57b0548 100644 --- a/NumericWordsConversion/ExtensionHelper.cs +++ b/NumericWordsConversion/ExtensionHelper.cs @@ -1,16 +1,15 @@ namespace NumericWordsConversion { + + using JetBrains.Annotations; + public static class ExtensionHelper { - public static string ToNumericWords(this decimal amount) - { - return GlobalOptions.NumericWordsConverter.ToWords(amount); - } + [NotNull] + public static string ToNumericWords(this decimal amount) => GlobalOptions.NumericWordsConverter.ToWords(amount); - public static string ToCurrencyWords(this decimal amount) - { - return GlobalOptions.CurrencyWordsConverter.ToWords(amount); - } + [NotNull] + public static string ToCurrencyWords(this decimal amount) => GlobalOptions.CurrencyWordsConverter.ToWords(amount); } } diff --git a/NumericWordsConversion/GlobalSuppressions.cs b/NumericWordsConversion/GlobalSuppressions.cs new file mode 100644 index 0000000..5f9a853 --- /dev/null +++ b/NumericWordsConversion/GlobalSuppressions.cs @@ -0,0 +1,9 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( "Style", "IDE0049:Use framework type", Justification = "Samyeak prefers int and not Int32" )] +[assembly: SuppressMessage( "Style", "IDE0047:Remove unnecessary parentheses", Justification = "" )] \ No newline at end of file diff --git a/NumericWordsConversion/NumericWordsConfiguration.cs b/NumericWordsConversion/NumericWordsConfiguration.cs index f0bbd05..29f2b03 100644 --- a/NumericWordsConversion/NumericWordsConfiguration.cs +++ b/NumericWordsConversion/NumericWordsConfiguration.cs @@ -1,64 +1,69 @@ -using System; - -namespace NumericWordsConversion -{ - /// - /// Configuration Manager for Words Conversion - /// - public static class NumericWordsConfiguration - { - /// - /// Configure Default Conversion Options for words conversion - /// - /// Define options for numeric or currency words - public static void ConfigureConversionDefaults(Action options) - { - if (options == null) throw new NullReferenceException("Numeric Words Options Initializer Option cannot be null"); +namespace NumericWordsConversion { + + using System; + using JetBrains.Annotations; + + public static class GlobalOptions { + + [NotNull] + public static CurrencyWordsConverter CurrencyWordsConverter { get; internal set; } + + /// Default option used for conversion if no explicit option during conversion or initialization of CurrencyWords + [NotNull] + public static CurrencyWordsConversionOptions CurrencyWordsOptions { get; internal set; } + + [NotNull] + public static NumericWordsConverter NumericWordsConverter { get; internal set; } - OptionsInitializer initializer = new OptionsInitializer(); - options.Invoke(initializer); + /// Default option used for conversion if no explicit option during conversion or initialization of NumericWords + [NotNull] + public static NumericWordsConversionOptions NumericWordsOptions { get; internal set; } + + static GlobalOptions() { + + //Initializing these in the ctor allows for the code lines to reformatted without causing order of initialization issues. + CurrencyWordsOptions = new CurrencyWordsConversionOptions(); + CurrencyWordsConverter = new CurrencyWordsConverter( CurrencyWordsOptions ); + NumericWordsOptions = new NumericWordsConversionOptions(); + NumericWordsConverter = new NumericWordsConverter( NumericWordsOptions ); } } - public static class GlobalOptions - { - /// - /// Default option used for conversion if no explicit option during conversion or initialization of NumericWords - /// - public static NumericWordsConversionOptions NumericWordsOptions { get; internal set; } = new NumericWordsConversionOptions(); - /// - /// Default option used for conversion if no explicit option during conversion or initialization of CurrencyWords - /// - public static CurrencyWordsConversionOptions CurrencyWordsOptions { get; internal set; } = new CurrencyWordsConversionOptions(); - - public static NumericWordsConverter NumericWordsConverter { get; internal set; } = new NumericWordsConverter(NumericWordsOptions); - - public static CurrencyWordsConverter CurrencyWordsConverter { get; internal set; } = new CurrencyWordsConverter(CurrencyWordsOptions); -} - - public class OptionsInitializer - { - - /// - /// Configures default options to be used while converting numeric to words. - /// Uses default options if assigned null - /// - /// Options for Numeric Words Conversion - public void SetDefaultNumericWordsOptions(NumericWordsConversionOptions numericWordsOptions) - { - GlobalOptions.NumericWordsOptions = numericWordsOptions ?? new NumericWordsConversionOptions(); - GlobalOptions.NumericWordsConverter = new NumericWordsConverter(GlobalOptions.NumericWordsOptions); + + /// Configuration Manager for Words Conversion + public static class NumericWordsConfiguration { + + /// Configure Default Conversion Options for words conversion + /// Define options for numeric or currency words + public static void ConfigureConversionDefaults( [NotNull] Action options ) { + if ( options == null ) { + throw new NullReferenceException( "Numeric Words Options Initializer Option cannot be null" ); + } + + var initializer = new OptionsInitializer(); + options.Invoke( initializer ); //TODO Using an Action here feels wrong.. } - /// - /// Configures default options to be used while converting currency to words. - /// Uses default options if assigned null - /// + } + + public class OptionsInitializer { + + //TODO This class should be static or entirely removed. + + /// Configures default options to be used while converting currency to words. Uses default options if assigned null /// - public void SetDefaultCurrencyWordsOptions(CurrencyWordsConversionOptions currencyWordsOptions) - { + public static void SetDefaultCurrencyWordsOptions( [CanBeNull] CurrencyWordsConversionOptions currencyWordsOptions ) { GlobalOptions.CurrencyWordsOptions = currencyWordsOptions ?? new CurrencyWordsConversionOptions(); - GlobalOptions.CurrencyWordsConverter = new CurrencyWordsConverter(GlobalOptions.CurrencyWordsOptions); + GlobalOptions.CurrencyWordsConverter = new CurrencyWordsConverter( GlobalOptions.CurrencyWordsOptions ); } + + /// Configures default options to be used while converting numeric to words. Uses default options if assigned null + /// Options for Numeric Words Conversion + public static void SetDefaultNumericWordsOptions( [CanBeNull] NumericWordsConversionOptions numericWordsOptions ) { + GlobalOptions.NumericWordsOptions = numericWordsOptions ?? new NumericWordsConversionOptions(); + GlobalOptions.NumericWordsConverter = new NumericWordsConverter( GlobalOptions.NumericWordsOptions ); + } + } -} + +} \ No newline at end of file diff --git a/NumericWordsConversion/NumericWordsConversion.csproj b/NumericWordsConversion/NumericWordsConversion.csproj index 06e40c4..51693fe 100644 --- a/NumericWordsConversion/NumericWordsConversion.csproj +++ b/NumericWordsConversion/NumericWordsConversion.csproj @@ -1,14 +1,14 @@  - netcoreapp3.0 + netcoreapp3.1 true Samyeak Maharjan - Numeric Words Conversion is a C# library for converting numeric into words. The goal is to create a simple customizable library which can easily be used to convert any numbers or currencies to words. Supports Nepali, Hindi and International Numeral System out of the box. + Numeric Words Conversion is a C# library for converting numeric into words. The goal is to create a simple customizable library which can easily be used to convert any numbers or currencies to words. Supports Nepali, Hindi, and International Numeral System out of the box. Samyeak Maharjan en 2.0.0.0 - LICENSE + LICENSE.md https://github.com/Samyeak/NumericWordsConversion.git https://github.com/Samyeak/NumericWordsConversion.git github @@ -20,17 +20,28 @@ NumericWordsConversionSignatureKey.snk false https://repository-images.githubusercontent.com/233162696/d06bb100-4545-11ea-8853-f816e055791a + enable - true + false + DEBUG;TRACE - + + True + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/NumericWordsConversion/NumericWordsConversion.csproj.DotSettings b/NumericWordsConversion/NumericWordsConversion.csproj.DotSettings new file mode 100644 index 0000000..846d678 --- /dev/null +++ b/NumericWordsConversion/NumericWordsConversion.csproj.DotSettings @@ -0,0 +1,3 @@ + + Latest + True \ No newline at end of file diff --git a/NumericWordsConversion/NumericWordsConversionOptions.cs b/NumericWordsConversion/NumericWordsConversionOptions.cs index 5953f1e..e821d9f 100644 --- a/NumericWordsConversion/NumericWordsConversionOptions.cs +++ b/NumericWordsConversion/NumericWordsConversionOptions.cs @@ -1,61 +1,86 @@ -using System; - -namespace NumericWordsConversion -{ - /// - /// Options to be used for converting number to words. - ///
For currency please use CurrencyWordsConversionOptions - ///
- public class NumericWordsConversionOptions - { - /// - /// The culture to be used in order to convert the number to words. - /// Default value: International
- ///
- public Culture Culture { get; set; } = Culture.International; +namespace NumericWordsConversion { + + using System; + using System.ComponentModel; + using JetBrains.Annotations; + + /// Options to be used for converting number to words.
For currency please use CurrencyWordsConversionOptions
+ public class NumericWordsConversionOptions { + + [CanBeNull] + private readonly string? _decimalSeparator; + + /// In order to use generic algorithm for all the numeral system, this is used to map suitable resources as per different numeral system. + internal int ResourceLimitIndex => this.OutputFormat == OutputFormat.English ? 20 : 100; + + /// The culture to be used in order to convert the number to words. Default value: International
+ public Culture Culture { get; set; } + /// - /// Has control over the string format of the output words. - ///
Default value: English - ///
Output Format depends upon the culture specified. + /// Number of digits after decimal point.
Default Value: 2
Assign -1 to support all provided decimal values
Excessive values than the specified digits will + /// be truncated ///
- public OutputFormat OutputFormat { get; set; } = OutputFormat.English; + public int DecimalPlaces { get; set; } - /// - /// Number of digits after decimal point.
- /// Default Value: 2
- /// Assign -1 to support all provided decimal values
- /// Excessive values than the specified digits will be truncated + //International English + + /// Has control over the string format of the output words. + /// Default value: English + /// Output Format depends upon the culture specified. /// - public int DecimalPlaces { get; set; } = 2; + public OutputFormat OutputFormat { get; set; } - /// - /// Separator to be placed between numbers and their decimal values
- /// Default value differs wrt Culture and Output Format
- /// Assign an empty string to ignore the separator
- /// Uses default separator if null + public const String DefaultDecimalSeparator = "point"!; + + public NumericWordsConversionOptions( OutputFormat? format = null, Culture? culture = null, int? decimalPlaces = 2, [CanBeNull] String? defaultDecimalSeparator = null ) { + if ( format != null && !Enum.IsDefined( enumType: typeof( OutputFormat ), value: format.Value ) ) { + throw new InvalidEnumArgumentException( argumentName: nameof( format ), invalidValue: ( Int32 ) format, enumClass: typeof( OutputFormat ) ); + } + + if ( culture != null && !Enum.IsDefined( enumType: typeof( Culture ), value: culture.Value ) ) { + throw new InvalidEnumArgumentException( argumentName: nameof( culture ), invalidValue: ( Int32 ) culture, enumClass: typeof( Culture ) ); + } + + this.OutputFormat = format ?? OutputFormat.English; + this.Culture = culture ?? Culture.International; + + this.DecimalPlaces = decimalPlaces ?? 2; + + if ( this.DecimalPlaces < 0 ) { + this.DecimalPlaces = 0; + } + else if ( this.DecimalPlaces > 10 ) { + this.DecimalPlaces = 10; //or some other *reasonable* limit. + } + + this._decimalSeparator = defaultDecimalSeparator ?? DefaultDecimalSeparator; + } + + /// Separator to be placed between numbers and their decimal values. + /// Default value differs with Culture and Output Format. + /// Assign an empty string to ignore the separator. + /// Uses default separator if null. /// - public string DecimalSeparator - { - get => _decimalSeparator ?? (Culture, OutputFormat) switch - { - (Culture.International, _) => "point", - (Culture.Nepali, OutputFormat.English) => "point", - (Culture.Nepali, OutputFormat.Devnagari) => "bzdnj", - (Culture.Nepali, OutputFormat.Unicode) => "दशमलव", - (Culture.Hindi, OutputFormat.English) => "point", - (Culture.Hindi, OutputFormat.Devnagari) => "bzdnj", - (Culture.Hindi, OutputFormat.Unicode) => "दशमलव", - _ => throw new ArgumentOutOfRangeException(nameof(Culture)) + [NotNull] + public String GetDecimalSeparator() { + var s = this._decimalSeparator; + + if ( s != null ) { + return s; + } + + return ( this.Culture, this.OutputFormat ) switch { + (Culture.International, OutputFormat.English ) => "point", //changed so if the enum order is changed in the future, then this still defaults to English. + (Culture.Nepali, OutputFormat.English ) => "point", + (Culture.Nepali, OutputFormat.Devnagari ) => "bzdnj", + (Culture.Nepali, OutputFormat.Unicode ) => "दशमलव", + (Culture.Hindi, OutputFormat.English ) => "point", + (Culture.Hindi, OutputFormat.Devnagari ) => "bzdnj", + (Culture.Hindi, OutputFormat.Unicode ) => "दशमलव", + _ => throw new ArgumentOutOfRangeException( $"Combination of {nameof( this.Culture )} {this.Culture:G} format {this.OutputFormat:G} is unknown." ) }; - set => _decimalSeparator = value; } - private string _decimalSeparator; - - /// - /// In order to use generic algorithm for all the numeral system, - /// this is used to map suitable resources as per different numeral system - /// - internal int ResourceLimitIndex => this.OutputFormat == OutputFormat.English ? 20 : 100; } + } \ No newline at end of file diff --git a/NumericWordsConversion/NumericWordsConverter.cs b/NumericWordsConversion/NumericWordsConverter.cs index 9538a03..137c439 100644 --- a/NumericWordsConversion/NumericWordsConverter.cs +++ b/NumericWordsConversion/NumericWordsConverter.cs @@ -1,70 +1,71 @@ -using System; -using System.Globalization; -using System.Linq; -using static System.String; - -namespace NumericWordsConversion -{ - /// - /// Used to convert number to words - /// For Currency: Use CurrencyWordsConverter> - /// - public class NumericWordsConverter - { +namespace NumericWordsConversion { + + using System; + using System.Collections.Concurrent; + using System.Globalization; + using System.Linq; + using JetBrains.Annotations; + using static System.String; + + /// Used to convert number to words + /// For Currency: Use CurrencyWordsConverter + /// > + public class NumericWordsConverter { + private readonly ConversionFactory _conversionFactory; + private readonly NumericWordsConversionOptions _options; - #region Constructors + private ConcurrentDictionary Cache { get; } = new ConcurrentDictionary(); - /// - /// Creates an instance of NumberConverter with default options - ///
Culture: International, OutputFormat: English, DecimalPlaces : 2 + /// Creates an instance of NumberConverter with default options. + /// Culture: International, OutputFormat: English, DecimalPlaces : 2 /// - public NumericWordsConverter() - { + public NumericWordsConverter() { this._options = GlobalOptions.NumericWordsOptions; - _conversionFactory = Utilities.InitializeConversionFactory(_options); + this._conversionFactory = Utilities.InitializeConversionFactory( this._options ); } - /// - /// Creates an instance of NumberConverter with specified options - /// - public NumericWordsConverter(NumericWordsConversionOptions options) - { - this._options = options; - _conversionFactory = Utilities.InitializeConversionFactory(_options); + /// Creates an instance of NumberConverter with specified options + public NumericWordsConverter( [NotNull] NumericWordsConversionOptions options ) { + this._options = options ?? throw new ArgumentNullException( nameof( options ) ); + this._conversionFactory = Utilities.InitializeConversionFactory( this._options ); } - #endregion - /// - /// Convert number to words as per specified options - /// + /// Convert number to words as per specified options /// - /// - public string ToWords(decimal number) - { - string integralDigitsString = number - .ToString(CultureInfo.InvariantCulture) - .Split('.') - .ElementAt(0); - - decimal fractionalDigits = number % 1; - - string integralWords = _conversionFactory.ConvertDigits(integralDigitsString); - string fractionalDigitsString = (_options.DecimalPlaces > -1 ? decimal.Parse(fractionalDigits.ToString($"F{_options.DecimalPlaces}", CultureInfo.InvariantCulture)) - .ToString($"G{_options.DecimalPlaces}", CultureInfo.InvariantCulture) - : fractionalDigits.ToString("G", CultureInfo.InvariantCulture) - ) - .Split('.') - .ElementAtOrDefault(1); - if (fractionalDigits <= 0 || IsNullOrEmpty(fractionalDigitsString)) return integralWords.CapitalizeFirstLetter(); - - string fractionalWords = Empty; - fractionalDigitsString - .ToList() - .ForEach(x => fractionalWords += _conversionFactory.ToOnesWords(Convert.ToUInt16(x.ToString(CultureInfo.InvariantCulture))) + " "); - - return $"{integralWords} {_options.DecimalSeparator} {fractionalWords.TrimEnd()}".CapitalizeFirstLetter(); + [NotNull] + public string ToWords( decimal number ) { + if ( this.Cache.TryGetValue( number, out var result ) ) { + return result; + } + + var integralDigitsString = number.ToString( CultureInfo.InvariantCulture ).Split( '.' ).ElementAt( 0 ); + + var fractionalDigits = number % 1; + + var integralWords = this._conversionFactory.ConvertDigits( integralDigitsString ); + + var fractionalDigitsString = + ( this._options.DecimalPlaces > -1 ? + Decimal.Parse( fractionalDigits.ToString( $"F{this._options.DecimalPlaces}", CultureInfo.InvariantCulture ) ) + .ToString( $"G{this._options.DecimalPlaces}", CultureInfo.InvariantCulture ) : + fractionalDigits.ToString( "G", CultureInfo.InvariantCulture ) ).Split( '.' ).ElementAtOrDefault( 1 ); + + if ( fractionalDigits <= 0 || IsNullOrEmpty( fractionalDigitsString ) ) { + return integralWords.CapitalizeFirstLetter(); + } + + var fractionalWords = Empty; + + fractionalDigitsString.ToList().ForEach( x => + fractionalWords += $"{this._conversionFactory.ToOnesWords( Convert.ToUInt16( x.ToString( CultureInfo.InvariantCulture ) ) )} " ); + + result = $"{integralWords} {this._options.GetDecimalSeparator()} {fractionalWords.TrimEnd()}".CapitalizeFirstLetter(); + + return this.Cache[ number ] = result; } + } + } \ No newline at end of file diff --git a/NumericWordsConversion/OutputFormat.cs b/NumericWordsConversion/OutputFormat.cs index 830edaa..6b07aef 100644 --- a/NumericWordsConversion/OutputFormat.cs +++ b/NumericWordsConversion/OutputFormat.cs @@ -1,9 +1,13 @@ -namespace NumericWordsConversion -{ - public enum OutputFormat - { +namespace NumericWordsConversion { + + public enum OutputFormat { + English, + Devnagari, + Unicode + } -} + +} \ No newline at end of file diff --git a/NumericWordsConversion/Utilities.cs b/NumericWordsConversion/Utilities.cs index 3cda293..6b5b983 100644 --- a/NumericWordsConversion/Utilities.cs +++ b/NumericWordsConversion/Utilities.cs @@ -1,92 +1,158 @@ -using System; -using System.Globalization; -using System.Linq; - -namespace NumericWordsConversion -{ - internal static class Utilities - { - /// - /// Capitalizes the first letter of input string - /// +namespace NumericWordsConversion { + + using System; + using System.Diagnostics; + using System.Globalization; + using System.Linq; + using System.Runtime.CompilerServices; + using JetBrains.Annotations; + + internal static class Utilities { + + /// Capitalizes the first letter of input string /// /// - internal static string CapitalizeFirstLetter(this string words) - { - if (string.IsNullOrEmpty(words)) throw new ArgumentException("Input string must not be null or empty"); - return words.First().ToString(CultureInfo.InvariantCulture).ToUpper(CultureInfo.InvariantCulture) + words.Substring(1); + [NotNull] + internal static string CapitalizeFirstLetterOld( this string words ) { + if ( String.IsNullOrEmpty( words ) ) { + throw new ArgumentException( "Input string must not be null or empty" ); + } + + return words.First().ToString( CultureInfo.InvariantCulture ).ToUpper( CultureInfo.InvariantCulture ) + words.Substring( 1 ); } - /// - /// Used to initialize the conversion factory as per the specified options - /// + /// Used to initialize the conversion factory as per the specified options /// - internal static ConversionFactory InitializeConversionFactory(NumericWordsConversionOptions options) - { - ManageSuitableResources(out string[] ones, out string[] tens, out string[] scale, options); - return new ConversionFactory(options, ones, tens, scale); + [NotNull] + internal static ConversionFactory InitializeConversionFactory( NumericWordsConversionOptions options ) { + ManageSuitableResources( out var ones, out var tens, out var scale, options ); + + return new ConversionFactory( options, ones, tens, scale ); } - /// - /// Output resources for words conversion as per the specified options - /// + /// Output resources for words conversion as per the specified options /// Output parameter for ones digit /// Output parameter for tens digit /// Output parameter for scale of specified culture /// Options used for resources output - internal static void ManageSuitableResources(out string[] ones, out string[] tens, out string[] scale, NumericWordsConversionOptions options) - { - switch (options.Culture) - { + internal static void ManageSuitableResources( [NotNull] [ItemNotNull] out string[] ones, [NotNull] [ItemNotNull] out string[] tens, + [NotNull] [ItemNotNull] out string[] scale, NumericWordsConversionOptions options ) { + switch ( options.Culture ) { case Culture.Nepali: - switch (options.OutputFormat) - { + switch ( options.OutputFormat ) { case OutputFormat.English: ones = WordResources.OnesEnglish; tens = WordResources.TensEnglish; scale = WordResources.ScaleNepEnglish; + break; + case OutputFormat.Unicode: ones = WordResources.OnesNep; tens = WordResources.TensNep; scale = WordResources.ScaleNep; + break; + case OutputFormat.Devnagari: ones = WordResources.OnesDevnagari; tens = WordResources.TensDevnagari; scale = WordResources.ScaleDevnagari; + break; - default: - throw new ArgumentOutOfRangeException(); + + default: throw new InvalidOperationException( "Invalid value." ); } + break; + case Culture.International: scale = WordResources.ScaleEng; ones = WordResources.OnesEnglish; tens = WordResources.TensEnglish; + break; + case Culture.Hindi: - switch (options.OutputFormat) - { + switch ( options.OutputFormat ) { case OutputFormat.English: ones = WordResources.OnesEnglish; tens = WordResources.TensEnglish; scale = WordResources.ScaleNepEnglish; + break; + case OutputFormat.Unicode: ones = WordResources.OnesHindi; tens = WordResources.TensHindi; scale = WordResources.ScaleHindi; + break; - case OutputFormat.Devnagari: - throw new NotSupportedException("Devnagari Output is not currently supported for Hindi Numeric System"); - default: - throw new ArgumentOutOfRangeException(); + + case OutputFormat.Devnagari: throw new NotSupportedException( "Devnagari Output is not currently supported for Hindi Numeric System" ); + default: throw new InvalidOperationException( "Invalid value."); } + break; - default: - throw new ArgumentOutOfRangeException(nameof(options.Culture), options.Culture, "Invalid Culture in Conversion Options"); + + default: throw new InvalidOperationException( "Invalid Culture in Conversion Options" ); + } + } + + /// Modifies the and makes the first letter capitalized. + /// + [DebuggerStepThrough] + public static void CapitalizeFirstLetter( this Memory memory ) { + if ( memory.IsEmpty ) { + return; } + + ref var first = ref memory.Span[ 0 ]; + first = Char.ToUpper( first, CultureInfo.InvariantCulture ); } + + /// Returns the with the first letter capitalized. + /// + /// + [DebuggerStepThrough] + [NotNull] + [Pure] + public static String CapitalizeFirstLetter( [CanBeNull] this String text ) { + if ( String.IsNullOrEmpty( text ) ) { + return String.Empty; + } + + if ( text.Length == 1 ) { + return Char.ToUpper( text[ 0 ], CultureInfo.InvariantCulture ).ToString( CultureInfo.InvariantCulture ); + } + + return Char.ToUpper( text[ 0 ], CultureInfo.InvariantCulture ) + text.Substring( 1 ); + } + + /// Returns null if is . + /// + /// + [CanBeNull] + [MethodImpl( MethodImplOptions.AggressiveInlining )] + [DebuggerStepThrough] + [Pure] + public static String? NullIfEmpty( [CanBeNull] this String self ) => String.IsNullOrEmpty( self ) ? null : self; + + /// Trim the ToString() of the object; returning null if null, empty, or whitespace. + /// + /// + [DebuggerStepThrough] + [CanBeNull] + [MethodImpl( MethodImplOptions.AggressiveInlining )] + [Pure] + public static String? Trimmed( [CanBeNull] this T self ) { + switch ( self ) { + case null: return null; + case String s: return s.Trim().NullIfEmpty(); + default: return self.ToString()?.Trim().NullIfEmpty(); + } + } + } -} + +} \ No newline at end of file diff --git a/NumericWordsConversion/WordResources.cs b/NumericWordsConversion/WordResources.cs index 0ef5029..03cdc79 100644 --- a/NumericWordsConversion/WordResources.cs +++ b/NumericWordsConversion/WordResources.cs @@ -1,38 +1,30 @@ -using System.Collections.Generic; +namespace NumericWordsConversion { + + using System.Collections.Generic; + using JetBrains.Annotations; + + internal static class WordResources { + + [NotNull] + public static IDictionary<(Culture culture, OutputFormat outputFormat), (string CurrencyUnit, string SubCurrencyUnit, string EndOfWordsMarker)> CurrencyDefaults { + get; + } + = new Dictionary<(Culture culture, OutputFormat outputFormat), (string CurrencyUnit, string SubCurrencyUnit, string EndOfWordsMarker)> + { + {(Culture.International, OutputFormat.English), ("dollar", "cents", "only")}, + {(Culture.Nepali, OutputFormat.English), ("rupees", "paisa", "only")}, + {(Culture.Nepali, OutputFormat.Unicode), ("रूपैयाँ", "पैसा", "मात्र")}, + {(Culture.Nepali, OutputFormat.Devnagari), ("¿k}ofF", "k};f", "dfq")} + //TODO: ADD FOR HINDI + }; -namespace NumericWordsConversion -{ - internal static class WordResources - { /** * Number Notation has been added up to 10^39 * Decimal type supports up to 10^27 */ - public static readonly string[] ScaleEng = { "", "hundred", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion " }; - public static readonly string[] ScaleNep = { "", "सय", "हजार", "लाख", "करोड", "अरब", "खरब", "नील", "पद्म", "शंख", "उपाध", "अंक", "जल्द", "मध", "परर्ध", "अन्त", "महाअन्त", "शिशन्त", "सिंघर", "महासिंहर", "अदन्त सिंहर" }; - public static readonly string[] ScaleNepEnglish = { "", "hundred", "thousand", "lakh", "crore", "arba", "kharba", "neel", "padma", "shankha", "Upadh", "Anka", "Jald", "Madh", "Parardha", "Anta", "Mahaanta", "Shishanta", "Singhar", "Maha Singhar", "Adanta Singhar" }; //Pow(10,39) - public static readonly string[] ScaleDevnagari = { "", ";o", "xhf/", "nfv", "s/f]8", "c/a", "v/a", "gLn", "kß", "z+v", "pkfw", "c+s", "hNb", "dw", "k/w{", "cGt", "dxfcGt", "lzzGt", "l;+3/", "dxfl;+x/", "cbGt l;+x/" }; - public static readonly string[] ScaleHindi = { "", "सौ", "हजार", "लाख", "करोड़", "अरब", "खरब", "नील", "पद्म", "शंख", "उपाध", "अंक", "जल्द", "मध", "परर्ध", "अन्त", "महाअन्त", "शिशन्त", "सिंघर", "महासिंहर", "अदन्त सिंहर" }; - - //ENGLISH WORDS RESOURCE - public static readonly string[] OnesEnglish = { "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen" }; - public static readonly string[] TensEnglish = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; - //NEPALI WORDS RESOURCE - public static readonly string[] TensNep = { "", "दस", "बीस", "तीस", "चालीस", "पचास", "साठी", "सतरी", "अस्सी", "नब्बे" }; - public static readonly string[] TensDevnagari = { "", "b;", "aL;", "tL;", "rfnL;", "krf;", ";f7L", ";t/L", "c:;L", "gAa]" }; - - public static readonly string[] OnesNep = { "सुन्य", "एक", "दुई", "तीन", "चार", "पाँच", "छ", "सात", "आठ", "नौ", "दस", - "एघार", "बाह्र", "तेह्र", "चौध", "पन्ध्र", "सोह्र", "सत्र", "अठाह्र", "उन्नाइस", "बीस", "एकाइस", - "बाइस", "तेइस", "चौबीस", "पचीस", "छब्बीस", "सत्ताइस", "अठ्ठाइस", "उनन्तीस", "तीस", - "एकतीस", "बतीस", "तेतीस", "चौतीस", "पैतीस", "छतीस", "सरतीस", "अरतीस", "उननचालीस", "चालीस", - "एकचालीस", "बयालिस", "तीरचालीस", "चौवालिस", "पैंतालिस", "छयालिस", "सरचालीस", "अरचालीस", "उननचास", "पचास", - "एकाउन्न", "बाउन्न", "त्रिपन्न", "चौवन्न", "पच्पन्न", "छपन्न", "सन्ताउन्न", "अन्ठाउँन्न", "उनान्न्साठी", "साठी", - "एकसाठी", "बासाठी", "तीरसाठी", "चौंसाठी", "पैसाठी", "छैसठी", "सत्सठ्ठी", "अर्सठ्ठी", "उनन्सत्तरी", "सतरी", - "एकहत्तर", "बहत्तर", "त्रिहत्तर", "चौहत्तर", "पचहत्तर", "छहत्तर", "सत्हत्तर", "अठ्हत्तर", "उनास्सी", "अस्सी", - "एकासी", "बयासी", "त्रीयासी", "चौरासी", "पचासी", "छयासी", "सतासी", "अठासी", "उनान्नब्बे", "नब्बे", - "एकान्नब्बे", "बयान्नब्बे", "त्रियान्नब्बे", "चौरान्नब्बे", "पंचान्नब्बे", "छयान्नब्बे", "सन्तान्‍नब्बे", "अन्ठान्नब्बे", "उनान्सय" - }; + //TODO Minor optimization.. these arrays could be converted to Lazy so any unused languages don't have to initialized on startup, only once used. + //TODO Minor adjustment: these arrays could also be moved into static sub-classes Ones() and Tens(). Won't make much difference if no other languages are added in the future. public static readonly string[] OnesDevnagari = { ";'Go", "Ps", "b'O{", "tLg", "rf/", "kfFr", "5", ";ft", "cf7", "gf}", "b;", "P3f/", "afx|", "t]x|", "rf}w", "kG„", ";f]x|", ";q", "c7fx|", "pGgfO;", "aL;", "PsfO;", @@ -46,7 +38,11 @@ internal static class WordResources "PsfGgAa]", "aofGgAa]", "lqofGgAa]", "rf}/fGgAa]", "k+rfGgAa]", "5ofGgAa]", ";GtfG‍gAa]", "cG7fGgAa]", "pgfG;o" }; - public static readonly string[] TensHindi = { "", "दस", "बीस", "तीस", "चालीस", "पचास", "साठ", "सत्तर", "अस्सी", "नब्बे" }; + //ENGLISH WORDS RESOURCE + public static readonly string[] OnesEnglish = { + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", + "seventeen", "eighteen", "nineteen" + }; public static readonly string[] OnesHindi = { "सुन्य", "एक", "दो", "तीन", "चार", "पाँच", "छह", "सात", "आठ", "नौ", "दस", "ग्यारह", "बारह", "तेरह", "चौदह", "पन्द्रह", "सोलह", "सत्रह", "अठारह", "उन्नीस", "बीस", @@ -60,15 +56,36 @@ internal static class WordResources "इक्यानबे", "बानबे", "तिरानबे", "चौरानबे", "पंचानबे", "छियानबे", "सत्तानबे", "अट्ठानबे", "निन्यानबे" }; - - public static IDictionary<(Culture culture, OutputFormat outputFormat), (string CurrencyUnit, string SubCurrencyUnit, string EndOfWordsMarker)> CurrencyDefaults - = new Dictionary<(Culture culture, OutputFormat outputFormat), (string CurrencyUnit, string SubCurrencyUnit, string EndOfWordsMarker)> - { - {(Culture.International, OutputFormat.English), ("dollar", "cents", "only")}, - {(Culture.Nepali, OutputFormat.English), ("rupees", "paisa", "only")}, - {(Culture.Nepali, OutputFormat.Unicode), ("रूपैयाँ", "पैसा", "मात्र")}, - {(Culture.Nepali, OutputFormat.Devnagari), ("¿k}ofF", "k};f", "dfq")} - //TODO: ADD FOR HINDI + public static readonly string[] OnesNep = { "सुन्य", "एक", "दुई", "तीन", "चार", "पाँच", "छ", "सात", "आठ", "नौ", "दस", + "एघार", "बाह्र", "तेह्र", "चौध", "पन्ध्र", "सोह्र", "सत्र", "अठाह्र", "उन्नाइस", "बीस", "एकाइस", + "बाइस", "तेइस", "चौबीस", "पचीस", "छब्बीस", "सत्ताइस", "अठ्ठाइस", "उनन्तीस", "तीस", + "एकतीस", "बतीस", "तेतीस", "चौतीस", "पैतीस", "छतीस", "सरतीस", "अरतीस", "उननचालीस", "चालीस", + "एकचालीस", "बयालिस", "तीरचालीस", "चौवालिस", "पैंतालिस", "छयालिस", "सरचालीस", "अरचालीस", "उननचास", "पचास", + "एकाउन्न", "बाउन्न", "त्रिपन्न", "चौवन्न", "पच्पन्न", "छपन्न", "सन्ताउन्न", "अन्ठाउँन्न", "उनान्न्साठी", "साठी", + "एकसाठी", "बासाठी", "तीरसाठी", "चौंसाठी", "पैसाठी", "छैसठी", "सत्सठ्ठी", "अर्सठ्ठी", "उनन्सत्तरी", "सतरी", + "एकहत्तर", "बहत्तर", "त्रिहत्तर", "चौहत्तर", "पचहत्तर", "छहत्तर", "सत्हत्तर", "अठ्हत्तर", "उनास्सी", "अस्सी", + "एकासी", "बयासी", "त्रीयासी", "चौरासी", "पचासी", "छयासी", "सतासी", "अठासी", "उनान्नब्बे", "नब्बे", + "एकान्नब्बे", "बयान्नब्बे", "त्रियान्नब्बे", "चौरान्नब्बे", "पंचान्नब्बे", "छयान्नब्बे", "सन्तान्‍नब्बे", "अन्ठान्नब्बे", "उनान्सय" }; + + public static readonly string[] ScaleDevnagari = { "", ";o", "xhf/", "nfv", "s/f]8", "c/a", "v/a", "gLn", "kß", "z+v", "pkfw", "c+s", "hNb", "dw", "k/w{", "cGt", "dxfcGt", "lzzGt", "l;+3/", "dxfl;+x/", "cbGt l;+x/" }; + + public static readonly string[] ScaleEng = { "", "hundred", "thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion", "octillion", "nonillion", "decillion", "undecillion", "duodecillion " }; + + public static readonly string[] ScaleHindi = { "", "सौ", "हजार", "लाख", "करोड़", "अरब", "खरब", "नील", "पद्म", "शंख", "उपाध", "अंक", "जल्द", "मध", "परर्ध", "अन्त", "महाअन्त", "शिशन्त", "सिंघर", "महासिंहर", "अदन्त सिंहर" }; + + public static readonly string[] ScaleNep = { "", "सय", "हजार", "लाख", "करोड", "अरब", "खरब", "नील", "पद्म", "शंख", "उपाध", "अंक", "जल्द", "मध", "परर्ध", "अन्त", "महाअन्त", "शिशन्त", "सिंघर", "महासिंहर", "अदन्त सिंहर" }; + + public static readonly string[] ScaleNepEnglish = { "", "hundred", "thousand", "lakh", "crore", "arba", "kharba", "neel", "padma", "shankha", "Upadh", "Anka", "Jald", "Madh", "Parardha", "Anta", "Mahaanta", "Shishanta", "Singhar", "Maha Singhar", "Adanta Singhar" }; //Pow(10,39) + + public static readonly string[] TensDevnagari = { "", "b;", "aL;", "tL;", "rfnL;", "krf;", ";f7L", ";t/L", "c:;L", "gAa]" }; + + public static readonly string[] TensEnglish = { "", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety" }; + + public static readonly string[] TensHindi = { "", "दस", "बीस", "तीस", "चालीस", "पचास", "साठ", "सत्तर", "अस्सी", "नब्बे" }; + + //NEPALI WORDS RESOURCE + public static readonly string[] TensNep = { "", "दस", "बीस", "तीस", "चालीस", "पचास", "साठी", "सतरी", "अस्सी", "नब्बे" }; + } -} +} \ No newline at end of file diff --git a/NumericWordsConversion/WordsConverter.cs b/NumericWordsConversion/WordsConverter.cs new file mode 100644 index 0000000..78caaa1 --- /dev/null +++ b/NumericWordsConversion/WordsConverter.cs @@ -0,0 +1,63 @@ +// Copyright © 2020 Protiguous. All Rights Reserved. +// +// This entire copyright notice and license must be retained and must be kept visible in any binaries, libraries, repositories, and source code (directly or derived) +// from our binaries, libraries, projects, or solutions. +// +// This source code contained in "WordsConverter.cs" belongs to Protiguous@Protiguous.com unless otherwise specified or the original license has been overwritten +// by formatting. (We try to avoid it from happening, but it does accidentally happen.) +// +// Any unmodified portions of source code gleaned from other projects still retain their original license and our thanks goes to those Authors. +// If you find your code in this source code, please let us know so we can properly attribute you and include the proper license and/or copyright. +// +// If you want to use any of our code in a commercial project, you must contact Protiguous@Protiguous.com for permission and a quote. +// +// Donations are accepted (for now) via +// bitcoin: 1Mad8TxTqxKnMiHuZxArFvX8BuFEB9nqX2 +// PayPal: Protiguous@Protiguous.com +// +// ========================================================= +// Disclaimer: Usage of the source code or binaries is AS-IS. +// No warranties are expressed, implied, or given. +// We are NOT responsible for Anything You Do With Our Code. +// We are NOT responsible for Anything You Do With Our Executables. +// We are NOT responsible for Anything You Do With Your Computer. +// ========================================================= +// +// Contact us by email if you have any questions, helpful criticism, or if you would like to use our code in your project(s). +// For business inquiries, please contact me at Protiguous@Protiguous.com. +// +// Our website can be found at "https://Protiguous.com/" +// Our software can be found at "https://Protiguous.Software/" +// Our GitHub address is "https://github.com/Protiguous". +// Feel free to browse any source code we make available. +// +// Project: "NumericWordsConversion", File: "WordsConverter.cs" was last formatted by Protiguous on 2020/02/06 at 6:36 AM. + +namespace NumericWordsConversion { + + using System; + using JetBrains.Annotations; + + public static class WordsConverter { + + [NotNull] + private static CurrencyWordsConverter _currencyWordsConverter = new CurrencyWordsConverter(); + + [NotNull] + private static CurrencyWordsConverter CurrencyWordsConverter { + get => _currencyWordsConverter; + set => _currencyWordsConverter = value ?? throw new ArgumentNullException( nameof( value ), "Value cannot be null" ); + } + + [CanBeNull] + public static string ToWords( this decimal number, [CanBeNull] CurrencyWordsConversionOptions? options = null ) { + if ( !(options is null) ) { + CurrencyWordsConverter = new CurrencyWordsConverter( options ); + } + + return CurrencyWordsConverter.ToWords( number ); + } + + } + +} \ No newline at end of file diff --git a/UnitTests/ConvertToWordsEnglish.cs b/UnitTests/ConvertToWordsEnglish.cs index 8314f6d..5575022 100644 --- a/UnitTests/ConvertToWordsEnglish.cs +++ b/UnitTests/ConvertToWordsEnglish.cs @@ -1,72 +1,63 @@ -using NumericWordsConversion; -using NUnit.Framework; +namespace UnitTests { + + using System; + using NumericWordsConversion; + using NUnit.Framework; -namespace UnitTests -{ [TestFixture] - public class ToWordsEnglish - { - public CurrencyWordsConverter AmtToWords { get; set; } + public class ToWordsEnglish { [SetUp] - public void Setup() - { - AmtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions - { - Culture = Culture.International, - OutputFormat = OutputFormat.English, - CurrencyUnit = "rupees", - SubCurrencyUnit = "paisa" - }); + public void Setup() { + this.AmtToWords = new CurrencyWordsConverter( new CurrencyWordsConversionOptions { + Culture = Culture.International, OutputFormat = OutputFormat.English, CurrencyUnit = "rupees", SubCurrencyUnit = "paisa" + } ); } + public CurrencyWordsConverter AmtToWords { get; set; } + [Test] - public void ZeroPaisa() - { - string actualResult = AmtToWords.ToWords(32152M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees only"; - Assert.AreEqual(expectedResult, actualResult); + public void EightyEightPaisa() { + var actualResult = this.AmtToWords.ToWords( 32152.88M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees eighty eight paisa only"; + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void OnePaisa() - { - string actualResult = AmtToWords.ToWords(32152.01M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees one paisa only"; - Assert.AreEqual(expectedResult, actualResult); + public void ElevenPaisa() { + var actualResult = this.AmtToWords.ToWords( 32152.11M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees eleven paisa only"; + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void TenPaisa() - { - string actualResult = AmtToWords.ToWords(32152.10M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees ten paisa only"; - Assert.AreEqual(expectedResult, actualResult); + public void OnePaisa() { + var actualResult = this.AmtToWords.ToWords( 32152.01M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees one paisa only"; + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void ElevenPaisa() - { - string actualResult = AmtToWords.ToWords(32152.11M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees eleven paisa only"; - Assert.AreEqual(expectedResult, actualResult); + public void TenPaisa() { + var actualResult = this.AmtToWords.ToWords( 32152.10M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees ten paisa only"; + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void ThirtyPaisa() - { - string actualResult = AmtToWords.ToWords(32152.30M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees thirty paisa only"; - Assert.AreEqual(expectedResult, actualResult); + public void ThirtyPaisa() { + var actualResult = this.AmtToWords.ToWords( 32152.30M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees thirty paisa only"; + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void EightyEightPaisa() - { - string actualResult = AmtToWords.ToWords(32152.88M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees eighty eight paisa only"; - Assert.AreEqual(expectedResult, actualResult); + public void ZeroPaisa() { + var actualResult = this.AmtToWords.ToWords( 32152M ); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees only"; + Assert.AreEqual( expectedResult, actualResult ); } } -} + +} \ No newline at end of file diff --git a/UnitTests/ConvertToWords_Nepali.cs b/UnitTests/ConvertToWords_Nepali.cs index 804f8c8..c0b3b13 100644 --- a/UnitTests/ConvertToWords_Nepali.cs +++ b/UnitTests/ConvertToWords_Nepali.cs @@ -3,6 +3,9 @@ namespace UnitTests { + + using System; + public class ToWordsNepali { public CurrencyWordsConverter AmtToWords { get; set; } @@ -10,7 +13,7 @@ public class ToWordsNepali [SetUp] public void Setup() { - AmtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions + this.AmtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions { Culture = Culture.Nepali, OutputFormat = OutputFormat.Unicode, @@ -20,8 +23,8 @@ public void Setup() [Test] public void ZeroPaisa() { - string actualResult = AmtToWords.ToWords(32152M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ मात्र"; + var actualResult = this.AmtToWords.ToWords(32152M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ मात्र"; Assert.AreEqual(expectedResult, actualResult); } @@ -29,9 +32,9 @@ public void ZeroPaisa() public void OnePaisa() { //Arrange - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एक पैसा मात्र"; + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एक पैसा मात्र"; //Act - string actualResult = AmtToWords.ToWords(32152.01M); + var actualResult = this.AmtToWords.ToWords(32152.01M); //Assert Assert.AreEqual(expectedResult, actualResult); } @@ -39,32 +42,32 @@ public void OnePaisa() [Test] public void TenPaisa() { - string actualResult = AmtToWords.ToWords(32152.10M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ दस पैसा मात्र"; + var actualResult = this.AmtToWords.ToWords(32152.10M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ दस पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ElevenPaisa() { - string actualResult = AmtToWords.ToWords(32152.11M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एघार पैसा मात्र"; + var actualResult = this.AmtToWords.ToWords(32152.11M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एघार पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ThirtyPaisa() { - string actualResult = AmtToWords.ToWords(32152.30M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ तीस पैसा मात्र"; + var actualResult = this.AmtToWords.ToWords(32152.30M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ तीस पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void EightyEightPaisa() { - string actualResult = AmtToWords.ToWords(32152.88M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; + var actualResult = this.AmtToWords.ToWords(32152.88M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } diff --git a/UnitTests/CurrencyConverterTest.cs b/UnitTests/CurrencyConverterTest.cs index a44faaf..d609621 100644 --- a/UnitTests/CurrencyConverterTest.cs +++ b/UnitTests/CurrencyConverterTest.cs @@ -1,36 +1,32 @@ using NumericWordsConversion; using NUnit.Framework; -namespace UnitTests -{ +namespace UnitTests { [TestFixture] - public class CurrencyConverterTest - { - [Test, TestCaseSource(nameof(TestCases))] - public string MyTestCases(decimal amount) - { - CurrencyWordsConversionOptions options = new CurrencyWordsConversionOptions() - { + public class CurrencyConverterTest { + [Test] + [TestCaseSource( nameof( TestCases ) )] + public string MyTestCases( decimal amount ) { + var options = new CurrencyWordsConversionOptions() { Culture = Culture.International, }; - CurrencyWordsConverter amt = new CurrencyWordsConverter(options); - string result = amt.ToWords(amount); + var amt = new CurrencyWordsConverter( options ); + var result = amt.ToWords( amount ); return result; } - [Test, TestCaseSource(nameof(NepaliUnicodeCases))] - public string NepaliUnicodeTest(decimal amount) - { - CurrencyWordsConversionOptions options = new CurrencyWordsConversionOptions() - { + [Test] + [TestCaseSource( nameof( NepaliUnicodeCases ) )] + public string NepaliUnicodeTest( decimal amount ) { + var options = new CurrencyWordsConversionOptions() { Culture = Culture.Nepali, OutputFormat = OutputFormat.Unicode, EndOfWordsMarker = "मात्र" }; - CurrencyWordsConverter amt = new CurrencyWordsConverter(options); - string result = amt.ToWords(amount); + var amt = new CurrencyWordsConverter( options ); + var result = amt.ToWords( amount ); return result; } diff --git a/UnitTests/EnglishCulture.cs b/UnitTests/EnglishCulture.cs index 84398a8..5550dc0 100644 --- a/UnitTests/EnglishCulture.cs +++ b/UnitTests/EnglishCulture.cs @@ -1,154 +1,335 @@ -using NumericWordsConversion; -using NUnit.Framework; +namespace UnitTests { -namespace UnitTests -{ - [TestFixture] - public class EnglishCulture - { - [SetUp] - public void Setup() - { - NumericWordsConfiguration.ConfigureConversionDefaults(options => - { - options.SetDefaultCurrencyWordsOptions(new CurrencyWordsConversionOptions - { - Culture = Culture.International, - OutputFormat = OutputFormat.English, - CurrencyUnit = "rupees", - SubCurrencyUnit = "paisa" - }); - }); - } - - [Test, TestCaseSource(nameof(EnglishWordCases))] - public void DecimalOnly(decimal amount, string words) - { - string result = amount.ToCurrencyWords(); - Assert.AreEqual(words, result); - } - - [Test, TestCaseSource(nameof(TestCases))] - public string MyTestCases(decimal amount) - { - string result = amount.ToCurrencyWords(); - return result; - } - - private static readonly object[] EnglishWordCases = - { - new object[] { 0M, "" }, - new object[] { 0.01M, "One paisa only" }, - new object[] { 0.10M, "Ten paisa only" }, - new object[] { 0.88M, "Eighty eight paisa only" }, - new object[] { 1M , "One rupees only" }, - new object[] { 1.01M, "One rupees one paisa only" }, - new object[] { 1.10M, "One rupees ten paisa only" }, - new object[] { 1.88M, "One rupees eighty eight paisa only" }, - new object[] { 10M , "Ten rupees only" }, - new object[] { 10.01M, "Ten rupees one paisa only" }, - new object[] { 10.10M, "Ten rupees ten paisa only" }, - new object[] { 10.88M, "Ten rupees eighty eight paisa only" }, - new object[] { 19M , "Nineteen rupees only" }, - new object[] { 19.01M, "Nineteen rupees one paisa only" }, - new object[] { 19.10M, "Nineteen rupees ten paisa only" }, - new object[] { 19.88M, "Nineteen rupees eighty eight paisa only" }, - new object[] { 21M , "Twenty one rupees only" }, - new object[] { 21.01M, "Twenty one rupees one paisa only" }, - new object[] { 21.10M, "Twenty one rupees ten paisa only" }, - new object[] { 21.88M, "Twenty one rupees eighty eight paisa only" }, - new object[] { 100M , "One hundred rupees only" }, - new object[] { 100.01M, "One hundred rupees one paisa only" }, - new object[] { 100.10M, "One hundred rupees ten paisa only" }, - new object[] { 100.88M, "One hundred rupees eighty eight paisa only" }, - new object[] { 550M , "Five hundred fifty rupees only" }, - new object[] { 550.01M, "Five hundred fifty rupees one paisa only" }, - new object[] { 550.10M, "Five hundred fifty rupees ten paisa only" }, - new object[] { 550.88M, "Five hundred fifty rupees eighty eight paisa only" }, - new object[] { 555M , "Five hundred fifty five rupees only" }, - new object[] { 555.01M, "Five hundred fifty five rupees one paisa only" }, - new object[] { 555.10M, "Five hundred fifty five rupees ten paisa only" }, - new object[] { 555.88M, "Five hundred fifty five rupees eighty eight paisa only" }, - new object[] { 1555M , "One thousand five hundred fifty five rupees only" }, - new object[] { 1555.01M, "One thousand five hundred fifty five rupees one paisa only" }, - new object[] { 1555.10M, "One thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 1555.88M, "One thousand five hundred fifty five rupees eighty eight paisa only" }, - new object[] { 10555M , "Ten thousand five hundred fifty five rupees only" }, - new object[] { 10555.01M, "Ten thousand five hundred fifty five rupees one paisa only" }, - new object[] { 10555.10M, "Ten thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 10555.88M, "Ten thousand five hundred fifty five rupees eighty eight paisa only" }, + using JetBrains.Annotations; + using NumericWordsConversion; + using NUnit.Framework; - new object[] { 100_000M , "One hundred thousand rupees only" }, - new object[] { 100_000.01M, "One hundred thousand rupees one paisa only" }, - new object[] { 100_000.10M, "One hundred thousand rupees ten paisa only" }, - new object[] { 100_000.88M, "One hundred thousand rupees eighty eight paisa only" }, - new object[] { 100_555.01M, "One hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 100_555.10M, "One hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 100_555.88M, "One hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + [TestFixture] + public class EnglishCulture { - new object[] { 9_100_000M , "Nine million one hundred thousand rupees only" }, - new object[] { 9_100_000.01M, "Nine million one hundred thousand rupees one paisa only" }, - new object[] { 9_100_000.10M, "Nine million one hundred thousand rupees ten paisa only" }, - new object[] { 9_100_000.88M, "Nine million one hundred thousand rupees eighty eight paisa only" }, - new object[] { 9_100_555.01M, "Nine million one hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 9_100_555.10M, "Nine million one hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 9_100_555.88M, "Nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + [SetUp] + public void Setup() => + NumericWordsConfiguration.ConfigureConversionDefaults( options => OptionsInitializer.SetDefaultCurrencyWordsOptions( new CurrencyWordsConversionOptions { + Culture = Culture.International, OutputFormat = OutputFormat.English, CurrencyUnit = "rupees", SubCurrencyUnit = "paisa" + } ) ); - new object[] { 90_100_000M , "Ninety million one hundred thousand rupees only" }, - new object[] { 90_100_000.01M, "Ninety million one hundred thousand rupees one paisa only" }, - new object[] { 90_100_000.10M, "Ninety million one hundred thousand rupees ten paisa only" }, - new object[] { 90_100_000.88M, "Ninety million one hundred thousand rupees eighty eight paisa only" }, - new object[] { 90_100_555.01M, "Ninety million one hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 90_100_555.10M, "Ninety million one hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 90_100_555.88M, "Ninety million one hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + private static readonly object[] EnglishWordCases = { + new object[] { + 0M, "" + }, + new object[] { + 0.01M, "One paisa only" + }, + new object[] { + 0.10M, "Ten paisa only" + }, + new object[] { + 0.88M, "Eighty eight paisa only" + }, + new object[] { + 1M, "One rupees only" + }, + new object[] { + 1.01M, "One rupees one paisa only" + }, + new object[] { + 1.10M, "One rupees ten paisa only" + }, + new object[] { + 1.88M, "One rupees eighty eight paisa only" + }, + new object[] { + 10M, "Ten rupees only" + }, + new object[] { + 10.01M, "Ten rupees one paisa only" + }, + new object[] { + 10.10M, "Ten rupees ten paisa only" + }, + new object[] { + 10.88M, "Ten rupees eighty eight paisa only" + }, + new object[] { + 19M, "Nineteen rupees only" + }, + new object[] { + 19.01M, "Nineteen rupees one paisa only" + }, + new object[] { + 19.10M, "Nineteen rupees ten paisa only" + }, + new object[] { + 19.88M, "Nineteen rupees eighty eight paisa only" + }, + new object[] { + 21M, "Twenty one rupees only" + }, + new object[] { + 21.01M, "Twenty one rupees one paisa only" + }, + new object[] { + 21.10M, "Twenty one rupees ten paisa only" + }, + new object[] { + 21.88M, "Twenty one rupees eighty eight paisa only" + }, + new object[] { + 100M, "One hundred rupees only" + }, + new object[] { + 100.01M, "One hundred rupees one paisa only" + }, + new object[] { + 100.10M, "One hundred rupees ten paisa only" + }, + new object[] { + 100.88M, "One hundred rupees eighty eight paisa only" + }, + new object[] { + 550M, "Five hundred fifty rupees only" + }, + new object[] { + 550.01M, "Five hundred fifty rupees one paisa only" + }, + new object[] { + 550.10M, "Five hundred fifty rupees ten paisa only" + }, + new object[] { + 550.88M, "Five hundred fifty rupees eighty eight paisa only" + }, + new object[] { + 555M, "Five hundred fifty five rupees only" + }, + new object[] { + 555.01M, "Five hundred fifty five rupees one paisa only" + }, + new object[] { + 555.10M, "Five hundred fifty five rupees ten paisa only" + }, + new object[] { + 555.88M, "Five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1555M, "One thousand five hundred fifty five rupees only" + }, + new object[] { + 1555.01M, "One thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 1555.10M, "One thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 1555.88M, "One thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 10555M, "Ten thousand five hundred fifty five rupees only" + }, + new object[] { + 10555.01M, "Ten thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 10555.10M, "Ten thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 10555.88M, "Ten thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 100_000M, "One hundred thousand rupees only" + }, + new object[] { + 100_000.01M, "One hundred thousand rupees one paisa only" + }, + new object[] { + 100_000.10M, "One hundred thousand rupees ten paisa only" + }, + new object[] { + 100_000.88M, "One hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 100_555.01M, "One hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 100_555.10M, "One hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 100_555.88M, "One hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 9_100_000M, "Nine million one hundred thousand rupees only" + }, + new object[] { + 9_100_000.01M, "Nine million one hundred thousand rupees one paisa only" + }, + new object[] { + 9_100_000.10M, "Nine million one hundred thousand rupees ten paisa only" + }, + new object[] { + 9_100_000.88M, "Nine million one hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 9_100_555.01M, "Nine million one hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 9_100_555.10M, "Nine million one hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 9_100_555.88M, "Nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 90_100_000M, "Ninety million one hundred thousand rupees only" + }, + new object[] { + 90_100_000.01M, "Ninety million one hundred thousand rupees one paisa only" + }, + new object[] { + 90_100_000.10M, "Ninety million one hundred thousand rupees ten paisa only" + }, + new object[] { + 90_100_000.88M, "Ninety million one hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 90_100_555.01M, "Ninety million one hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 90_100_555.10M, "Ninety million one hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 90_100_555.88M, "Ninety million one hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 909_100_000M, "Nine hundred nine million one hundred thousand rupees only" + }, + new object[] { + 909_100_000.01M, "Nine hundred nine million one hundred thousand rupees one paisa only" + }, + new object[] { + 909_100_000.10M, "Nine hundred nine million one hundred thousand rupees ten paisa only" + }, + new object[] { + 909_100_000.88M, "Nine hundred nine million one hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 909_100_555.01M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 909_100_555.10M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 909_100_555.88M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 462_909_100_000M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees only" + }, + new object[] { + 462_909_100_000.01M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees one paisa only" + }, + new object[] { + 462_909_100_000.10M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees ten paisa only" + }, + new object[] { + 462_909_100_000.88M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 462_909_100_555.01M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 462_909_100_555.10M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 462_909_100_555.88M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1_000_909_100_000M, "One trillion nine hundred nine million one hundred thousand rupees only" + }, + new object[] { + 1_000_909_100_000.01M, "One trillion nine hundred nine million one hundred thousand rupees one paisa only" + }, + new object[] { + 1_000_909_100_000.10M, "One trillion nine hundred nine million one hundred thousand rupees ten paisa only" + }, + new object[] { + 1_000_909_100_000.88M, "One trillion nine hundred nine million one hundred thousand rupees eighty eight paisa only" + }, + new object[] { + 1_000_909_100_555.01M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 1_000_909_100_555.10M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 1_000_909_100_555.88M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1M, "One rupees only" + }, + new object[] { + 10M, "Ten rupees only" + }, + new object[] { + 100M, "One hundred rupees only" + }, + new object[] { + 1_000M, "One thousand rupees only" + }, + new object[] { + 10_000M, "Ten thousand rupees only" + }, + new object[] { + 100_000M, "One hundred thousand rupees only" + }, + new object[] { + 1_000_000M, "One million rupees only" + }, + new object[] { + 10_000_000M, "Ten million rupees only" + }, + new object[] { + 100_000_000M, "One hundred million rupees only" + }, + new object[] { + 1_000_000_000M, "One billion rupees only" + }, + new object[] { + 10_000_000_000M, "Ten billion rupees only" + }, + new object[] { + 100_000_000_000M, "One hundred billion rupees only" + }, + new object[] { + 1_000_000_000_000M, "One trillion rupees only" + }, + new object[] { + 10_000_000_000_000M, "Ten trillion rupees only" + }, + new object[] { + 100_000_000_000_000M, "One hundred trillion rupees only" + }, + new object[] { + 10_000_000_000_000_000_000_000_000_000M, "Ten octillion rupees only" + } + }; - new object[] { 909_100_000M , "Nine hundred nine million one hundred thousand rupees only" }, - new object[] { 909_100_000.01M, "Nine hundred nine million one hundred thousand rupees one paisa only" }, - new object[] { 909_100_000.10M, "Nine hundred nine million one hundred thousand rupees ten paisa only" }, - new object[] { 909_100_000.88M, "Nine hundred nine million one hundred thousand rupees eighty eight paisa only" }, - new object[] { 909_100_555.01M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 909_100_555.10M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 909_100_555.88M, "Nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + private static readonly TestCaseData[] TestCases = { + new TestCaseData( 0M ).Returns( "" ) + }; - new object[] { 462_909_100_000M , "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees only" }, - new object[] { 462_909_100_000.01M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees one paisa only" }, - new object[] { 462_909_100_000.10M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees ten paisa only" }, - new object[] { 462_909_100_000.88M, "Four hundred sixty two billion nine hundred nine million one hundred thousand rupees eighty eight paisa only" }, - new object[] { 462_909_100_555.01M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 462_909_100_555.10M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 462_909_100_555.88M, "Four hundred sixty two billion nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + [Test] + [TestCaseSource( nameof( EnglishWordCases ) )] + public void DecimalOnly( decimal amount, string words ) { + var result = amount.ToCurrencyWords(); + Assert.AreEqual( words, result ); + } - new object[] { 1_000_909_100_000M , "One trillion nine hundred nine million one hundred thousand rupees only" }, - new object[] { 1_000_909_100_000.01M, "One trillion nine hundred nine million one hundred thousand rupees one paisa only" }, - new object[] { 1_000_909_100_000.10M, "One trillion nine hundred nine million one hundred thousand rupees ten paisa only" }, - new object[] { 1_000_909_100_000.88M, "One trillion nine hundred nine million one hundred thousand rupees eighty eight paisa only" }, - new object[] { 1_000_909_100_555.01M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees one paisa only" }, - new object[] { 1_000_909_100_555.10M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 1_000_909_100_555.88M, "One trillion nine hundred nine million one hundred thousand five hundred fifty five rupees eighty eight paisa only" }, + [Test] + [TestCaseSource( nameof( TestCases ) )] + [NotNull] + public string MyTestCases( decimal amount ) { + var result = amount.ToCurrencyWords(); - new object[] { 1M , "One rupees only" }, - new object[] { 10M , "Ten rupees only" }, - new object[] { 100M , "One hundred rupees only" }, - new object[] { 1_000M, "One thousand rupees only" }, - new object[] { 10_000M, "Ten thousand rupees only" }, - new object[] { 100_000M, "One hundred thousand rupees only" }, - new object[] { 1_000_000M, "One million rupees only" }, - new object[] { 10_000_000M, "Ten million rupees only" }, - new object[] { 100_000_000M, "One hundred million rupees only" }, - new object[] { 1_000_000_000M, "One billion rupees only" }, - new object[] { 10_000_000_000M, "Ten billion rupees only" }, - new object[] { 100_000_000_000M, "One hundred billion rupees only" }, - new object[] { 1_000_000_000_000M, "One trillion rupees only" }, - new object[] { 10_000_000_000_000M, "Ten trillion rupees only" }, - new object[] { 100_000_000_000_000M, "One hundred trillion rupees only" }, - new object[] { 10_000_000_000_000_000_000_000_000_000M, "Ten octillion rupees only" }, - }; + return result; + } - private static readonly TestCaseData[] TestCases = - { - new TestCaseData(0M).Returns(""), - }; } - } \ No newline at end of file diff --git a/UnitTests/ExtensionFunction_English.cs b/UnitTests/ExtensionFunction_English.cs index ce226d2..8c30180 100644 --- a/UnitTests/ExtensionFunction_English.cs +++ b/UnitTests/ExtensionFunction_English.cs @@ -1,33 +1,24 @@ -using NUnit.Framework; -using System; -using NumericWordsConversion; +namespace UnitTests { + + using System; + using NumericWordsConversion; + using NUnit.Framework; + + public class ExtensionFunctionEnglish { -namespace UnitTests -{ - public class ExtensionFunctionEnglish - { [SetUp] - public void Setup() - { - NumericWordsConfiguration.ConfigureConversionDefaults(options => - { - options.SetDefaultCurrencyWordsOptions(new CurrencyWordsConversionOptions - { - Culture = Culture.International, - OutputFormat = OutputFormat.English, - CurrencyUnit = "rupees", - SubCurrencyUnit = "paisa" - }); - }); + public void Setup() { + NumericWordsConfiguration.ConfigureConversionDefaults( options => OptionsInitializer.SetDefaultCurrencyWordsOptions( new CurrencyWordsConversionOptions { + Culture = Culture.International, OutputFormat = OutputFormat.English, CurrencyUnit = "rupees", SubCurrencyUnit = "paisa" + } ) ); } [Test] - public void Extension() - { - decimal amt = 36253.20M; - string expectedResult = "Thirty six thousand two hundred fifty three rupees twenty paisa only"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + public void Extension() { + const Decimal amt = 36253.20M; + const String expectedResult = "Thirty six thousand two hundred fifty three rupees twenty paisa only"; + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } //[Test] @@ -39,41 +30,40 @@ public void Extension() //} [Test] - public void ThreeDigitFloorPaisa() - { - decimal amt = 11_321.924M; - string expectedResult = "Eleven thousand three hundred twenty one rupees ninety two paisa only"; + public void ThreeDigitFloorPaisa() { + const Decimal amt = 11_321.924M; + const String expectedResult = "Eleven thousand three hundred twenty one rupees ninety two paisa only"; var result = amt.ToCurrencyWords(); - Assert.AreEqual(result, expectedResult); + Assert.AreEqual( result, expectedResult ); } [Test] - public void ThreeDigitCeilingPaisa() - { - decimal amt = 11_321.929M; - string expectedResult = "Eleven thousand three hundred twenty one rupees ninety three paisa only"; + public void ThreeDigitCeilingPaisa() { + const Decimal amt = 11_321.929M; + const String expectedResult = "Eleven thousand three hundred twenty one rupees ninety three paisa only"; var result = amt.ToCurrencyWords(); - Assert.AreEqual(result, expectedResult); + Assert.AreEqual( result, expectedResult ); } [Test] - public void ShankhaExtension() - { - decimal amt = 9_800_777_660_544_100_110_321.99M; - string expectedResult = "Nine sextillion eight hundred quintillion seven hundred seventy seven quadrillion six hundred sixty trillion five hundred forty four billion one hundred million one hundred ten thousand three hundred twenty one rupees ninety nine paisa only"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + public void ShankhaExtension() { + const Decimal amt = 9_800_777_660_544_100_110_321.99M; + + const String expectedResult = "Nine sextillion eight hundred quintillion seven hundred seventy seven quadrillion six hundred sixty trillion five hundred forty four billion one hundred million one hundred ten thousand three hundred twenty one rupees ninety nine paisa only"; + + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void PaisaOnly() - { - decimal amt = 0.20M; - string expectedResult = "Twenty paisa only"; + public void PaisaOnly() { + const Decimal amt = 0.20M; + const String expectedResult = "Twenty paisa only"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } } + } \ No newline at end of file diff --git a/UnitTests/ExtensionFunction_Nepali.cs b/UnitTests/ExtensionFunction_Nepali.cs index 633d220..187a5a8 100644 --- a/UnitTests/ExtensionFunction_Nepali.cs +++ b/UnitTests/ExtensionFunction_Nepali.cs @@ -1,66 +1,59 @@ -using NumericWordsConversion; -using NUnit.Framework; +namespace UnitTests { + + using System; + using NumericWordsConversion; + using NUnit.Framework; + + public class ExtensionFunctionNepali { -namespace UnitTests -{ - public class ExtensionFunctionNepali - { [SetUp] - public void Setup() - { - NumericWordsConfiguration.ConfigureConversionDefaults(options => - { - options.SetDefaultCurrencyWordsOptions(new CurrencyWordsConversionOptions - { - Culture = Culture.Nepali, - OutputFormat = OutputFormat.Unicode, - }); - }); + public void Setup() { + NumericWordsConfiguration.ConfigureConversionDefaults( options => OptionsInitializer.SetDefaultCurrencyWordsOptions( new CurrencyWordsConversionOptions { + Culture = Culture.Nepali, OutputFormat = OutputFormat.Unicode + } ) ); } [Test] - public void Extension() - { - decimal amt = 30246.20M; - string expectedResult = "तीस हजार दुई सय छयालिस रूपैयाँ बीस पैसा मात्र"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + public void Extension() { + const Decimal amt = 30246.20M; + const String expectedResult = "तीस हजार दुई सय छयालिस रूपैयाँ बीस पैसा मात्र"; + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } + [Test] - public void ShankhaExtension() - { - decimal amt = 88_77_66_55_44_33_22_11_321M; - string expectedResult = "अठासी शंख सत्हत्तर पद्म छैसठी नील पच्पन्न खरब चौवालिस अरब तेतीस करोड बाइस लाख एघार हजार तीन सय एकाइस रूपैयाँ मात्र"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + public void ShankhaExtension() { + const Decimal amt = 88_77_66_55_44_33_22_11_321M; + const String expectedResult = "अठासी शंख सत्हत्तर पद्म छैसठी नील पच्पन्न खरब चौवालिस अरब तेतीस करोड बाइस लाख एघार हजार तीन सय एकाइस रूपैयाँ मात्र"; + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void PadmaAndTwentyPaisaExtension() - { - decimal amt = 77_66_55_44_33_22_11_321.88123456789M; - string expectedResult = "सत्हत्तर पद्म छैसठी नील पच्पन्न खरब चौवालिस अरब तेतीस करोड बाइस लाख एघार हजार तीन सय एकाइस रूपैयाँ अठासी पैसा मात्र"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + public void PadmaAndTwentyPaisaExtension() { + const Decimal amt = 77_66_55_44_33_22_11_321.88123456789M; + const String expectedResult = "सत्हत्तर पद्म छैसठी नील पच्पन्न खरब चौवालिस अरब तेतीस करोड बाइस लाख एघार हजार तीन सय एकाइस रूपैयाँ अठासी पैसा मात्र"; + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void PaisaOnly() - { - decimal amt = 0.88M; - string expectedResult = "अठासी पैसा मात्र"; + public void PaisaOnly() { + const Decimal amt = 0.88M; + const String expectedResult = "अठासी पैसा मात्र"; - string actualResult = amt.ToCurrencyWords(); - Assert.AreEqual(expectedResult, actualResult); + var actualResult = amt.ToCurrencyWords(); + Assert.AreEqual( expectedResult, actualResult ); } [Test] - public void NepaliExtension() - { - decimal amt = 32152.88M; - string actualResult = amt.ToCurrencyWords(); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; - Assert.AreEqual(expectedResult, actualResult); + public void NepaliExtension() { + const Decimal amt = 32152.88M; + var actualResult = amt.ToCurrencyWords(); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; + Assert.AreEqual( expectedResult, actualResult ); } + } + } \ No newline at end of file diff --git a/UnitTests/GlobalSuppressions.cs b/UnitTests/GlobalSuppressions.cs new file mode 100644 index 0000000..0d3e549 --- /dev/null +++ b/UnitTests/GlobalSuppressions.cs @@ -0,0 +1,8 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( "Style", "IDE0049:Use framework type", Justification = "Samyeak prefers int and not Int32" )] \ No newline at end of file diff --git a/UnitTests/InternationalNepaliTest.cs b/UnitTests/InternationalNepaliTest.cs index f07762e..eaf827c 100644 --- a/UnitTests/InternationalNepaliTest.cs +++ b/UnitTests/InternationalNepaliTest.cs @@ -4,6 +4,9 @@ namespace UnitTests { + + using System; + public class InternationalNepaliTest { public CurrencyWordsConverter AmtToWords { get; set; } @@ -11,7 +14,7 @@ public class InternationalNepaliTest [SetUp] public void Setup() { - AmtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions + this.AmtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions { Culture = Culture.International, CurrencyUnit = "rupees", @@ -22,48 +25,48 @@ public void Setup() [Test] public void ZeroPaisa() { - string actualResult = AmtToWords.ToWords(32152M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees only"; + var actualResult = this.AmtToWords.ToWords(32152M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees only"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void OnePaisa() { - string actualResult = AmtToWords.ToWords(32152.01M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees one paisa only"; + var actualResult = this.AmtToWords.ToWords(32152.01M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees one paisa only"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void TenPaisa() { - string actualResult = AmtToWords.ToWords(32152.10M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees ten paisa only"; + var actualResult = this.AmtToWords.ToWords(32152.10M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees ten paisa only"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ElevenPaisa() { - string actualResult = AmtToWords.ToWords(32152.11M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees eleven paisa only"; + var actualResult = this.AmtToWords.ToWords(32152.11M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees eleven paisa only"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ThirtyPaisa() { - string actualResult = AmtToWords.ToWords(32152.30M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees thirty paisa only"; + var actualResult = this.AmtToWords.ToWords(32152.30M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees thirty paisa only"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void EightyEightPaisa() { - string actualResult = AmtToWords.ToWords(32152.88M); - string expectedResult = "Thirty two thousand one hundred fifty two rupees eighty eight paisa only"; + var actualResult = this.AmtToWords.ToWords(32152.88M); + const String expectedResult = "Thirty two thousand one hundred fifty two rupees eighty eight paisa only"; Assert.AreEqual(expectedResult, actualResult); } diff --git a/UnitTests/NepaliCultureEnglishOutput.cs b/UnitTests/NepaliCultureEnglishOutput.cs index 161bcbe..9918fcb 100644 --- a/UnitTests/NepaliCultureEnglishOutput.cs +++ b/UnitTests/NepaliCultureEnglishOutput.cs @@ -1,125 +1,298 @@ -using System.Net.NetworkInformation; -using NumericWordsConversion; -using NUnit.Framework; +namespace UnitTests { -namespace UnitTests -{ - [TestFixture] - public class NepaliCultureEnglishOutput - { - [Test, TestCaseSource("WordCases")] - public void DecimalOnly(decimal amount, string words) - { - CurrencyWordsConverter amt = new CurrencyWordsConverter(new CurrencyWordsConversionOptions() - { - Culture = Culture.Nepali, - OutputFormat = OutputFormat.English - }); - string result = amt.ToWords(amount); - Assert.AreEqual(words, result); - } - - private static readonly object[] WordCases = - { - new object[] { 0M, "" }, - new object[] { 0.01M, "One paisa only" }, - new object[] { 0.10M, "Ten paisa only" }, - new object[] { 0.88M, "Eighty eight paisa only" }, - new object[] { 1M , "One rupees only" }, - new object[] { 1.01M, "One rupees one paisa only" }, - new object[] { 1.10M, "One rupees ten paisa only" }, - new object[] { 1.88M, "One rupees eighty eight paisa only" }, - new object[] { 10M , "Ten rupees only" }, - new object[] { 10.01M, "Ten rupees one paisa only" }, - new object[] { 10.10M, "Ten rupees ten paisa only" }, - new object[] { 10.88M, "Ten rupees eighty eight paisa only" }, - new object[] { 19M , "Nineteen rupees only" }, - new object[] { 19.01M, "Nineteen rupees one paisa only" }, - new object[] { 19.10M, "Nineteen rupees ten paisa only" }, - new object[] { 19.88M, "Nineteen rupees eighty eight paisa only" }, - new object[] { 21M , "Twenty one rupees only" }, - new object[] { 21.01M, "Twenty one rupees one paisa only" }, - new object[] { 21.10M, "Twenty one rupees ten paisa only" }, - new object[] { 21.88M, "Twenty one rupees eighty eight paisa only" }, - new object[] { 100M , "One hundred rupees only" }, - new object[] { 100.01M, "One hundred rupees one paisa only" }, - new object[] { 100.10M, "One hundred rupees ten paisa only" }, - new object[] { 100.88M, "One hundred rupees eighty eight paisa only" }, - new object[] { 550M , "Five hundred fifty rupees only" }, - new object[] { 550.01M, "Five hundred fifty rupees one paisa only" }, - new object[] { 550.10M, "Five hundred fifty rupees ten paisa only" }, - new object[] { 550.88M, "Five hundred fifty rupees eighty eight paisa only" }, - new object[] { 555M , "Five hundred fifty five rupees only" }, - new object[] { 555.01M, "Five hundred fifty five rupees one paisa only" }, - new object[] { 555.10M, "Five hundred fifty five rupees ten paisa only" }, - new object[] { 555.88M, "Five hundred fifty five rupees eighty eight paisa only" }, - new object[] { 1555M , "One thousand five hundred fifty five rupees only" }, - new object[] { 1555.01M, "One thousand five hundred fifty five rupees one paisa only" }, - new object[] { 1555.10M, "One thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 1555.88M, "One thousand five hundred fifty five rupees eighty eight paisa only" }, - new object[] { 10555M , "Ten thousand five hundred fifty five rupees only" }, - new object[] { 10555.01M, "Ten thousand five hundred fifty five rupees one paisa only" }, - new object[] { 10555.10M, "Ten thousand five hundred fifty five rupees ten paisa only" }, - new object[] { 10555.88M, "Ten thousand five hundred fifty five rupees eighty eight paisa only" }, - - new object[] { 1_00_000M , "One lakh rupees only" }, - new object[] { 1_00_000.01M, "One lakh rupees one paisa only" }, - new object[] { 1_00_000.10M, "One lakh rupees ten paisa only" }, - new object[] { 1_00_000.88M, "One lakh rupees eighty eight paisa only" }, - new object[] { 1_00_555.01M, "One lakh five hundred fifty five rupees one paisa only" }, - new object[] { 1_00_555.10M, "One lakh five hundred fifty five rupees ten paisa only" }, - new object[] { 1_00_555.88M, "One lakh five hundred fifty five rupees eighty eight paisa only" }, + using NumericWordsConversion; + using NUnit.Framework; - new object[] { 91_00_000M , "Ninety one lakh rupees only" }, - new object[] { 91_00_000.01M, "Ninety one lakh rupees one paisa only" }, - new object[] { 91_00_000.10M, "Ninety one lakh rupees ten paisa only" }, - new object[] { 91_00_000.88M, "Ninety one lakh rupees eighty eight paisa only" }, - new object[] { 91_00_555.01M, "Ninety one lakh five hundred fifty five rupees one paisa only" }, - new object[] { 91_00_555.10M, "Ninety one lakh five hundred fifty five rupees ten paisa only" }, - new object[] { 91_00_555.88M, "Ninety one lakh five hundred fifty five rupees eighty eight paisa only" }, + [TestFixture] + public class NepaliCultureEnglishOutput { - new object[] { 9_01_00_000M , "Nine crore one lakh rupees only" }, - new object[] { 9_01_00_000.01M, "Nine crore one lakh rupees one paisa only" }, - new object[] { 9_01_00_000.10M, "Nine crore one lakh rupees ten paisa only" }, - new object[] { 9_01_00_000.88M, "Nine crore one lakh rupees eighty eight paisa only" }, - new object[] { 9_01_00_555.01M, "Nine crore one lakh five hundred fifty five rupees one paisa only" }, - new object[] { 9_01_00_555.10M, "Nine crore one lakh five hundred fifty five rupees ten paisa only" }, - new object[] { 9_01_00_555.88M, "Nine crore one lakh five hundred fifty five rupees eighty eight paisa only" }, + private static readonly object[] WordCases = { + new object[] { + 0M, "" + }, + new object[] { + 0.01M, "One paisa only" + }, + new object[] { + 0.10M, "Ten paisa only" + }, + new object[] { + 0.88M, "Eighty eight paisa only" + }, + new object[] { + 1M, "One rupees only" + }, + new object[] { + 1.01M, "One rupees one paisa only" + }, + new object[] { + 1.10M, "One rupees ten paisa only" + }, + new object[] { + 1.88M, "One rupees eighty eight paisa only" + }, + new object[] { + 10M, "Ten rupees only" + }, + new object[] { + 10.01M, "Ten rupees one paisa only" + }, + new object[] { + 10.10M, "Ten rupees ten paisa only" + }, + new object[] { + 10.88M, "Ten rupees eighty eight paisa only" + }, + new object[] { + 19M, "Nineteen rupees only" + }, + new object[] { + 19.01M, "Nineteen rupees one paisa only" + }, + new object[] { + 19.10M, "Nineteen rupees ten paisa only" + }, + new object[] { + 19.88M, "Nineteen rupees eighty eight paisa only" + }, + new object[] { + 21M, "Twenty one rupees only" + }, + new object[] { + 21.01M, "Twenty one rupees one paisa only" + }, + new object[] { + 21.10M, "Twenty one rupees ten paisa only" + }, + new object[] { + 21.88M, "Twenty one rupees eighty eight paisa only" + }, + new object[] { + 100M, "One hundred rupees only" + }, + new object[] { + 100.01M, "One hundred rupees one paisa only" + }, + new object[] { + 100.10M, "One hundred rupees ten paisa only" + }, + new object[] { + 100.88M, "One hundred rupees eighty eight paisa only" + }, + new object[] { + 550M, "Five hundred fifty rupees only" + }, + new object[] { + 550.01M, "Five hundred fifty rupees one paisa only" + }, + new object[] { + 550.10M, "Five hundred fifty rupees ten paisa only" + }, + new object[] { + 550.88M, "Five hundred fifty rupees eighty eight paisa only" + }, + new object[] { + 555M, "Five hundred fifty five rupees only" + }, + new object[] { + 555.01M, "Five hundred fifty five rupees one paisa only" + }, + new object[] { + 555.10M, "Five hundred fifty five rupees ten paisa only" + }, + new object[] { + 555.88M, "Five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1555M, "One thousand five hundred fifty five rupees only" + }, + new object[] { + 1555.01M, "One thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 1555.10M, "One thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 1555.88M, "One thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 10555M, "Ten thousand five hundred fifty five rupees only" + }, + new object[] { + 10555.01M, "Ten thousand five hundred fifty five rupees one paisa only" + }, + new object[] { + 10555.10M, "Ten thousand five hundred fifty five rupees ten paisa only" + }, + new object[] { + 10555.88M, "Ten thousand five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1_00_000M, "One lakh rupees only" + }, + new object[] { + 1_00_000.01M, "One lakh rupees one paisa only" + }, + new object[] { + 1_00_000.10M, "One lakh rupees ten paisa only" + }, + new object[] { + 1_00_000.88M, "One lakh rupees eighty eight paisa only" + }, + new object[] { + 1_00_555.01M, "One lakh five hundred fifty five rupees one paisa only" + }, + new object[] { + 1_00_555.10M, "One lakh five hundred fifty five rupees ten paisa only" + }, + new object[] { + 1_00_555.88M, "One lakh five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 91_00_000M, "Ninety one lakh rupees only" + }, + new object[] { + 91_00_000.01M, "Ninety one lakh rupees one paisa only" + }, + new object[] { + 91_00_000.10M, "Ninety one lakh rupees ten paisa only" + }, + new object[] { + 91_00_000.88M, "Ninety one lakh rupees eighty eight paisa only" + }, + new object[] { + 91_00_555.01M, "Ninety one lakh five hundred fifty five rupees one paisa only" + }, + new object[] { + 91_00_555.10M, "Ninety one lakh five hundred fifty five rupees ten paisa only" + }, + new object[] { + 91_00_555.88M, "Ninety one lakh five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 9_01_00_000M, "Nine crore one lakh rupees only" + }, + new object[] { + 9_01_00_000.01M, "Nine crore one lakh rupees one paisa only" + }, + new object[] { + 9_01_00_000.10M, "Nine crore one lakh rupees ten paisa only" + }, + new object[] { + 9_01_00_000.88M, "Nine crore one lakh rupees eighty eight paisa only" + }, + new object[] { + 9_01_00_555.01M, "Nine crore one lakh five hundred fifty five rupees one paisa only" + }, + new object[] { + 9_01_00_555.10M, "Nine crore one lakh five hundred fifty five rupees ten paisa only" + }, + new object[] { + 9_01_00_555.88M, "Nine crore one lakh five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 90_91_00_000M, "Ninety crore ninety one lakh rupees only" + }, + new object[] { + 90_91_00_000.01M, "Ninety crore ninety one lakh rupees one paisa only" + }, + new object[] { + 90_91_00_000.10M, "Ninety crore ninety one lakh rupees ten paisa only" + }, + new object[] { + 90_91_00_000.88M, "Ninety crore ninety one lakh rupees eighty eight paisa only" + }, + new object[] { + 90_91_00_555.01M, "Ninety crore ninety one lakh five hundred fifty five rupees one paisa only" + }, + new object[] { + 90_91_00_555.10M, "Ninety crore ninety one lakh five hundred fifty five rupees ten paisa only" + }, + new object[] { + 90_91_00_555.88M, "Ninety crore ninety one lakh five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 46_29_09_00_000M, "Forty six arba twenty nine crore nine lakh rupees only" + }, + new object[] { + 46_29_09_00_000.01M, "Forty six arba twenty nine crore nine lakh rupees one paisa only" + }, + new object[] { + 46_29_09_00_000.10M, "Forty six arba twenty nine crore nine lakh rupees ten paisa only" + }, + new object[] { + 46_29_09_00_000.88M, "Forty six arba twenty nine crore nine lakh rupees eighty eight paisa only" + }, + new object[] { + 46_29_09_00_555.01M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees one paisa only" + }, + new object[] { + 46_29_09_00_555.10M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees ten paisa only" + }, + new object[] { + 46_29_09_00_555.88M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees eighty eight paisa only" + }, + new object[] { + 1M, "One rupees only" + }, + new object[] { + 10M, "Ten rupees only" + }, + new object[] { + 100M, "One hundred rupees only" + }, + new object[] { + 1_000M, "One thousand rupees only" + }, + new object[] { + 10_000M, "Ten thousand rupees only" + }, + new object[] { + 1_00_000M, "One lakh rupees only" + }, + new object[] { + 10_00_000M, "Ten lakh rupees only" + }, + new object[] { + 1_00_00_000M, "One crore rupees only" + }, + new object[] { + 10_00_00_000M, "Ten crore rupees only" + }, + new object[] { + 1_00_00_00_000M, "One arba rupees only" + }, + new object[] { + 10_00_00_00_000M, "Ten arba rupees only" + }, + new object[] { + 1_00_00_00_00_000M, "One kharba rupees only" + }, + new object[] { + 10_00_00_00_00_000M, "Ten kharba rupees only" + }, + new object[] { + 1_00_00_00_00_00_000M, "One neel rupees only" + }, + new object[] { + 10_00_00_00_00_00_000M, "Ten neel rupees only" + }, + new object[] { + 10_00_00_00_00_00_00_00_00_00_00_00_00_000M, "Ten Parardha rupees only" + } + }; - new object[] { 90_91_00_000M , "Ninety crore ninety one lakh rupees only" }, - new object[] { 90_91_00_000.01M, "Ninety crore ninety one lakh rupees one paisa only" }, - new object[] { 90_91_00_000.10M, "Ninety crore ninety one lakh rupees ten paisa only" }, - new object[] { 90_91_00_000.88M, "Ninety crore ninety one lakh rupees eighty eight paisa only" }, - new object[] { 90_91_00_555.01M, "Ninety crore ninety one lakh five hundred fifty five rupees one paisa only" }, - new object[] { 90_91_00_555.10M, "Ninety crore ninety one lakh five hundred fifty five rupees ten paisa only" }, - new object[] { 90_91_00_555.88M, "Ninety crore ninety one lakh five hundred fifty five rupees eighty eight paisa only" }, + [Test] + [TestCaseSource( nameof( WordCases ) )] + public void DecimalOnly( decimal amount, string words ) { + var amt = new CurrencyWordsConverter( new CurrencyWordsConversionOptions { + Culture = Culture.Nepali, OutputFormat = OutputFormat.English + } ); - new object[] { 46_29_09_00_000M , "Forty six arba twenty nine crore nine lakh rupees only" }, - new object[] { 46_29_09_00_000.01M, "Forty six arba twenty nine crore nine lakh rupees one paisa only" }, - new object[] { 46_29_09_00_000.10M, "Forty six arba twenty nine crore nine lakh rupees ten paisa only" }, - new object[] { 46_29_09_00_000.88M, "Forty six arba twenty nine crore nine lakh rupees eighty eight paisa only" }, - new object[] { 46_29_09_00_555.01M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees one paisa only" }, - new object[] { 46_29_09_00_555.10M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees ten paisa only" }, - new object[] { 46_29_09_00_555.88M, "Forty six arba twenty nine crore nine lakh five hundred fifty five rupees eighty eight paisa only" }, + var result = amt.ToWords( amount ); + Assert.AreEqual( words, result ); + } - new object[] { 1M, "One rupees only" }, - new object[] { 10M, "Ten rupees only" }, - new object[] { 100M, "One hundred rupees only" }, - new object[] { 1_000M, "One thousand rupees only" }, - new object[] { 10_000M, "Ten thousand rupees only" }, - new object[] { 1_00_000M, "One lakh rupees only" }, - new object[] { 10_00_000M, "Ten lakh rupees only" }, - new object[] { 1_00_00_000M, "One crore rupees only" }, - new object[] { 10_00_00_000M, "Ten crore rupees only" }, - new object[] { 1_00_00_00_000M, "One arba rupees only" }, - new object[] { 10_00_00_00_000M, "Ten arba rupees only" }, - new object[] { 1_00_00_00_00_000M, "One kharba rupees only" }, - new object[] { 10_00_00_00_00_000M, "Ten kharba rupees only" }, - new object[] { 1_00_00_00_00_00_000M, "One neel rupees only" }, - new object[] { 10_00_00_00_00_00_000M, "Ten neel rupees only" }, - new object[] { 10_00_00_00_00_00_00_00_00_00_00_00_00_000M, "Ten Parardha rupees only" }, - }; } - } \ No newline at end of file diff --git a/UnitTests/NumberConverterTest.cs b/UnitTests/NumberConverterTest.cs index 66b4469..1f7535f 100644 --- a/UnitTests/NumberConverterTest.cs +++ b/UnitTests/NumberConverterTest.cs @@ -1,60 +1,53 @@ -using NumericWordsConversion; -using NUnit.Framework; +namespace UnitTests { + + using NumericWordsConversion; + using NUnit.Framework; -namespace UnitTests -{ [TestFixture] - public class NumberConverterTest - { + public class NumberConverterTest { + [SetUp] - public void Setup() - { - NumericWordsConfiguration.ConfigureConversionDefaults(options => - { - options.SetDefaultNumericWordsOptions(new NumericWordsConversionOptions - { - DecimalPlaces = 2 - }); - }); + public void Setup() { + NumericWordsConfiguration.ConfigureConversionDefaults( options => OptionsInitializer.SetDefaultNumericWordsOptions( new NumericWordsConversionOptions { + DecimalPlaces = 2 + } ) ); } - [Test, TestCaseSource(nameof(TestCases))] - public string MyTestCases(decimal amount) - { - NumericWordsConverter amt = new NumericWordsConverter(new NumericWordsConversionOptions(){DecimalPlaces = 4}); - string result = amt.ToWords(amount); + private static readonly TestCaseData[] StaticExtensionEnglishCases = { + new TestCaseData( 0M ).Returns( "Zero" ), new TestCaseData( 0.001M ).Returns( "Zero" ), new TestCaseData( 0.01M ).Returns( "Zero point zero one" ), + new TestCaseData( 100M ).Returns( "One hundred" ), new TestCaseData( 10555.01M ).Returns( "Ten thousand five hundred fifty five point zero one" ), + new TestCaseData( 99_000M ).Returns( "Ninety nine thousand" ), new TestCaseData( 99_000.1M ).Returns( "Ninety nine thousand point one" ), + new TestCaseData( 10_000_000_000_000_000_000_000_000_000M ).Returns( "Ten octillion" ) + }; + + private static readonly TestCaseData[] TestCases = { + new TestCaseData( 0M ).Returns( "Zero" ), new TestCaseData( 0.001M ).Returns( "Zero point zero zero one" ), + new TestCaseData( 0.01M ).Returns( "Zero point zero one" ), new TestCaseData( 100M ).Returns( "One hundred" ), + new TestCaseData( 10555.01M ).Returns( "Ten thousand five hundred fifty five point zero one" ), new TestCaseData( 99_000M ).Returns( "Ninety nine thousand" ), + new TestCaseData( 99_000.1M ).Returns( "Ninety nine thousand point one" ), new TestCaseData( 10_000_000_000_000_000_000_000_000_000M ).Returns( "Ten octillion" ) + }; + + [Test] + [TestCaseSource( nameof( TestCases ) )] + public string MyTestCases( decimal amount ) { + var amt = new NumericWordsConverter( new NumericWordsConversionOptions { + DecimalPlaces = 4 + } ); + + var result = amt.ToWords( amount ); + return result; } - [Test, TestCaseSource(nameof(StaticExtensionEnglishCases))] - public string StaticExtensionEnglish(decimal amount) - { + [Test] + [TestCaseSource( nameof( StaticExtensionEnglishCases ) )] + public string StaticExtensionEnglish( decimal amount ) { + + var result = amount.ToNumericWords(); - string result = amount.ToNumericWords(); return result; } - private static readonly TestCaseData[] StaticExtensionEnglishCases = - { - new TestCaseData(0M).Returns("Zero"), - new TestCaseData(0.001M).Returns("Zero"), - new TestCaseData(0.01M).Returns("Zero point zero one"), - new TestCaseData(100M).Returns("One hundred"), - new TestCaseData(10555.01M).Returns("Ten thousand five hundred fifty five point zero one"), - new TestCaseData(99_000M).Returns("Ninety nine thousand"), - new TestCaseData(99_000.1M).Returns("Ninety nine thousand point one"), - new TestCaseData( 10_000_000_000_000_000_000_000_000_000M).Returns("Ten octillion"), - }; - private static readonly TestCaseData[] TestCases = - { - new TestCaseData(0M).Returns("Zero"), - new TestCaseData(0.001M).Returns("Zero point zero zero one"), - new TestCaseData(0.01M).Returns("Zero point zero one"), - new TestCaseData(100M).Returns("One hundred"), - new TestCaseData(10555.01M).Returns("Ten thousand five hundred fifty five point zero one"), - new TestCaseData(99_000M).Returns("Ninety nine thousand"), - new TestCaseData(99_000.1M).Returns("Ninety nine thousand point one"), - new TestCaseData( 10_000_000_000_000_000_000_000_000_000M).Returns("Ten octillion"), - }; } + } \ No newline at end of file diff --git a/UnitTests/ToUnicodeWords.cs b/UnitTests/ToUnicodeWords.cs index 3537f7f..6542465 100644 --- a/UnitTests/ToUnicodeWords.cs +++ b/UnitTests/ToUnicodeWords.cs @@ -3,6 +3,9 @@ namespace UnitTests { + + using System; + public class ToUnicodeWords { public CurrencyWordsConverter amtToWords { get; set; } @@ -10,7 +13,7 @@ public class ToUnicodeWords [SetUp] public void Setup() { - amtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions + this.amtToWords = new CurrencyWordsConverter(new CurrencyWordsConversionOptions { Culture = Culture.Nepali, OutputFormat = OutputFormat.Unicode, @@ -20,48 +23,48 @@ public void Setup() [Test] public void ZeroPaisa() { - string actualResult = amtToWords.ToWords(32152M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ मात्र"; + var actualResult = this.amtToWords.ToWords(32152M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void OnePaisa() { - string actualResult = amtToWords.ToWords(32152.01M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एक पैसा मात्र"; + var actualResult = this.amtToWords.ToWords(32152.01M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एक पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void TenPaisa() { - string actualResult = amtToWords.ToWords(32152.10M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ दस पैसा मात्र"; + var actualResult = this.amtToWords.ToWords(32152.10M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ दस पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ElevenPaisa() { - string actualResult = amtToWords.ToWords(32152.11M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एघार पैसा मात्र"; + var actualResult = this.amtToWords.ToWords(32152.11M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ एघार पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void ThirtyPaisa() { - string actualResult = amtToWords.ToWords(32152.30M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ तीस पैसा मात्र"; + var actualResult = this.amtToWords.ToWords(32152.30M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ तीस पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } [Test] public void EightyEightPaisa() { - string actualResult = amtToWords.ToWords(32152.88M); - string expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; + var actualResult = this.amtToWords.ToWords(32152.88M); + const String expectedResult = "बतीस हजार एक सय बाउन्न रूपैयाँ अठासी पैसा मात्र"; Assert.AreEqual(expectedResult, actualResult); } diff --git a/UnitTests/UnitTests.csproj b/UnitTests/UnitTests.csproj index d57073a..4bf8d18 100644 --- a/UnitTests/UnitTests.csproj +++ b/UnitTests/UnitTests.csproj @@ -1,15 +1,26 @@  - netcoreapp3.0 + netcoreapp3.1 false + + DEBUG;TRACE + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + diff --git a/UnitTests/UnitTests.csproj.DotSettings b/UnitTests/UnitTests.csproj.DotSettings new file mode 100644 index 0000000..9c5cada --- /dev/null +++ b/UnitTests/UnitTests.csproj.DotSettings @@ -0,0 +1,3 @@ + + CSharp80 + True \ No newline at end of file