diff --git a/neo/Prompt/CommandBase.py b/neo/Prompt/CommandBase.py index 482885e6d..37de127f3 100644 --- a/neo/Prompt/CommandBase.py +++ b/neo/Prompt/CommandBase.py @@ -1,6 +1,7 @@ from abc import ABC, abstractmethod from neo.Prompt.Utils import get_arg from typing import List +from neo.Prompt.PromptPrinter import prompt_print as print class ParameterDesc(): diff --git a/neo/Prompt/Commands/BuildNRun.py b/neo/Prompt/Commands/BuildNRun.py index 996e6c961..cda740acb 100644 --- a/neo/Prompt/Commands/BuildNRun.py +++ b/neo/Prompt/Commands/BuildNRun.py @@ -13,6 +13,7 @@ from neocore.BigInteger import BigInteger from neo.Settings import settings from neo.logging import log_manager +from neo.Prompt.PromptPrinter import prompt_print as print logger = log_manager.getLogger() @@ -77,7 +78,6 @@ def BuildAndRun(arguments, wallet, verbose=True, min_fee=DEFAULT_MIN_FEE, invoca def DoRun(contract_script, arguments, wallet, path, verbose=True, from_addr=None, min_fee=DEFAULT_MIN_FEE, invocation_test_mode=True, debug_map=None, invoke_attrs=None, owners=None): - if not wallet: print("Please open a wallet to test build contract") return None, None, None, None diff --git a/neo/Prompt/Commands/Config.py b/neo/Prompt/Commands/Config.py index 16ba42c19..9b491e7ba 100644 --- a/neo/Prompt/Commands/Config.py +++ b/neo/Prompt/Commands/Config.py @@ -4,6 +4,7 @@ from neo.Prompt.Utils import get_arg from neo.Settings import settings from neo.Network.NodeLeader import NodeLeader +from neo.Prompt.PromptPrinter import prompt_print as print from distutils import util import logging diff --git a/neo/Prompt/Commands/Invoke.py b/neo/Prompt/Commands/Invoke.py index 9cc86bd9b..2ddc93246 100644 --- a/neo/Prompt/Commands/Invoke.py +++ b/neo/Prompt/Commands/Invoke.py @@ -34,6 +34,7 @@ from prompt_toolkit import prompt from copy import deepcopy from neo.logging import log_manager +from neo.Prompt.PromptPrinter import prompt_print as print logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/LoadSmartContract.py b/neo/Prompt/Commands/LoadSmartContract.py index 6886c220e..e94d3f943 100644 --- a/neo/Prompt/Commands/LoadSmartContract.py +++ b/neo/Prompt/Commands/LoadSmartContract.py @@ -9,6 +9,7 @@ from neo.Core.Blockchain import Blockchain from neo.SmartContract.Contract import Contract from neocore.BigInteger import BigInteger +from neo.Prompt.PromptPrinter import prompt_print as print def ImportContractAddr(wallet, contract_hash, pubkey_script_hash): diff --git a/neo/Prompt/Commands/SC.py b/neo/Prompt/Commands/SC.py index 36947b182..ba2e9a3e3 100644 --- a/neo/Prompt/Commands/SC.py +++ b/neo/Prompt/Commands/SC.py @@ -12,7 +12,7 @@ from neo.Implementations.Blockchains.LevelDB.DebugStorage import DebugStorage from distutils import util from neo.Settings import settings - +from neo.Prompt.PromptPrinter import prompt_print as print from neo.logging import log_manager logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/Search.py b/neo/Prompt/Commands/Search.py index 8f6fb71d6..6953f085a 100644 --- a/neo/Prompt/Commands/Search.py +++ b/neo/Prompt/Commands/Search.py @@ -3,6 +3,7 @@ from neo.Prompt.Utils import get_arg from neo.Core.Blockchain import Blockchain from neo.logging import log_manager +from neo.Prompt.PromptPrinter import prompt_print as print import json logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/Send.py b/neo/Prompt/Commands/Send.py index fe69e942a..4af3cf68f 100755 --- a/neo/Prompt/Commands/Send.py +++ b/neo/Prompt/Commands/Send.py @@ -14,6 +14,7 @@ from neo.Prompt.PromptData import PromptData from neo.Prompt.CommandBase import CommandBase, CommandDesc, ParameterDesc from logzero import logger +from neo.Prompt.PromptPrinter import prompt_print as print class CommandWalletSend(CommandBase): diff --git a/neo/Prompt/Commands/Show.py b/neo/Prompt/Commands/Show.py index 36c72f68f..0d3766e8b 100644 --- a/neo/Prompt/Commands/Show.py +++ b/neo/Prompt/Commands/Show.py @@ -11,6 +11,7 @@ from neo.Network.NodeLeader import NodeLeader from neo.Implementations.Notifications.LevelDB.NotificationDB import NotificationDB from neo.logging import log_manager +from neo.Prompt.PromptPrinter import prompt_print as print import json logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/Tokens.py b/neo/Prompt/Commands/Tokens.py index 1fe56192c..c8df76076 100644 --- a/neo/Prompt/Commands/Tokens.py +++ b/neo/Prompt/Commands/Tokens.py @@ -15,7 +15,7 @@ from neocore.Utils import isValidPublicAddress import peewee import traceback - +from neo.Prompt.PromptPrinter import prompt_print as print from neo.logging import log_manager logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/Wallet.py b/neo/Prompt/Commands/Wallet.py index ac0f4597e..aade4a306 100644 --- a/neo/Prompt/Commands/Wallet.py +++ b/neo/Prompt/Commands/Wallet.py @@ -21,6 +21,7 @@ from neo.Prompt.Commands.WalletExport import CommandWalletExport from neo.logging import log_manager from neocore.Utils import isValidPublicAddress +from neo.Prompt.PromptPrinter import prompt_print as print logger = log_manager.getLogger() diff --git a/neo/Prompt/Commands/WalletAddress.py b/neo/Prompt/Commands/WalletAddress.py index bafb537b1..f1a192e1d 100644 --- a/neo/Prompt/Commands/WalletAddress.py +++ b/neo/Prompt/Commands/WalletAddress.py @@ -11,6 +11,7 @@ from neo.Core.Blockchain import Blockchain from neo.Core.TX.Transaction import ContractTransaction from neo.Core.TX.Transaction import TransactionOutput +from neo.Prompt.PromptPrinter import prompt_print as print class CommandWalletAddress(CommandBase): diff --git a/neo/Prompt/Commands/WalletExport.py b/neo/Prompt/Commands/WalletExport.py index b394f7d75..7cc49c680 100644 --- a/neo/Prompt/Commands/WalletExport.py +++ b/neo/Prompt/Commands/WalletExport.py @@ -2,6 +2,7 @@ from neo.Prompt import Utils as PromptUtils from neo.Prompt.PromptData import PromptData from prompt_toolkit import prompt +from neo.Prompt.PromptPrinter import prompt_print as print class CommandWalletExport(CommandBase): diff --git a/neo/Prompt/Commands/WalletImport.py b/neo/Prompt/Commands/WalletImport.py index 4b48c8215..04b0b845d 100644 --- a/neo/Prompt/Commands/WalletImport.py +++ b/neo/Prompt/Commands/WalletImport.py @@ -12,6 +12,7 @@ from neo.SmartContract.Contract import Contract from neo.Core.Blockchain import Blockchain from neo.Wallets import NEP5Token +from neo.Prompt.PromptPrinter import prompt_print as print class CommandWalletImport(CommandBase): diff --git a/neo/Prompt/Commands/tests/test_claim_command.py b/neo/Prompt/Commands/tests/test_claim_command.py index a942b8ac6..dbbc0caf5 100644 --- a/neo/Prompt/Commands/tests/test_claim_command.py +++ b/neo/Prompt/Commands/tests/test_claim_command.py @@ -6,6 +6,7 @@ from neo.Prompt.Commands.Wallet import ClaimGas from neocore.Fixed8 import Fixed8 from neo.Core.TX.ClaimTransaction import ClaimTransaction +from neo.Prompt.PromptPrinter import pp import shutil @@ -28,6 +29,17 @@ class UserWalletTestCase(WalletFixtureTestCase): _wallet3 = None + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + @property def GAS(self): return Blockchain.Default().SystemCoin().Hash diff --git a/neo/Prompt/Commands/tests/test_config_commands.py b/neo/Prompt/Commands/tests/test_config_commands.py index fac51a2fb..2ee6eab6e 100644 --- a/neo/Prompt/Commands/tests/test_config_commands.py +++ b/neo/Prompt/Commands/tests/test_config_commands.py @@ -6,9 +6,20 @@ from neo.Network.NodeLeader import NodeLeader from mock import patch from io import StringIO +from neo.Prompt.PromptPrinter import pp class CommandConfigTestCase(BlockchainFixtureTestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() @classmethod def leveldb_testpath(self): @@ -25,6 +36,9 @@ def test_config(self): self.assertFalse(res) def test_config_output(self): + # importing because it sets up `peewee` logging, which is checked at the test below + from neo.Implementations.Wallets.peewee.UserWallet import UserWallet + args = ['output'] with patch('neo.Prompt.Commands.Config.prompt', side_effect=[1, 1, 1, "\n", "\n"]): # tests changing the level and keeping the current level res = CommandConfig().execute(args) diff --git a/neo/Prompt/Commands/tests/test_output_config.py b/neo/Prompt/Commands/tests/test_output_config.py index 200a961f2..885f2e93e 100644 --- a/neo/Prompt/Commands/tests/test_output_config.py +++ b/neo/Prompt/Commands/tests/test_output_config.py @@ -2,11 +2,22 @@ from neo.Prompt.Commands.Config import start_output_config from mock import patch from neo.Utils.NeoTestCase import NeoTestCase +from neo.Prompt.PromptPrinter import pp import logging import io class TestOutputConfig(NeoTestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily by patching sys.stdout + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() @patch('sys.stdout', new_callable=io.StringIO) @patch('neo.Prompt.Commands.Config.log_manager.config_stdio') diff --git a/neo/Prompt/Commands/tests/test_sc_commands.py b/neo/Prompt/Commands/tests/test_sc_commands.py index dbde28a16..ad3d77594 100644 --- a/neo/Prompt/Commands/tests/test_sc_commands.py +++ b/neo/Prompt/Commands/tests/test_sc_commands.py @@ -11,6 +11,7 @@ from io import StringIO from boa.compiler import Compiler from neo.Settings import settings +from neo.Prompt.PromptPrinter import pp class CommandSCTestCase(WalletFixtureTestCase): @@ -23,6 +24,17 @@ class CommandSCTestCase(WalletFixtureTestCase): _wallet1 = None _wallet3 = None + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + @classmethod def GetWallet1(cls, recreate=False): if cls._wallet1 is None or recreate: diff --git a/neo/Prompt/Commands/tests/test_search_commands.py b/neo/Prompt/Commands/tests/test_search_commands.py index 6ed1b76c9..35dc2c84a 100644 --- a/neo/Prompt/Commands/tests/test_search_commands.py +++ b/neo/Prompt/Commands/tests/test_search_commands.py @@ -4,10 +4,22 @@ from neo.Prompt.Commands.Search import CommandSearch from mock import patch from io import StringIO +from neo.Prompt.PromptPrinter import pp class CommandShowTestCase(BlockchainFixtureTestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + @classmethod def leveldb_testpath(self): return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') diff --git a/neo/Prompt/Commands/tests/test_send_command.py b/neo/Prompt/Commands/tests/test_send_command.py index 9754c6062..c1197bbf8 100644 --- a/neo/Prompt/Commands/tests/test_send_command.py +++ b/neo/Prompt/Commands/tests/test_send_command.py @@ -11,6 +11,7 @@ from mock import patch import json from io import StringIO +from neo.Prompt.PromptPrinter import pp class UserWalletTestCase(WalletFixtureTestCase): @@ -42,6 +43,17 @@ def GetWallet1(cls, recreate=False): def tearDown(cls): PromptData.Wallet = None + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + def test_send_neo(self): with patch('neo.Prompt.Commands.Send.prompt', side_effect=[UserWalletTestCase.wallet_1_pass()]): PromptData.Wallet = self.GetWallet1(recreate=True) diff --git a/neo/Prompt/Commands/tests/test_show_commands.py b/neo/Prompt/Commands/tests/test_show_commands.py index 942168bdd..6ebe66bcf 100644 --- a/neo/Prompt/Commands/tests/test_show_commands.py +++ b/neo/Prompt/Commands/tests/test_show_commands.py @@ -4,6 +4,7 @@ from neo.Prompt.Commands.Show import CommandShow from neo.Prompt.Commands.Wallet import CommandWallet from neo.Prompt.PromptData import PromptData +from neo.Prompt.PromptPrinter import pp from neo.bin.prompt import PromptInterface from copy import deepcopy from neo.Network.NodeLeader import NodeLeader, NeoNode @@ -13,6 +14,16 @@ class CommandShowTestCase(BlockchainFixtureTestCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() @classmethod def leveldb_testpath(self): diff --git a/neo/Prompt/Commands/tests/test_token_commands.py b/neo/Prompt/Commands/tests/test_token_commands.py index e27f54504..fb1d59057 100644 --- a/neo/Prompt/Commands/tests/test_token_commands.py +++ b/neo/Prompt/Commands/tests/test_token_commands.py @@ -15,6 +15,7 @@ from contextlib import contextmanager from io import StringIO from neo.VM.InteropService import StackItem +from neo.Prompt.PromptPrinter import pp class UserWalletTestCase(WalletFixtureTestCase): @@ -34,6 +35,17 @@ class UserWalletTestCase(WalletFixtureTestCase): token_hash_str = '31730cc9a1844891a3bafd1aa929a4142860d8d3' + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + @property def GAS(self): return Blockchain.Default().SystemCoin().Hash @@ -780,6 +792,17 @@ class TokenSendFromTestCase(WalletFixtureTestCase): watch_addr_str = 'AGYaEi3W6ndHPUmW7T12FFfsbQ6DWymkEm' wallet_1_addr = 'AJQ6FoaSXDFzA6wLnyZ1nFN7SGSN2oNTc3' + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print + + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + @contextmanager def OpenWallet1(self): PromptData.Wallet = UserWalletTestCase.GetWallet1(recreate=True) diff --git a/neo/Prompt/Commands/tests/test_wallet_commands.py b/neo/Prompt/Commands/tests/test_wallet_commands.py index 72257ef42..c319c6be4 100644 --- a/neo/Prompt/Commands/tests/test_wallet_commands.py +++ b/neo/Prompt/Commands/tests/test_wallet_commands.py @@ -7,6 +7,7 @@ from neo.Prompt.Commands.Wallet import CommandWallet from neo.Prompt.Commands.Wallet import ShowUnspentCoins from neo.Prompt.PromptData import PromptData +from neo.Prompt.PromptPrinter import pp import os import shutil from mock import patch @@ -61,9 +62,19 @@ def OpenWallet2(cls): def tearDown(cls): PromptData.Wallet = None + @classmethod + def setUpClass(cls): + super().setUpClass() + # replace the prompt_toolkit formatted print function with the default such that we can test easily + pp.printer = print -class UserWalletTestCase(UserWalletTestCaseBase): + @classmethod + def tearDownClass(cls): + super().tearDownClass() + pp.reset_printer() + +class UserWalletTestCase(UserWalletTestCaseBase): # Beginning with refactored tests def test_wallet(self): # without wallet opened diff --git a/neo/Prompt/PromptPrinter.py b/neo/Prompt/PromptPrinter.py new file mode 100644 index 000000000..3f013b8d6 --- /dev/null +++ b/neo/Prompt/PromptPrinter.py @@ -0,0 +1,40 @@ +from prompt_toolkit import print_formatted_text +from prompt_toolkit.formatted_text import FormattedText +from prompt_toolkit.styles import Style +from neo.UserPreferences import preferences + +token_style = Style.from_dict({ + "command": preferences.token_style['Command'], + "neo": preferences.token_style['Neo'], + "default": preferences.token_style['Default'], + "number": preferences.token_style['Number'], +}) + + +class PromptPrinter(): + def __init__(self): + self.printer = self._internal_prompt_print + + def reset_printer(self): + self.printer = self._internal_prompt_print + + def _internal_prompt_print(self, *args, **kwargs): + kwargs['style'] = token_style + frags = [] + for a in args: + if isinstance(a, FormattedText): + frags.append(a) + else: + frags.append(FormattedText([("class:command", a)])) + + print_formatted_text(*frags, **kwargs) + + def print(self, *args, **kwargs): + self.printer(*args, **kwargs) + + +pp = PromptPrinter() + + +def prompt_print(*args, **kwargs): + pp.print(*args, **kwargs) diff --git a/neo/Prompt/Utils.py b/neo/Prompt/Utils.py index d62fb29cf..5cd366d25 100644 --- a/neo/Prompt/Utils.py +++ b/neo/Prompt/Utils.py @@ -11,8 +11,8 @@ from prompt_toolkit.shortcuts import PromptSession from neo.logging import log_manager from neo.Wallets import NEP5Token -from typing import TYPE_CHECKING from neocore.Cryptography.Crypto import Crypto +from typing import TYPE_CHECKING if TYPE_CHECKING: from neo.Wallets.Wallet import Wallet diff --git a/neo/bin/prompt.py b/neo/bin/prompt.py index 4ca076493..0ef74af97 100755 --- a/neo/bin/prompt.py +++ b/neo/bin/prompt.py @@ -8,7 +8,6 @@ from prompt_toolkit.history import FileHistory from prompt_toolkit.shortcuts import print_formatted_text, PromptSession from prompt_toolkit.formatted_text import FormattedText -from prompt_toolkit.styles import Style from twisted.internet import reactor, task from neo import __version__ from neo.Core.Blockchain import Blockchain @@ -25,6 +24,7 @@ from neo.Settings import settings, PrivnetConnectionError from neo.UserPreferences import preferences from neo.logging import log_manager +from neo.Prompt.PromptPrinter import prompt_print, token_style logger = log_manager.getLogger() @@ -81,7 +81,6 @@ class PromptInterface: commands = {command.command_desc().command: command for command in _commands} - token_style = None start_height = None start_dt = None @@ -94,13 +93,6 @@ def __init__(self, history_filename=None): self.start_height = Blockchain.Default().Height self.start_dt = datetime.datetime.utcnow() - self.token_style = Style.from_dict({ - "command": preferences.token_style['Command'], - "neo": preferences.token_style['Neo'], - "default": preferences.token_style['Default'], - "number": preferences.token_style['Number'], - }) - def get_bottom_toolbar(self, cli=None): out = [] try: @@ -140,11 +132,11 @@ def quit(self): reactor.stop() def help(self): - print(f"\nCommands:") + prompt_print(f"\nCommands:") for command_group in sorted(self.commands.keys()): command = self.commands[command_group] - print(f" {command_group:<15} - {command.command_desc().short_help}") - print(f"\nRun 'COMMAND help' for more information on a command.") + prompt_print(f" {command_group:<15} - {command.command_desc().short_help}") + prompt_print(f"\nRun 'COMMAND help' for more information on a command.") def start_wallet_loop(self): if self.wallet_loop_deferred: @@ -170,7 +162,7 @@ def run(self): tokens = [("class:neo", 'NEO'), ("class:default", ' cli. Type '), ("class:command", '\'help\' '), ("class:default", 'to get started')] - print_formatted_text(FormattedText(tokens), style=self.token_style) + print_formatted_text(FormattedText(tokens), style=token_style) print('\n') @@ -180,7 +172,7 @@ def run(self): completer=self.get_completer(), history=self.history, bottom_toolbar=self.get_bottom_toolbar, - style=self.token_style, + style=token_style, refresh_interval=3, )