mirror of
https://github.com/SeedSigner/seedsigner.git
synced 2026-10-05 15:08:25 +00:00
adds test coverage
This commit is contained in:
+41
@@ -0,0 +1,41 @@
|
|||||||
|
[run]
|
||||||
|
branch = True
|
||||||
|
|
||||||
|
[report]
|
||||||
|
show_missing = True
|
||||||
|
skip_empty = True
|
||||||
|
skip_covered = True
|
||||||
|
|
||||||
|
# Omit; need a different approach to test modules with hardware dependencies
|
||||||
|
omit =
|
||||||
|
*/__init__.py
|
||||||
|
*/tests/*
|
||||||
|
*/pyzbar/*
|
||||||
|
*/gui/*
|
||||||
|
|
||||||
|
# Regexes for lines to exclude from consideration
|
||||||
|
exclude_lines =
|
||||||
|
# Have to re-enable the standard pragma
|
||||||
|
pragma: no cover
|
||||||
|
|
||||||
|
# Don't complain about missing debug-only code:
|
||||||
|
def __repr__
|
||||||
|
def __str__
|
||||||
|
if self\.debug
|
||||||
|
|
||||||
|
# Don't complain if tests don't hit defensive assertion code:
|
||||||
|
raise AssertionError
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
# Don't complain if non-runnable code isn't run:
|
||||||
|
if 0:
|
||||||
|
if __name__ == .__main__.:
|
||||||
|
|
||||||
|
# Don't complain about abstract methods, they aren't run:
|
||||||
|
@(abc\.)?abstractmethod
|
||||||
|
|
||||||
|
|
||||||
|
[html]
|
||||||
|
directory = coverage_html_report
|
||||||
|
skip_empty = True
|
||||||
|
skip_covered = False
|
||||||
@@ -6,3 +6,4 @@ src/seedsigner.egg-info/
|
|||||||
src/seedsigner/models/settings_definition.json
|
src/seedsigner/models/settings_definition.json
|
||||||
.idea
|
.idea
|
||||||
*.mo
|
*.mo
|
||||||
|
.coverage
|
||||||
|
|||||||
@@ -24,3 +24,19 @@ Run a specific test:
|
|||||||
```
|
```
|
||||||
pytest tests/test_this_file.py::test_this_specific_test
|
pytest tests/test_this_file.py::test_this_specific_test
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Test Coverage
|
||||||
|
Run tests and generate test coverage
|
||||||
|
```
|
||||||
|
coverage run -m pytest
|
||||||
|
```
|
||||||
|
|
||||||
|
Show the resulting test coverage details:
|
||||||
|
```
|
||||||
|
coverage report --show-missing
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate the html overview:
|
||||||
|
```
|
||||||
|
coverage html
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
|
coverage==7.2.1
|
||||||
|
mock==4.0.3
|
||||||
pytest==6.2.4
|
pytest==6.2.4
|
||||||
mock==4.0.3
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import pytest
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from embit import bip39
|
from embit import bip39
|
||||||
@@ -42,6 +43,31 @@ def test_calculate_checksum():
|
|||||||
assert bip39.mnemonic_is_valid(" ".join(mnemonic))
|
assert bip39.mnemonic_is_valid(" ".join(mnemonic))
|
||||||
|
|
||||||
|
|
||||||
|
def test_calculate_checksum_invalid_mnemonics():
|
||||||
|
"""
|
||||||
|
Should raise an Exception on a mnemonic that is invalid due to length or using invalid words.
|
||||||
|
"""
|
||||||
|
with pytest.raises(Exception) as e:
|
||||||
|
# Mnemonic is too short: 10 words instead of 11
|
||||||
|
partial_mnemonic = "abandon " * 9 + "about"
|
||||||
|
mnemonic_generation.calculate_checksum(partial_mnemonic.split(" "), wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH)
|
||||||
|
|
||||||
|
with pytest.raises(Exception) as e:
|
||||||
|
# Valid mnemonic but unsupported length
|
||||||
|
mnemonic = "devote myth base logic dust horse nut collect buddy element eyebrow visit empty dress jungle"
|
||||||
|
mnemonic_generation.calculate_checksum(mnemonic.split(" "), wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH)
|
||||||
|
|
||||||
|
with pytest.raises(Exception) as e:
|
||||||
|
# Mnemonic is too short: 22 words instead of 23
|
||||||
|
partial_mnemonic = "abandon " * 21 + "about"
|
||||||
|
mnemonic_generation.calculate_checksum(partial_mnemonic.split(" "), wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH)
|
||||||
|
|
||||||
|
with pytest.raises(Exception) as e:
|
||||||
|
# Invalid BIP-39 word
|
||||||
|
partial_mnemonic = "foobar " * 9 + "about"
|
||||||
|
mnemonic_generation.calculate_checksum(partial_mnemonic.split(" "), wordlist_language_code=SettingsConstants.WORDLIST_LANGUAGE__ENGLISH)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_calculate_checksum_with_default_final_word():
|
def test_calculate_checksum_with_default_final_word():
|
||||||
""" 11-word and 23-word mnemonics use word `0000` as a temp final word to complete
|
""" 11-word and 23-word mnemonics use word `0000` as a temp final word to complete
|
||||||
@@ -62,6 +88,22 @@ def test_calculate_checksum_with_default_final_word():
|
|||||||
assert mnemonic1 == mnemonic2
|
assert mnemonic1 == mnemonic2
|
||||||
|
|
||||||
|
|
||||||
|
def test_generate_mnemonic_from_bytes():
|
||||||
|
"""
|
||||||
|
Should generate a valid BIP-39 mnemonic from entropy bytes
|
||||||
|
"""
|
||||||
|
# From iancoleman.io
|
||||||
|
entropy = "3350f6ac9eeb07d2c6209932808aa7f6"
|
||||||
|
expected_mnemonic = "crew marble private differ race truly blush basket crater affair prepare unique".split()
|
||||||
|
mnemonic = mnemonic_generation.generate_mnemonic_from_bytes(bytes.fromhex(entropy))
|
||||||
|
assert mnemonic == expected_mnemonic
|
||||||
|
|
||||||
|
entropy = "5bf41629fce815c3570955e8f45422abd7e2234141bd4d7ec63b741043b98cad"
|
||||||
|
expected_mnemonic = "fossil pass media what life ticket found click trophy pencil anger fish lawsuit balance agree dash estate wage mom trial aerobic system crawl review".split()
|
||||||
|
mnemonic = mnemonic_generation.generate_mnemonic_from_bytes(bytes.fromhex(entropy))
|
||||||
|
assert mnemonic == expected_mnemonic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def test_verify_against_coldcard_sample():
|
def test_verify_against_coldcard_sample():
|
||||||
""" https://coldcard.com/docs/verifying-dice-roll-math """
|
""" https://coldcard.com/docs/verifying-dice-roll-math """
|
||||||
|
|||||||
Reference in New Issue
Block a user