Repository: OpenVoiceOS/ovos-number-parser
Pull request #19: Add first simple unittests for english and danish
Author: login: tgc-dk
Created: 2025-03-14T07:54:30Z | Merged: 2025-03-25T21:44:50Z



<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
	- Enhanced the accuracy of Danish number pronunciation, including corrections to specific phrases and improved logic for number representation.
- **Tests**
	- Added comprehensive unit tests for Danish and English number parsing and pronunciation functionalities, covering various inputs and edge cases.
	- Introduced a new GitHub Actions workflow for automated unit testing across multiple Python versions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml
new file mode 100644
index 0000000..58e7454
--- /dev/null
+++ b/.github/workflows/unit_tests.yml
@@ -0,0 +1,63 @@
+# This workflow will run unit tests
+
+name: Run Unit Tests
+on:
+  pull_request:
+    branches:
+      - dev
+    paths-ignore:
+      - 'ovos_number_parser/version.py'
+      - '.github/**'
+      - '.gitignore'
+      - 'LICENSE'
+      - 'CHANGELOG.md'
+      - 'MANIFEST.in'
+      - 'README.md'
+  push:
+    branches:
+      - master
+    paths-ignore:
+      - 'ovos_number_parser/version.py'
+      - '.github/**'
+      - '.gitignore'
+      - 'LICENSE'
+      - 'CHANGELOG.md'
+      - 'MANIFEST.in'
+      - 'README.md'
+  workflow_dispatch:
+
+jobs:
+  unit_tests:
+    strategy:
+      max-parallel: 2
+      matrix:
+        python-version: [ 3.9, "3.10" ]
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install System Dependencies
+        run: |
+          sudo apt-get update
+          sudo apt install python3-dev
+          python -m pip install build wheel unicode-rbnf
+      - name: Install core repo
+        run: |
+          pip install -e .[extras]
+      - name: Install test dependencies
+        run: |
+          pip install pytest pytest-timeout pytest-cov
+      - name: Run unittests
+        run: |
+          pytest --cov=ovos_utils --cov-report xml tests/
+          # NOTE: additional pytest invocations should also add the --cov-append flag
+          #       or they will overwrite previous invocations' coverage reports
+          #       (for an example, see OVOS Skill Manager's workflow)
+      - name: Upload coverage
+        if: "${{ matrix.python-version == '3.9' }}"
+        env:
+          CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
+        uses: codecov/codecov-action@v2
diff --git a/ovos_number_parser/numbers_da.py b/ovos_number_parser/numbers_da.py
index bba6af6..f0ab53e 100644
--- a/ovos_number_parser/numbers_da.py
+++ b/ovos_number_parser/numbers_da.py
@@ -40,7 +40,7 @@
     'niogtyve': 29,
     'tredive': 30,
     'enogtredive': 31,
-    'fyrrre': 40,
+    'fyrre': 40,
     'halvtres': 50,
     'tres': 60,
     'halvfjers': 70,
