123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- #!/usr/bin/env python3
- import sys,os
- pn = os.path.abspath(os.path.dirname(sys.argv[0]))
- parpar = os.path.dirname(os.path.dirname(pn))
- os.chdir(parpar)
- sys.path[0] = os.curdir
- from mmgen.cfg import Config,gc
- from mmgen.color import yellow,blue,cyan,set_vt100
- from mmgen.util import msg,ymsg,gmsg,fmt,fmt_list,die
- commands = [
- 'start',
- 'get_terminal_size',
- 'color',
- 'license',
- 'line_input',
- 'urand',
- 'txview',
- 'get_char_one',
- 'get_char_one_raw',
- ]
- if sys.platform == 'linux':
- commands.extend([
- 'get_char',
- 'get_char_immed_chars',
- 'get_char_raw',
- ])
- elif sys.platform == 'win32':
- commands.extend([
- 'get_char_one_char_immed_chars',
- ])
- opts_data = {
- 'text': {
- 'desc': 'Interactively test MMGen terminal functionality',
- 'usage': 'command',
- 'options': """
- -h, --help Print this help message
- """,
- 'notes': f"""
- available commands for platform {sys.platform!r}:
- {fmt_list(commands,fmt='col',indent=' ')}
- """
- }
- }
- cfg = Config(opts_data=opts_data)
- from mmgen.term import get_char,get_char_raw,get_terminal_size,get_term
- from mmgen.ui import line_input,keypress_confirm,do_license_msg
- import mmgen.term as term_mod
- def cmsg(m):
- msg('\n'+cyan(m))
- def confirm(m):
- if not keypress_confirm( cfg, m ):
- if keypress_confirm( cfg, 'Are you sure you want to exit test?' ):
- die(1,'Exiting test at user request')
- else:
- msg('Continuing...')
- def tt_start():
- m = fmt("""
- We will now test MMGen Wallet’s terminal capabilities.
- This is a non-automated test and requires user interaction.
- Continue?
- """)
- confirm(m.strip())
- def tt_get_terminal_size():
- cmsg('Testing get_terminal_size():')
- msg('X' * get_terminal_size().width)
- confirm('Do the X’s exactly fill the width of the screen?')
- def tt_color():
- cmsg('Testing color:')
- confirm(blue('THIS TEXT') + ' should be blue. Is it?')
- def tt_license():
- cmsg('Testing do_license_msg() with pager')
- ymsg('Press "w" to test the pager, then "c" to continue')
- do_license_msg(cfg)
- def tt_line_input():
- set_vt100()
- cmsg('Testing line_input():')
- msg(fmt("""
- At the Ready? prompt type and hold down "y".
- Then Enter some text, followed by held-down ENTER.
- The held-down "y" and ENTER keys should be blocked, not affecting the output
- on screen or entered text.
- """))
- get_char_raw('Ready? ',num_bytes=1)
- reply = line_input( cfg, '\nEnter text: ' )
- confirm(f'Did you enter the text {reply!r}?')
- def _tt_get_char(raw=False,one_char=False,immed_chars=''):
- funcname = ('get_char','get_char_raw')[raw]
- fs = fmt("""
- Press some keys in quick succession.
- {}{}
- {}
- When you’re finished, use Ctrl-C to exit.
- """).strip()
- m1 = (
- 'You should experience a delay with quickly repeated entry.',
- 'Your entry should be repeated back to you immediately.'
- )[raw]
- m2 = (
- '',
- f'\nThe characters {immed_chars!r} will be repeated immediately, the others with delay.'
- )[bool(immed_chars)]
- m3 = 'The F1-F12 keys will be ' + (
- 'blocked entirely.'
- if one_char and not raw else
- "echoed AS A SINGLE character '\\x1b'."
- if one_char else
- 'echoed as a FULL CONTROL SEQUENCE.'
- )
- if sys.platform == 'win32':
- if raw:
- m3 = 'The Escape and F1-F12 keys will be returned as two-character strings.'
- else:
- m3 = 'The Escape and F1-F12 keys will be returned as single characters.'
- kwargs = {}
- if one_char:
- kwargs.update({'num_bytes':1})
- if immed_chars:
- kwargs.update({'immed_chars':immed_chars})
- cmsg('Testing {}({}):'.format(
- funcname,
- ','.join(f'{a}={b!r}' for a,b in kwargs.items())
- ))
- msg(fs.format( m1, yellow(m2), yellow(m3) ))
- try:
- while True:
- ret = getattr( term_mod, funcname )('Enter a letter: ',**kwargs)
- msg(f'You typed {ret!r}')
- except KeyboardInterrupt:
- msg('\nDone')
- def tt_urand():
- cmsg('Testing _get_random_data_from_user():')
- from mmgen.crypto import Crypto
- ret = Crypto(cfg)._get_random_data_from_user(uchars=10,desc='data').decode()
- msg(f'USER ENTROPY (user input + keystroke timings):\n\n{fmt(ret," ")}')
- times = ret.splitlines()[1:]
- avg_prec = sum(len(t.split('.')[1]) for t in times) // len(times)
- if avg_prec < gc.min_time_precision:
- ymsg(f'WARNING: Avg. time precision of only {avg_prec} decimal points. User entropy quality is degraded!')
- else:
- msg(f'Average time precision: {avg_prec} decimal points - OK')
- line_input( cfg, 'Press ENTER to continue: ' )
- def tt_txview():
- cmsg('Testing tx.info.view_with_prompt() (try each viewing option)')
- from mmgen.tx import UnsignedTX
- fn = 'test/ref/0B8D5A[15.31789,14,tl=1320969600].rawtx'
- tx = UnsignedTX(cfg=cfg,filename=fn,quiet_open=True)
- while True:
- tx.info.view_with_prompt('View data for transaction?',pause=False)
- set_vt100()
- if not keypress_confirm( cfg, 'Continue testing transaction view?', default_yes=True ):
- break
- def tt_get_char_one():
- _tt_get_char(one_char=True)
- def tt_get_char_one_raw():
- _tt_get_char(one_char=True,raw=True)
- def tt_get_char():
- _tt_get_char(one_char=False)
- def tt_get_char_immed_chars():
- _tt_get_char(one_char=False,immed_chars='asdf')
- def tt_get_char_raw():
- _tt_get_char(one_char=False,raw=True)
- def tt_get_char_one_char_immed_chars():
- _tt_get_char(one_char=True,immed_chars='asdf')
- get_term().register_cleanup()
- if cfg._args:
- locals()['tt_'+cfg._args[0]]()
- else:
- for command in commands:
- locals()['tt_'+command]()
- gmsg('\nTest completed')
|