diff --git a/requirements.txt b/requirements.txt index f33a851ad61ff13189369876aa6029646c2680d1..c4379dc46caef502b33db85fe8b273c1058bd20a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ ucoinpy>=0.13 -git+https://github.com/Insoleet/quamash.git@qeventloop +git+https://github.com/harvimt/quamash.git@gh45 asynctest git+https://github.com/networkx/networkx.git@v1.11 \ No newline at end of file diff --git a/setup.py b/setup.py index e4e3db248753841e740fa5abd43ebb137acaccfe..4cdfe1a466d7d481e36be932054b2f88af6d086c 100644 --- a/setup.py +++ b/setup.py @@ -124,7 +124,7 @@ else: setup( name = "sakia", - version = "0.11.4", + version = "0.12.0", description = "UCoin client", author = "Inso", options = {"build_exe": options}, diff --git a/src/sakia/__init__.py b/src/sakia/__init__.py index e92e1772fccf93ff2627cba943fed2e5091cbfbf..993750a514d8123b5e23027dc8e44da36df81c60 100644 --- a/src/sakia/__init__.py +++ b/src/sakia/__init__.py @@ -1,2 +1,2 @@ -__version_info__ = ('0', '11', '3') +__version_info__ = ('0', '11', '5') __version__ = '.'.join(__version_info__) diff --git a/src/sakia/core/community.py b/src/sakia/core/community.py index bc97eddeb913a1d9a7976a7e4c9772b4ef674204..e9104305ccad82bd1cac164f5bc00b991c0056fd 100644 --- a/src/sakia/core/community.py +++ b/src/sakia/core/community.py @@ -116,13 +116,16 @@ class Community(QObject): u = ord('\u24B6') + ord(letter) - ord('A') return chr(u) - async def dividend(self): + async def dividend(self, block_number=None): """ - Get the last generated community universal dividend. + Get the last generated community universal dividend before block_number. + If block_number is None, returns the last block_number. + + :param int block_number: The block at which we get the latest dividend :return: The last UD or 1 if no UD was generated. """ - block = await self.get_ud_block() + block = await self.get_ud_block(block_number=block_number) if block: return block['dividend'] else: @@ -152,18 +155,24 @@ class Community(QObject): else: return 1 - async def get_ud_block(self, x=0): + async def get_ud_block(self, x=0, block_number=None): """ Get a block with universal dividend + If x and block_number are passed to the result, + it returns the 'x' older block with UD in it BEFORE block_number :param int x: Get the 'x' older block with UD in it + :param int block_number: Get the latest dividend before this block number :return: The last block with universal dividend. + :rtype: dict """ try: udblocks = await self.bma_access.future_request(bma.blockchain.UD) blocks = udblocks['result']['blocks'] + if block_number: + blocks = [b for b in blocks if b <= block_number] if len(blocks) > 0: - index = len(blocks)-(1+x) + index = len(blocks) - (1+x) if index < 0: index = 0 block_number = blocks[index] diff --git a/src/sakia/core/money/__init__.py b/src/sakia/core/money/__init__.py index 05a4b506a6ff4f03c503992f6cae11774a6a4ab1..21b04a8f501cfb26ba65419a6e3590b5d54bb331 100644 --- a/src/sakia/core/money/__init__.py +++ b/src/sakia/core/money/__init__.py @@ -2,5 +2,6 @@ from .quantitative import Quantitative from .relative import Relative from .quant_zerosum import QuantitativeZSum from .relative_zerosum import RelativeZSum +from .relative_to_past import RelativeToPast -Referentials = (Quantitative, Relative, QuantitativeZSum, RelativeZSum) +Referentials = (Quantitative, Relative, QuantitativeZSum, RelativeZSum, RelativeToPast) diff --git a/src/sakia/core/money/base_referential.py b/src/sakia/core/money/base_referential.py new file mode 100644 index 0000000000000000000000000000000000000000..4040074b7695f74c10cd3d464da2cb4fbe3bed37 --- /dev/null +++ b/src/sakia/core/money/base_referential.py @@ -0,0 +1,41 @@ +from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale +import asyncio + + +class BaseReferential: + """ + Interface to all referentials + """ + def __init__(self, amount, community, app, block_number=None): + self.amount = amount + self.community = community + self.app = app + self._block_number = block_number + + @classmethod + def translated_name(self): + pass + + @property + def units(self): + pass + + @property + def diff_units(self): + pass + + async def value(self): + pass + + async def differential(self): + pass + + @staticmethod + def to_si(value, digits): + pass + + async def localized(self, units=False, international_system=False): + pass + + async def diff_localized(self, units=False, international_system=False): + pass diff --git a/src/sakia/core/money/quant_zerosum.py b/src/sakia/core/money/quant_zerosum.py index 2c63322514e1d69c2952869965da43c8d61ab421..98f1f1c26569db4de65c5c729e314d31d4b5ef9e 100644 --- a/src/sakia/core/money/quant_zerosum.py +++ b/src/sakia/core/money/quant_zerosum.py @@ -1,29 +1,27 @@ from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale from . import Quantitative -import asyncio +from .base_referential import BaseReferential -class QuantitativeZSum: +class QuantitativeZSum(BaseReferential): _NAME_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', 'Quant Z-sum') - _REF_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "{0} Q0 {1}") + _REF_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "{0} {1}Q0 {2}") _UNITS_STR_ = QT_TRANSLATE_NOOP('QuantitativeZSum', "Q0 {0}") - def __init__(self, amount, community, app): - self.amount = amount - self.community = community - self.app = app + def __init__(self, amount, community, app, block_number=None): + super().__init__(amount, community, app, block_number) @classmethod def translated_name(cls): return QCoreApplication.translate('QuantitativeZSum', QuantitativeZSum._NAME_STR_) - @classmethod - def units(cls, currency): - return QCoreApplication.translate("QuantitativeZSum", QuantitativeZSum._UNITS_STR_).format(currency) + @property + def units(self): + return QCoreApplication.translate("QuantitativeZSum", QuantitativeZSum._UNITS_STR_).format(self.community.short_currency) - @classmethod - def diff_units(cls, currency): - return Quantitative.units(currency) + @property + def diff_units(self): + return self.units async def value(self): """ @@ -43,7 +41,7 @@ class QuantitativeZSum: ud_block = await self.community.get_ud_block() if ud_block and ud_block['membersCount'] > 0: monetary_mass = await self.community.monetary_mass() - average = monetary_mass / ud_block['membersCount'] + average = int(monetary_mass / ud_block['membersCount']) else: average = 0 return self.amount - average @@ -60,10 +58,11 @@ class QuantitativeZSum: else: localized_value = QLocale().toString(float(value), 'f', 0) - if units: + if units or international_system: return QCoreApplication.translate("QuantitativeZSum", QuantitativeZSum._REF_STR_) \ .format(localized_value, + prefix, self.community.short_currency if units else "") else: return localized_value diff --git a/src/sakia/core/money/quantitative.py b/src/sakia/core/money/quantitative.py index 811ff8f0c9cd2473410576f7d513f5ce176373ca..d1d07c151059c58ed1336fcf0da2b981c5b6666e 100644 --- a/src/sakia/core/money/quantitative.py +++ b/src/sakia/core/money/quantitative.py @@ -1,28 +1,26 @@ -from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QObject, QLocale -import asyncio +from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale +from .base_referential import BaseReferential -class Quantitative(): +class Quantitative(BaseReferential): _NAME_STR_ = QT_TRANSLATE_NOOP('Quantitative', 'Units') _REF_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0} {1}{2}") _UNITS_STR_ = QT_TRANSLATE_NOOP('Quantitative', "{0}") - def __init__(self, amount, community, app): - self.amount = amount - self.community = community - self.app = app + def __init__(self, amount, community, app, block_number=None): + super().__init__(amount, community, app, block_number) @classmethod def translated_name(cls): return QCoreApplication.translate('Quantitative', Quantitative._NAME_STR_) - @classmethod - def units(cls, currency): - return QCoreApplication.translate("Quantitative", Quantitative._UNITS_STR_).format(currency) + @property + def units(self): + return QCoreApplication.translate("Quantitative", Quantitative._UNITS_STR_).format(self.community.short_currency) - @classmethod - def diff_units(cls, currency): - return Quantitative.units(currency) + @property + def diff_units(self): + return self.units async def value(self): """ diff --git a/src/sakia/core/money/relative.py b/src/sakia/core/money/relative.py index 29b7d3f0d001d87a8d75b1341df748b0adff35d7..a757b762a1166bd1081c8773e6bd7d2dfecc1285 100644 --- a/src/sakia/core/money/relative.py +++ b/src/sakia/core/money/relative.py @@ -1,28 +1,26 @@ from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale -import asyncio +from .base_referential import BaseReferential -class Relative: +class Relative(BaseReferential): _NAME_STR_ = QT_TRANSLATE_NOOP('Relative', 'UD') _REF_STR_ = QT_TRANSLATE_NOOP('Relative', "{0} {1}UD {2}") _UNITS_STR_ = QT_TRANSLATE_NOOP('Relative', "UD {0}") - def __init__(self, amount, community, app): - self.amount = amount - self.community = community - self.app = app + def __init__(self, amount, community, app, block_number=None): + super().__init__(amount, community, app, block_number) @classmethod def translated_name(cls): return QCoreApplication.translate('Relative', Relative._NAME_STR_) - @classmethod - def units(self, currency): - return QCoreApplication.translate("Relative", Relative._UNITS_STR_).format(currency) + @property + def units(self): + return QCoreApplication.translate("Relative", Relative._UNITS_STR_).format(self.community.short_currency) - @classmethod - def diff_units(self, currency): - return self.units(currency) + @property + def diff_units(self): + return self.units async def value(self): """ @@ -42,7 +40,7 @@ class Relative: @staticmethod def to_si(value, digits): - prefixes = ['', 'd', 'c', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'] + prefixes = ['', 'm', 'µ', 'n', 'p', 'f', 'a', 'z', 'y'] if value < 0: value = -value multiplier = -1 @@ -53,10 +51,7 @@ class Relative: prefix = "" while int(scientific_value) == 0 and scientific_value > 0.0: - if prefix_index > 3: - scientific_value *= 1000 - else: - scientific_value *= 10 + scientific_value *= 1000 prefix_index += 1 if prefix_index < len(prefixes): diff --git a/src/sakia/core/money/relative_to_past.py b/src/sakia/core/money/relative_to_past.py new file mode 100644 index 0000000000000000000000000000000000000000..8fdae53c34b54ec1aa3b136ac2219936b945494c --- /dev/null +++ b/src/sakia/core/money/relative_to_past.py @@ -0,0 +1,91 @@ +from PyQt5.QtCore import QObject, QCoreApplication, QT_TRANSLATE_NOOP, QLocale, QDateTime +from .base_referential import BaseReferential +from . import Relative + + +class RelativeToPast(BaseReferential): + _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', 'Past UD') + _REF_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', "{0} {1}UD({2}) {3}") + _UNITS_STR_ = QT_TRANSLATE_NOOP('RelativeToPast', "UD({0}) {1}") + + def __init__(self, amount, community, app, block_number=None): + super().__init__(amount, community, app, block_number) + + @classmethod + def translated_name(cls): + return QCoreApplication.translate('RelativeToPast', RelativeToPast._NAME_STR_) + + @property + def units(self): + return QCoreApplication.translate("RelativeToPast", RelativeToPast._UNITS_STR_).format('t', + self.community.short_currency) + + @property + def diff_units(self): + return self.units + + async def value(self): + """ + Return relative to past value of amount + :return: float + """ + dividend = await self.community.dividend() + if dividend > 0: + return self.amount / float(dividend) + else: + return self.amount + + async def differential(self): + """ + Return relative to past differential value of amount + :return: float + """ + dividend = await self.community.dividend(self._block_number) + if dividend > 0: + return self.amount / float(dividend) + else: + return self.amount + + async def localized(self, units=False, international_system=False): + value = await self.value() + block = await self.community.get_block() + prefix = "" + if international_system: + localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma']) + else: + localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) + + if units or international_system: + return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_) \ + .format(localized_value, + prefix, + QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block['medianTime']).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ), + self.community.short_currency if units else "") + else: + return localized_value + + async def diff_localized(self, units=False, international_system=False): + value = await self.differential() + block = await self.community.get_block(self._block_number) + prefix = "" + if international_system and value != 0: + localized_value, prefix = Relative.to_si(value, self.app.preferences['digits_after_comma']) + else: + localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) + + if units or international_system: + return QCoreApplication.translate("RelativeToPast", RelativeToPast._REF_STR_)\ + .format(localized_value, + prefix, + QLocale.toString( + QLocale(), + QDateTime.fromTime_t(block['medianTime']).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ), + self.community.short_currency if units else "") + else: + return localized_value diff --git a/src/sakia/core/money/relative_zerosum.py b/src/sakia/core/money/relative_zerosum.py index 5a6b823985ec04ade40327397fffe1337c2df790..797f7cb4d80fa78622c2b76b9a909b8702267b79 100644 --- a/src/sakia/core/money/relative_zerosum.py +++ b/src/sakia/core/money/relative_zerosum.py @@ -1,29 +1,27 @@ from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP, QLocale from .relative import Relative -import asyncio +from .base_referential import BaseReferential -class RelativeZSum: +class RelativeZSum(BaseReferential): _NAME_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', 'Relat Z-sum') - _REF_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "{0} R0 {1}") + _REF_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "{0} {1}R0 {2}") _UNITS_STR_ = QT_TRANSLATE_NOOP('RelativeZSum', "R0 {0}") - def __init__(self, amount, community, app): - self.amount = amount - self.community = community - self.app = app + def __init__(self, amount, community, app, block_number=None): + super().__init__(amount, community, app, block_number) @classmethod def translated_name(cls): return QCoreApplication.translate('RelativeZSum', RelativeZSum._NAME_STR_) - @classmethod - def units(cls, currency): - return QCoreApplication.translate("RelativeZSum", RelativeZSum._UNITS_STR_).format(currency) + @property + def units(self): + return QCoreApplication.translate("RelativeZSum", RelativeZSum._UNITS_STR_).format(self.community.short_currency) - @classmethod - def diff_units(cls, currency): - return Relative.units(currency) + @property + def diff_units(self): + return self.units async def value(self): """ @@ -41,7 +39,7 @@ class RelativeZSum: :return: float """ ud_block = await self.community.get_ud_block() - ud_block_minus_1 = await self.community.get_ud_block(1) + ud_block_minus_1 = await self.community.get_ud_block(x=1) if ud_block_minus_1 and ud_block['membersCount'] > 0: median = ud_block_minus_1['monetaryMass'] / ud_block['membersCount'] relative_value = self.amount / float(ud_block['dividend']) @@ -63,9 +61,10 @@ class RelativeZSum: else: localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) - if units: + if units or international_system: return QCoreApplication.translate("RelativeZSum", RelativeZSum._REF_STR_)\ .format(localized_value, + prefix, self.community.short_currency if units else "") else: return localized_value @@ -79,8 +78,8 @@ class RelativeZSum: else: localized_value = QLocale().toString(float(value), 'f', self.app.preferences['digits_after_comma']) - if units: + if units or international_system: return QCoreApplication.translate("RelativeZSum", RelativeZSum._REF_STR_)\ - .format(localized_value, self.community.short_currency if units else "") + .format(localized_value, prefix, self.community.short_currency if units else "") else: return localized_value diff --git a/src/sakia/core/net/node.py b/src/sakia/core/net/node.py index 3539d85abd3134f0f269b7e095119ec2faa96a31..348aa4063206d704dee483f3ffa2cf5b76d2e044 100644 --- a/src/sakia/core/net/node.py +++ b/src/sakia/core/net/node.py @@ -12,9 +12,11 @@ from ucoinpy.api.bma import ConnectionHandler import asyncio from aiohttp.errors import ClientError, DisconnectedError +from asyncio import TimeoutError import logging import time import jsonschema +import aiohttp from socket import gaierror from PyQt5.QtCore import QObject, pyqtSignal @@ -258,8 +260,6 @@ class Node(QObject): # self.state, new_state)) if self._state != new_state: - if self.pubkey[:5] in ("6YfbK", "J78bP"): - pass self.last_change = time.time() self._state = new_state self.changed.emit() @@ -318,8 +318,8 @@ class Node(QObject): logging.debug("Error in previous block reply : {0}".format(self.pubkey)) logging.debug(str(e)) self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -338,8 +338,8 @@ class Node(QObject): logging.debug("Error in block reply : {0}".format(self.pubkey)) logging.debug(str(e)) self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -371,8 +371,8 @@ class Node(QObject): logging.debug("Error in peering reply : {0}".format(str(e))) self.state = Node.OFFLINE self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -398,8 +398,8 @@ class Node(QObject): logging.debug("Error in summary : {0}".format(e)) self.state = Node.OFFLINE self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -433,8 +433,8 @@ class Node(QObject): logging.debug("error in uid reply : {0}".format(self.pubkey)) self.state = Node.OFFLINE self.identity_changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -469,8 +469,8 @@ class Node(QObject): leaf=leaf_hash)) self.state = Node.OFFLINE self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) @@ -481,8 +481,8 @@ class Node(QObject): logging.debug("Error in peers reply") self.state = Node.OFFLINE self.changed.emit() - except (ClientError, gaierror, asyncio.TimeoutError, DisconnectedError) as e: - logging.debug("{0} : {1}".format(str(e), self.pubkey)) + except (ClientError, gaierror, TimeoutError, DisconnectedError) as e: + logging.debug("{0} : {1}".format(type(e).__name__, self.pubkey)) self.state = Node.OFFLINE except jsonschema.ValidationError: logging.debug("Validation error : {0}".format(self.pubkey)) diff --git a/src/sakia/gui/certification.py b/src/sakia/gui/certification.py index da2bbfba295e91475f53d1a45dcc6270f6b5abe8..9f5ad92ea3da52c4f0c6d10088b9714d518403ea 100644 --- a/src/sakia/gui/certification.py +++ b/src/sakia/gui/certification.py @@ -52,6 +52,7 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): @asyncify async def accept(self): + self.button_box.setEnabled(False) if self.radio_contact.isChecked(): for contact in self.account.contacts: if contact['name'] == self.combo_contact.currentText(): @@ -62,6 +63,7 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): password = await self.password_asker.async_exec() if password == "": + self.button_box.setEnabled(True) return QApplication.setOverrideCursor(Qt.WaitCursor) result = await self.account.certify(password, self.community, pubkey) @@ -83,6 +85,7 @@ class CertificationDialog(QDialog, Ui_CertificationDialog): self.tr("Could not broadcast certification : {0}" .format(result[1]))) QApplication.restoreOverrideCursor() + self.button_box.setEnabled(True) def change_current_community(self, index): self.community = self.account.communities[index] diff --git a/src/sakia/gui/informations_tab.py b/src/sakia/gui/informations_tab.py index bfad9b2f535dcc205a324538fe00a965aac780fd..790556d52ccf8e4de8b76b6354fa73bc49796139 100644 --- a/src/sakia/gui/informations_tab.py +++ b/src/sakia/gui/informations_tab.py @@ -70,7 +70,7 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): logging.debug('community get_ud_block error : ' + str(e)) return False try: - block_ud_minus_1 = await self.community.get_ud_block(1) + block_ud_minus_1 = await self.community.get_ud_block(x=1) except NoPeerAvailable as e: logging.debug('community get_ud_block error : ' + str(e)) return False @@ -125,15 +125,15 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): """).format( localized_ud, self.tr('Universal Dividend UD(t) in'), - self.account.current_ref.diff_units(self.community.currency), + self.account.current_ref(0, self.community, self.app, None).diff_units, localized_mass_minus_1, self.tr('Monetary Mass M(t-1) in'), - self.account.current_ref.diff_units(self.community.currency), + self.account.current_ref(0, self.community, self.app, None).units, block_ud['membersCount'], self.tr('Members N(t)'), localized_mass_minus_1_per_member, self.tr('Monetary Mass per member M(t-1)/N(t) in'), - self.account.current_ref.diff_units(self.community.currency), + self.account.current_ref(0, self.community, self.app, None).diff_units, float(0) if block_ud['membersCount'] == 0 or block_ud_minus_1['monetaryMass'] == 0 else block_ud['dividend'] / (block_ud_minus_1['monetaryMass'] / block_ud['membersCount']), @@ -179,10 +179,10 @@ class InformationsTabWidget(QWidget, Ui_InformationsTabWidget): self.tr('{:} = MAX {{ {:} {:} ; {:2.0%} × {:} {:} / {:} }}').format( localized_ud_plus_1, localized_ud, - self.account.current_ref.diff_units(self.community.currency), + self.account.current_ref(0, self.community, self.app, None).diff_units, params['c'], localized_mass, - self.account.current_ref.diff_units(self.community.currency), + self.account.current_ref(0, self.community, self.app, None).diff_units, block_ud['membersCount'] ), self.tr('Universal Dividend (computed)') diff --git a/src/sakia/gui/transfer.py b/src/sakia/gui/transfer.py index e97939ee51759746d6628e34d4fc24195c274b2f..e0dae0faab07a4df7efeb45827bc59c7ad39f6f1 100644 --- a/src/sakia/gui/transfer.py +++ b/src/sakia/gui/transfer.py @@ -90,6 +90,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): @asyncify async def accept(self): + self.button_box.setEnabled(False) comment = self.edit_message.text() if self.radio_contact.isChecked(): @@ -105,6 +106,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): await QAsyncMessageBox.critical(self, self.tr("Money transfer"), self.tr("No amount. Please give the transfert amount"), QMessageBox.Ok) + self.button_box.setEnabled(True) return password = await self.password_asker.async_exec() @@ -136,6 +138,7 @@ class TransferMoneyDialog(QDialog, Ui_TransferMoneyDialog): await QAsyncMessageBox.critical(self, self.tr("Transfer"), result[1]) QApplication.restoreOverrideCursor() + self.button_box.setEnabled(True) @asyncify async def amount_changed(self, value): diff --git a/src/sakia/main.py b/src/sakia/main.py index 07e123a3564df1677321b198a4197f1bd80d12b0..8058c3324f3d79366edcf76c175031a18bd8ba19 100755 --- a/src/sakia/main.py +++ b/src/sakia/main.py @@ -16,7 +16,7 @@ import jsonschema # To force cx_freeze import import PyQt5.QtSvg -from quamash import QEventLoopSelector +from quamash import QSelectorEventLoop from PyQt5.QtWidgets import QApplication from sakia.gui.mainwindow import MainWindow from sakia.core.app import Application @@ -61,7 +61,7 @@ if __name__ == '__main__': # activate ctrl-c interrupt signal.signal(signal.SIGINT, signal.SIG_DFL) sakia = QApplication(sys.argv) - loop = QEventLoopSelector(sakia) + loop = QSelectorEventLoop(sakia) loop.set_exception_handler(async_exception_handler) asyncio.set_event_loop(loop) diff --git a/src/sakia/models/txhistory.py b/src/sakia/models/txhistory.py index d138dada1f9d006d46f344bdc1ef6c6672f70a5e..8bbc8a66af86acce4fb34fb6dd45e6fd4e14075c 100644 --- a/src/sakia/models/txhistory.py +++ b/src/sakia/models/txhistory.py @@ -231,7 +231,8 @@ class HistoryTableModel(QAbstractTableModel): async def data_received(self, transfer): amount = transfer.metadata['amount'] - deposit = await self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\ + deposit = await self.account.current_ref(transfer.metadata['amount'], self.community, + self.app, transfer.blockid.number)\ .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" if transfer.metadata['comment'] != "": @@ -254,7 +255,8 @@ class HistoryTableModel(QAbstractTableModel): async def data_sent(self, transfer): amount = transfer.metadata['amount'] - paiment = await self.account.current_ref(transfer.metadata['amount'], self.community, self.app)\ + paiment = await self.account.current_ref(transfer.metadata['amount'], self.community, + self.app, transfer.blockid.number)\ .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" if transfer.metadata['comment'] != "": @@ -277,7 +279,7 @@ class HistoryTableModel(QAbstractTableModel): async def data_dividend(self, dividend): amount = dividend['amount'] - deposit = await self.account.current_ref(dividend['amount'], self.community, self.app)\ + deposit = await self.account.current_ref(dividend['amount'], self.community, self.app, dividend['block_number'])\ .diff_localized(international_system=self.app.preferences['international_system_of_units']) comment = "" receiver = self.account.name @@ -334,7 +336,7 @@ class HistoryTableModel(QAbstractTableModel): if self.columns_types[section] == 'payment' or self.columns_types[section] == 'deposit': return '{:}\n({:})'.format( self.column_headers[section](), - self.account.current_ref.diff_units(self.community.short_currency) + self.account.current_ref(0, self.community, self.app, None).diff_units ) return self.column_headers[section]() diff --git a/src/sakia/models/wallets.py b/src/sakia/models/wallets.py index a656f182d05107b72ba6dc777cbf32967a83c61d..4428dcbb9cc070488c58c4ac009857f0ff74541b 100644 --- a/src/sakia/models/wallets.py +++ b/src/sakia/models/wallets.py @@ -112,7 +112,7 @@ class WalletsTableModel(QAbstractTableModel): if self.columns_types[section] == 'amount': return '{:}\n({:})'.format( self.columns_headers[section], - self.account.current_ref.units(self.community.short_currency) + self.account.current_ref(0, self.community, self.app, None).units ) return self.columns_headers[section] diff --git a/src/sakia/tests/quamash_utils.py b/src/sakia/tests/quamash_utils.py index a359319d252f0b79c8d054cf6090e3a87195ddbe..7c11293ca4cbacbda7815318d3923c4b91eca84f 100644 --- a/src/sakia/tests/quamash_utils.py +++ b/src/sakia/tests/quamash_utils.py @@ -9,7 +9,7 @@ _application_ = [] class QuamashTest: def setUpQuamash(self): self.qapplication = get_application() - self.lp = quamash.QEventLoopSelector(self.qapplication) + self.lp = quamash.QSelectorEventLoop(self.qapplication) asyncio.set_event_loop(self.lp) self.lp.set_exception_handler(lambda l, c: unitttest_exception_handler(self, l, c)) self.exceptions = [] diff --git a/src/sakia/tests/unit/core/money/__init__.py b/src/sakia/tests/unit/core/money/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/src/sakia/tests/unit/core/money/test_quantitative.py b/src/sakia/tests/unit/core/money/test_quantitative.py new file mode 100644 index 0000000000000000000000000000000000000000..dd32a301ff91a7280f982bb66e68ade163d32be4 --- /dev/null +++ b/src/sakia/tests/unit/core/money/test_quantitative.py @@ -0,0 +1,144 @@ +import unittest +from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock +from PyQt5.QtCore import QLocale +from sakia.tests import QuamashTest +from sakia.core.money import Quantitative + + +class TestQuantitative(unittest.TestCase, QuamashTest): + def setUp(self): + self.setUpQuamash() + QLocale.setDefault(QLocale("en_GB")) + + def tearDown(self): + self.tearDownQuamash() + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Quantitative(0, community, app, None) + self.assertEqual(referential.units, "TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Quantitative(0, community, app, None) + self.assertEqual(referential.units, "TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_value(self, app, community): + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertEqual(value, 101010110) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_differential(self, app, community): + referential = Quantitative(110, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertEqual(value, 110) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.localized(units=True) + self.assertEqual(value, "101,010,110 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.localized(units=True, international_system=True) + self.assertEqual(value, "101.010110 MTC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=False) + self.assertEqual(value, "101,010,110") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=True) + self.assertEqual(value, "101.010110 M") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True) + self.assertEqual(value, "101,010,110 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True, international_system=True) + self.assertEqual(value, "101.010110 MTC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=False) + self.assertEqual(value, "101,010,110") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Quantitative(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=True) + self.assertEqual(value, "101.010110 M") + self.lp.run_until_complete(exec_test()) diff --git a/src/sakia/tests/unit/core/money/test_quantitative_zsum.py b/src/sakia/tests/unit/core/money/test_quantitative_zsum.py new file mode 100644 index 0000000000000000000000000000000000000000..68ecaad7c751ba4b8f6fa014c93875e0bc85ebe7 --- /dev/null +++ b/src/sakia/tests/unit/core/money/test_quantitative_zsum.py @@ -0,0 +1,164 @@ +import unittest +from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock +from PyQt5.QtCore import QLocale +from sakia.tests import QuamashTest +from sakia.core.money import QuantitativeZSum + + +class TestQuantitativeZSum(unittest.TestCase, QuamashTest): + def setUp(self): + self.setUpQuamash() + QLocale.setDefault(QLocale("en_GB")) + + def tearDown(self): + self.tearDownQuamash() + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = QuantitativeZSum(0, community, app, None) + self.assertEqual(referential.units, "Q0 TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = QuantitativeZSum(0, community, app, None) + self.assertEqual(referential.units, "Q0 TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_value(self, app, community): + referential = QuantitativeZSum(110, community, app, None) + community.get_ud_block = CoroutineMock(return_value={'membersCount': 5}) + community.monetary_mass = CoroutineMock(return_value=500) + async def exec_test(): + value = await referential.value() + self.assertEqual(value, 10) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_differential(self, app, community): + community.get_ud_block = CoroutineMock(return_value={'membersCount': 5}) + community.monetary_mass = CoroutineMock(return_value=500) + referential = QuantitativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertEqual(value, 10) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 5}) + community.monetary_mass = CoroutineMock(return_value=500) + referential = QuantitativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=True) + self.assertEqual(value, "10 Q0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(110 * 1000, community, app, None) + async def exec_test(): + value = await referential.localized(units=True, international_system=True) + self.assertEqual(value, "109.500000 kQ0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 5}) + community.monetary_mass = CoroutineMock(return_value=500) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=False) + self.assertEqual(value, "10") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(110 * 1000, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=True) + self.assertEqual(value, "109.500000 kQ0 ") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 1000}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000) + referential = QuantitativeZSum(110 * 1000, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True) + self.assertEqual(value, "110,000 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 10}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True, international_system=True) + self.assertEqual(value, "101.010110 MTC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 10}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=False) + self.assertEqual(value, "101,010,110") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.get_ud_block = CoroutineMock(return_value={'membersCount': 10}) + community.monetary_mass = CoroutineMock(return_value=500 * 1000 * 1000) + app.preferences = { + 'digits_after_comma': 6 + } + referential = QuantitativeZSum(101010110, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=True) + self.assertEqual(value, "101.010110 M") + self.lp.run_until_complete(exec_test()) diff --git a/src/sakia/tests/unit/core/money/test_relative.py b/src/sakia/tests/unit/core/money/test_relative.py new file mode 100644 index 0000000000000000000000000000000000000000..ae542b05ae8f5f4110dfebd8370ed67297342b46 --- /dev/null +++ b/src/sakia/tests/unit/core/money/test_relative.py @@ -0,0 +1,160 @@ +import unittest +from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock +from PyQt5.QtCore import QLocale +from sakia.tests import QuamashTest +from sakia.core.money import Relative + + +class TestRelative(unittest.TestCase, QuamashTest): + def setUp(self): + self.setUpQuamash() + QLocale.setDefault(QLocale("en_GB")) + + def tearDown(self): + self.tearDownQuamash() + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Relative(0, community, app, None) + self.assertEqual(referential.units, "UD TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = Relative(0, community, app, None) + self.assertEqual(referential.units, "UD TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_value(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + referential = Relative(10101011, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 1010.10110) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_differential(self, app, community): + community.dividend = CoroutineMock(return_value=1000) + referential = Relative(110, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 0.11) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(101, community, app, None) + async def exec_test(): + value = await referential.localized(units=True) + self.assertEqual(value, "0.101000 UD TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.localized(units=True, international_system=True) + self.assertEqual(value, "1.011000 mUD TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=False) + self.assertEqual(value, "0.101100") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=True) + self.assertEqual(value, "1.011000 mUD ") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True) + self.assertEqual(value, "0.101100 UD TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True, international_system=True) + self.assertEqual(value, "1.011000 mUD TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=False) + self.assertEqual(value, "0.001011") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = Relative(1011, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=True) + self.assertEqual(value, "1.011000 mUD ") + self.lp.run_until_complete(exec_test()) \ No newline at end of file diff --git a/src/sakia/tests/unit/core/money/test_relative_to_past.py b/src/sakia/tests/unit/core/money/test_relative_to_past.py new file mode 100644 index 0000000000000000000000000000000000000000..0a0f5e2d83b6512d01d745b1e66bdfb66d9342f5 --- /dev/null +++ b/src/sakia/tests/unit/core/money/test_relative_to_past.py @@ -0,0 +1,192 @@ +import unittest +from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock +from PyQt5.QtCore import QLocale, QDateTime +from sakia.tests import QuamashTest +from sakia.core.money import RelativeToPast + + +class TestRelativeToPast(unittest.TestCase, QuamashTest): + def setUp(self): + self.setUpQuamash() + QLocale.setDefault(QLocale("en_GB")) + + def tearDown(self): + self.tearDownQuamash() + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = RelativeToPast(0, community, app, 100) + self.assertEqual(referential.units, "UD(t) TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = RelativeToPast(0, community, app, 100) + self.assertEqual(referential.units, "UD(t) TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_value(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + referential = RelativeToPast(10101011, community, app, 100) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 1010.10110) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_differential(self, app, community): + community.dividend = CoroutineMock(return_value=1000) + referential = RelativeToPast(110, community, app, 100) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 0.11) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(101, community, app, 100) + async def exec_test(): + value = await referential.localized(units=True) + self.assertEqual(value, "0.101000 UD({0}) TC".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.localized(units=True, international_system=True) + self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.localized(units=False, international_system=False) + self.assertEqual(value, "0.101100") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.localized(units=False, international_system=True) + self.assertEqual(value, "1.011000 mUD({0}) ".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.diff_localized(units=True) + self.assertEqual(value, "0.101100 UD({0}) TC".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.diff_localized(units=True, international_system=True) + self.assertEqual(value, "1.011000 mUD({0}) TC".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_no_si(self, app, community): + community.dividend = CoroutineMock(return_value=10000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=False) + self.assertEqual(value, "0.101100") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_with_si(self, app, community): + community.dividend = CoroutineMock(return_value=1000000) + community.get_block = CoroutineMock(return_value={'medianTime': 1452663088792}) + type(community).short_currency = PropertyMock(return_value="TC") + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeToPast(1011, community, app, 100) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=True) + self.assertEqual(value, "1.011000 mUD({0}) ".format(QLocale.toString( + QLocale(), + QDateTime.fromTime_t(1452663088792).date(), + QLocale.dateFormat(QLocale(), QLocale.ShortFormat) + ))) + self.lp.run_until_complete(exec_test()) diff --git a/src/sakia/tests/unit/core/money/test_relative_zsum.py b/src/sakia/tests/unit/core/money/test_relative_zsum.py new file mode 100644 index 0000000000000000000000000000000000000000..2a8208997fc6f2a7a34c7fece2fdd5cfe46f0eda --- /dev/null +++ b/src/sakia/tests/unit/core/money/test_relative_zsum.py @@ -0,0 +1,184 @@ +import unittest +from asynctest.mock import Mock, CoroutineMock, patch, PropertyMock +from PyQt5.QtCore import QLocale +from sakia.tests import QuamashTest +from sakia.core.money import RelativeZSum + + +class TestRelativeZSum(unittest.TestCase, QuamashTest): + def setUp(self): + self.setUpQuamash() + QLocale.setDefault(QLocale("en_GB")) + + def tearDown(self): + self.tearDownQuamash() + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = RelativeZSum(0, community, app, None) + self.assertEqual(referential.units, "R0 TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_units(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + referential = RelativeZSum(0, community, app, None) + self.assertEqual(referential.units, "R0 TC") + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_value(self, app, community): + referential = RelativeZSum(110, community, app, None) + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 0.10) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_differential(self, app, community): + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + referential = RelativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.value() + self.assertAlmostEqual(value, 0.10) + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + referential = RelativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=True) + self.assertEqual(value, "0.1 R0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=True, international_system=True) + self.assertEqual(value, "100.000000 mR0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=False) + self.assertEqual(value, "0.100000") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(110, community, app, None) + async def exec_test(): + value = await referential.localized(units=False, international_system=True) + self.assertEqual(value, "100.000000 mR0 ") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + referential = RelativeZSum(90, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True) + self.assertEqual(value, "0.9 R0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(90, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=True, international_system=True) + self.assertEqual(value, "900.000000 mR0 TC") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_no_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(90, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=False) + self.assertEqual(value, "0.900000") + self.lp.run_until_complete(exec_test()) + + @patch('sakia.core.Community') + @patch('sakia.core.Application') + def test_diff_localized_no_units_with_si(self, app, community): + type(community).short_currency = PropertyMock(return_value="TC") + community.dividend = CoroutineMock(return_value=100) + community.get_ud_block = CoroutineMock(side_effect=lambda *args, **kwargs: \ + {'membersCount': 5, "monetaryMass": 500, "dividend": 100} if 'x' in kwargs \ + else {'membersCount': 5, "monetaryMass": 1050, "dividend": 100} ) + app.preferences = { + 'digits_after_comma': 6 + } + referential = RelativeZSum(90, community, app, None) + async def exec_test(): + value = await referential.diff_localized(units=False, international_system=True) + self.assertEqual(value, "900.000000 mR0 ") + self.lp.run_until_complete(exec_test())