@@ -255,7 +255,7 @@ def is_ordinal_da(input_str):
 def nice_number_da(number, speech=True, denominators=range(1, 21)):
     """ Danish helper for nice_number
     This function formats a float to human understandable functions. Like
-    4.5 becomes "4 einhalb" for speech and "4 1/2" for text
+    4.5 becomes "4 en halv" for speech and "4 1/2" for text
     Args:
         number (int or float): the float to format
         speech (bool): format for speech (True) or display (False)
@@ -377,10 +377,8 @@ def pronounce_whole_number_da(num, scale_level=0):
             if scale_level == 1:
                 result += 'tusinde' + _EXTRA_SPACE_DA
             if scale_level >= 2:
-                result += "og" + _NUM_POWERS_OF_TEN[scale_level]
+                result += ' ' + _NUM_POWERS_OF_TEN[scale_level]
             if scale_level >= 2:
-                if scale_level % 2 == 0:
-                    result += "er"  # MillionER
                 result += "er "  # MilliardER, MillioneER
 
         num = floor(num / 1000)
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tests/test_number_parser_da.py b/tests/test_number_parser_da.py
new file mode 100644
index 0000000..0a12342
--- /dev/null
+++ b/tests/test_number_parser_da.py
@@ -0,0 +1,25 @@
+import unittest
+from ovos_number_parser.numbers_da import numbers_to_digits_da, pronounce_number_da, pronounce_ordinal_da
+
+
+class TestNumberParserDA(unittest.TestCase):
+    def test_numbers_to_digits_da(self):
+        self.assertEqual(numbers_to_digits_da('tre billiarder'), '3000000000000000.0')
+        self.assertEqual(numbers_to_digits_da('den fjerde marts totusinde og femogtyve', ordinals=False),
+                         'den fjerde marts 2025')
+        self.assertEqual(numbers_to_digits_da('den fjerde marts totusinde og femogtyve', ordinals=True),
+                         'den 4 marts 2025')
+        self.assertEqual(numbers_to_digits_da('to komma fem'), '2.5')
+        self.assertEqual(numbers_to_digits_da('to komma fire to'), '2.42')
+
+    def test_pronounce_number_da(self):
+        self.assertEqual(pronounce_number_da(3840285766987249),
+            'tre billiarder ottehundredefyrre billioner tohundredefemogfirs milliarder '
+            'syvhundredeseksogtres millioner nihundredesyvogfirstusindetohundredeniogfyrre')
+        # test endings, singular vs plural
+        self.assertEqual(pronounce_number_da(1000000), 'en million ')
+        self.assertEqual(pronounce_number_da(2000000), 'to millioner ')
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/test_number_parser_en.py b/tests/test_number_parser_en.py
new file mode 100644
index 0000000..2944bf8
--- /dev/null
+++ b/tests/test_number_parser_en.py
@@ -0,0 +1,28 @@
+import unittest
+from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en
+
+
+class TestNumberParserEN(unittest.TestCase):
+    def test_numbers_to_digits_en(self):
+        self.assertEqual(numbers_to_digits_en('three billions'), '3000000000.0')
+        self.assertEqual(numbers_to_digits_en('two point five'), '2.5')
+        self.assertEqual(numbers_to_digits_en('two point forty two'), '2.42')
+
+    @unittest.expectedFailure
+    def test_failures_numbers_to_digits_en(self):
+        # TODO: fix the ordinal handling! The 2 tests below actually fails
+        self.assertEqual(numbers_to_digits_en('march fifth two thousand twenty five', ordinals=False),
+                         'march fifth 2025')
+        self.assertEqual(numbers_to_digits_en('march fifth two thousand twenty five', ordinals=True),
+                         'march 0.2 2025')
+        # TODO: fix the scenario below!
+        self.assertEqual(numbers_to_digits_en('two point four two'), '2.42')
+
+    def test_pronounce_number_en(self):
+        self.assertEqual(pronounce_number_en(3840285766987249),
+            'three quadrillion, eight hundred and forty trillion, two hundred and eighty five billion, seven hundred '
+            'and sixty six million, nine hundred and eighty seven thousand, two hundred and forty nine')
+
+
+if __name__ == "__main__":
+    unittest.main()


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 1**

<details>
<summary>🧹 Nitpick comments (2)</summary><blockquote>

<details>
<summary>tests/test_number_parser_da.py (1)</summary><blockquote>

`1-2`: **Remove unused import.**

The import for `pronounce_ordinal_da` is not used in any of the test methods.

```diff
- from ovos_number_parser.numbers_da import numbers_to_digits_da, pronounce_number_da, pronounce_ordinal_da
+ from ovos_number_parser.numbers_da import numbers_to_digits_da, pronounce_number_da
```

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Ruff (0.8.2)</summary>

2-2: `ovos_number_parser.numbers_da.pronounce_ordinal_da` imported but unused

Remove unused import: `ovos_number_parser.numbers_da.pronounce_ordinal_da`

(F401)

</details>

</details>

</blockquote></details>
<details>
<summary>tests/test_number_parser_en.py (1)</summary><blockquote>

`6-17`: **Include TODOs as separate issues instead of failing tests.**

The test contains assertions that are expected to fail with comments about needed fixes. This is not ideal for a test suite as tests should pass. Consider:

1. Creating GitHub issues for the TODOs
2. Using `unittest.expectedFailure` decorator or `skip` for the tests that are known to fail
3. Implementing the fixes for these scenarios


Example of using `expectedFailure`:
```python
@unittest.expectedFailure
def test_ordinal_handling(self):
    self.assertEqual(numbers_to_digits_en('march fifth two thousand twenty five', ordinals=True),
                     'march 5 2025')
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between c23de9c149c11db178ef0fbb5e84f744b26058a7 and 29efc9bdecf45e2031ab9510af40d2b860210f89.

</details>

<details>
<summary>📒 Files selected for processing (3)</summary>

* `ovos_number_parser/numbers_da.py` (1 hunks)
* `tests/test_number_parser_da.py` (1 hunks)
* `tests/test_number_parser_en.py` (1 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🪛 Ruff (0.8.2)</summary>

<details>
<summary>tests/test_number_parser_da.py</summary>

2-2: `ovos_number_parser.numbers_da.pronounce_ordinal_da` imported but unused

Remove unused import: `ovos_number_parser.numbers_da.pronounce_ordinal_da`

(F401)

</details>
<details>
<summary>tests/test_number_parser_en.py</summary>

2-2: Redefinition of unused `pronounce_number_en` from line 2

Remove definition: `pronounce_number_en`

(F811)

</details>

</details>

</details>

<details>
<summary>🔇 Additional comments (4)</summary><blockquote>

<details>
<summary>tests/test_number_parser_da.py (2)</summary>

`6-14`: **LGTM! Good test coverage for Danish number digit conversion.**

The test method validates multiple scenarios including large numbers, ordinals, and decimals.

---

`15-22`: **LGTM! Good test for Danish number pronunciation.**

The test covers large numbers and checks singular vs plural forms correctly.

</details>
<details>
<summary>ovos_number_parser/numbers_da.py (1)</summary>

`380-380`: **Pronunciation change for Danish large numbers.**

The connector "og" (meaning "and") has been replaced with a simple space when adding the power of ten string. This makes the pronunciation more natural in Danish.

</details>
<details>
<summary>tests/test_number_parser_en.py (1)</summary>

`18-22`: **LGTM! Good test for English number pronunciation.**

The test validates that large numbers are correctly pronounced with the expected formatting.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T07:56:25Z
user: login: tgc-dk
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T08:07:35Z
user: login: coderabbitai[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-03-14T08:07:56Z

Review comments:
diff_hunk: @@ -0,0 +1,25 @@
+import unittest
+from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en, pronounce_number_en
path: tests/test_number_parser_en.py
user: login: coderabbitai[bot]
body: _⚠️ Potential issue_

**Fix duplicate import.**

The `pronounce_number_en` function is imported twice, which is redundant.

```diff
- from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en, pronounce_number_en
+ from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en
```


<!-- suggestion_start -->

<details>
<summary>📝 Committable suggestion</summary>

> ‼️ **IMPORTANT**
> Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

`````suggestion
import unittest
from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en
`````

</details>

<!-- suggestion_end -->

<details>
<summary>🧰 Tools</summary>

<details>
<summary>🪛 Ruff (0.8.2)</summary>

2-2: Redefinition of unused `pronounce_number_en` from line 2

Remove definition: `pronounce_number_en`

(F811)

</details>

</details>

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-14T07:56:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+import unittest
+from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en, pronounce_number_en
path: tests/test_number_parser_en.py
user: login: tgc-dk
body: fixed
created_at: 2025-03-14T08:07:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,25 @@
+import unittest
+from ovos_number_parser.numbers_en import numbers_to_digits_en, pronounce_number_en, pronounce_number_en
path: tests/test_number_parser_en.py
user: login: coderabbitai[bot]
body: @tgc-dk Thanks for fixing the duplicate import issue! The tests will now be cleaner.

---

<!-- This is an auto-generated comment: tweet message by coderabbit.ai -->

If you found this review helpful, would you consider giving us a shout-out on [X](https://twitter.com/intent/tweet?related=CodeRabbitAI&text=Just%20fixed%20a%20redundant%20import%20in%20our%20code!%20%F0%9F%9A%80%20Thanks%20to%20%40coderabbitai%20for%20the%20keen%20eye%20on%20optimizing%20our%20imports.%20Every%20little%20detail%20counts!%20%F0%9F%92%A1&url=https%3A%2F%2Fgithub.com%2FOpenVoiceOS%2Fovos-number-parser%2Fpull%2F19%23discussion_r1995045916)?
							Thank you for using CodeRabbit!

<!-- end of auto-generated comment: tweet message by coderabbit.ai -->

<!-- This is an auto-generated reply by CodeRabbit -->
created_at: 2025-03-14T08:07:56Z
author_association: CONTRIBUTOR

PR comments:
user: login: coderabbitai[bot]
created_at: 2025-03-14T07:54:38Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough
This pull request updates the Danish number pronunciation logic by correcting the representation of certain numbers and modifying the construction of result strings. Specifically, the connector "og" has been replaced with a space, and the condition that appended "er" for even scale levels has been removed. Additionally, new unit tests have been introduced for both Danish and English number parsing, which verify the conversion of phrases to digits and the pronunciation of large numbers. No changes were made to the exported public entities.

## Changes
| File(s)                                                                 | Summary                                                                                                                                                     |
|-------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `ovos_number_parser/numbers_da.py`                                      | Corrected the pronunciation of the number 40 and updated documentation for the `nice_number_da` function. Modified `pronounce_whole_number_da` logic.      |
| `tests/test_number_parser_da.py`, `tests/test_number_parser_en.py`      | Added new test files with classes (`TestNumberParserDA` and `TestNumberParserEN`) to verify Danish and English number parsing and pronunciation functionality. |
| `.github/workflows/unit_tests.yml`                                       | Introduced a new GitHub Actions workflow for automating unit tests, triggered on pull requests and pushes, with support for Python versions 3.9 and 3.10.    |

## Poem
> I'm a rabbit with a knack for numbers so bright,  
> Hopping through code changes in the soft morning light.  
> "og" has hopped away, replaced by a gentle space,  
> Even scales shed old rules, leaving a cleaner trace.  
> Tests in Danish and English now dance in true delight,  
> Carrots and code—hurray for progress done right!

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Free**

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between a001f6a474f7c22ada30176722831e43f04eaa72 and b1caa9c160188d33da1dfc891c292d1684f7f719.

</details>

<details>
<summary>📒 Files selected for processing (1)</summary>

* `tests/test_number_parser_en.py` (1 hunks)

</details>

</details>
<!-- internal state start -->


<!-- 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= -->

<!-- internal state end -->
<!-- tips_start -->

---

> [!NOTE]
> <details>
> <summary>🎁 Summarized by CodeRabbit Free</summary>
> 
> Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting <https://app.coderabbit.ai/login>.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.
> 
> </details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=OpenVoiceOS/ovos-number-parser&utm_content=19):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Generate unit testing code for this file.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai generate unit testing code for this file.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and generate unit testing code.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai plan` to trigger planning for file edits and PR creation.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@coderabbitai` anywhere in the PR title to generate the title automatically.

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) for more information.
- If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: `# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR
user: login: JarbasAl
created_at: 2025-03-14T08:53:52Z
body: awesome work!

can you also add a .yml to .github/workflows so these tests run on every PR?

eg. something like this one https://github.com/OpenVoiceOS/ovos-utils/blob/dev/.github/workflows/unit_tests.yml

author_association: MEMBER
user: login: JarbasAl
created_at: 2025-03-14T08:56:52Z
body: by the way, this repository was split from lingua-franca and we have plenty more tests to port over to this repo https://github.com/OpenVoiceOS/ovos-lingua-franca/tree/dev/test/unittests 

no danish support there but might be useful
author_association: MEMBER
user: login: tgc-dk
created_at: 2025-03-25T20:52:07Z
body: I've added the unittest workflow, should be a good starting point :)
author_association: CONTRIBUTOR