Files
playerctl/test/test_format.py
2021-02-15 23:42:50 +00:00

186 lines
5.5 KiB
Python

from dbus_next import Variant
from .mpris import setup_mpris
from .playerctl import PlayerctlCli
import pytest
import asyncio
# TODO: test missing function does not segv
@pytest.mark.asyncio
async def test_emoji(bus_address):
[mpris] = await setup_mpris('emoji-format-test', bus_address=bus_address)
mpris.metadata = {'mpris:length': Variant('x', 100000)}
await mpris.ping()
playerctl = PlayerctlCli(bus_address)
status_emoji_cmd = 'metadata --format \'{{emoji(status)}}\''
mpris.playback_status = 'Playing'
cmd = await playerctl.run(status_emoji_cmd)
assert cmd.stdout == '▶️', cmd.stderr
mpris.playback_status = 'Paused'
cmd = await playerctl.run(status_emoji_cmd)
assert cmd.stdout == '⏸️', cmd.stderr
mpris.playback_status = 'Stopped'
cmd = await playerctl.run(status_emoji_cmd)
assert cmd.stdout == '⏹️', cmd.stderr
volume_emoji_cmd = 'metadata --format \'{{emoji(volume)}}\''
mpris.volume = 0.0
cmd = await playerctl.run(volume_emoji_cmd)
assert cmd.stdout == '🔈', cmd.stderr
mpris.volume = 0.5
cmd = await playerctl.run(volume_emoji_cmd)
assert cmd.stdout == '🔉', cmd.stderr
mpris.volume = 1.0
cmd = await playerctl.run(volume_emoji_cmd)
assert cmd.stdout == '🔊', cmd.stderr
cmd = await playerctl.run('metadata --format \'{{emoji("hi")}}\'')
assert cmd.returncode == 1, cmd.stderr
cmd = await playerctl.run('metadata --format \'{{emoji(status, volume)}}\''
)
assert cmd.returncode == 1, cmd.stderr
await mpris.disconnect()
class MetadataTest:
def __init__(self, playerctl):
self.tests = []
self.playerctl = playerctl
def add(self, fmt, expected, ret=0):
fmt = fmt.replace("'", r"\'")
self.tests.append((f"metadata --format '{fmt}'", expected, ret))
async def run(self):
coros = []
for fmt, _, _ in self.tests:
coros.append(self.playerctl.run(fmt))
results = await asyncio.gather(*coros)
for i, cmd in enumerate(results):
fmt, expected, ret = self.tests[i]
assert cmd.returncode == ret, cmd.stderr
if ret == 0:
assert cmd.stdout == expected, cmd.stderr
@pytest.mark.asyncio
async def test_format(bus_address):
title = 'A Title'
artist = 'An Artist'
album = 'An Album'
player_name = 'format-test'
player_instance = f'{player_name}.instance123'
[mpris] = await setup_mpris(player_instance, bus_address=bus_address)
mpris.metadata = {
'xesam:title': Variant('s', title),
'xesam:artist': Variant('as', [artist]),
'xesam:escapeme': Variant('s', '<hi>'),
'xesam:album': Variant('s', album),
'mpris:length': Variant('x', 100000)
}
mpris.volume = 2.0
playerctl = PlayerctlCli(bus_address)
test = MetadataTest(playerctl)
test.add('{{artist}} - {{title}}', f'{artist} - {title}')
test.add("{{markup_escape(xesam:escapeme)}}", "&lt;hi&gt;")
test.add("{{lc(artist)}}", artist.lower())
test.add("{{uc(title)}}", title.upper())
test.add("{{uc(lc(title))}}", title.upper())
test.add('{{uc("Hi")}}', "HI")
test.add("{{mpris:length}}", "100000")
test.add(
'@{{ uc( "hi" ) }} - {{uc( lc( "HO" ) ) }} . {{lc( uc( title ) ) }}@',
f'@HI - HO . {title.lower()}@')
test.add("{{default(xesam:missing, artist)}}", artist)
test.add("{{default(title, artist)}}", title)
test.add('{{default("", "ok")}}', 'ok')
test.add('{{default("ok", "not")}}', 'ok')
test.add(' {{lc(album)}} ', album.lower())
test.add('{{playerName}} - {{playerInstance}}',
f'{player_name} - {player_instance}')
test.add("{{trunc(title, 10)}}", title)
test.add("{{trunc(title, 5)}}", f"{title[:5]}")
test.add('{{trunc("", 0)}}', "")
test.add('{{trunc("", 10)}}', "")
await test.run()
# numbers
math = [
'10',
'-10 + 20',
'10 + 10',
'10 * 10',
'10 / 10',
'10 + 10 * 10 + 10',
'10 + 10 * -10 + 10',
'10 + 10 * -10 + -10',
'-10 * 10 + 10',
'-10 * -10 * -1 + -10',
'-10 * 10 + -10 * -10 + 20 / 10 * -20 + -10',
'8+-+--++-4',
'2 - 10 * 1 + 1',
'2 / -2 + 2 * 2 * -2 - 2 - 2 * -2',
'2 * (2 + 2)',
'10 * (10 + 12) - 4',
'-(10)',
'-(10 + 12 * -2)',
'14 - (10 * 2 + 5) * -6',
'(14 - 2 * 3) * (14 * -2 - 6) + -(4 - 2) * 5',
]
# variables
math += [
'volume',
'volume + 10',
'-volume',
'-volume * -1',
'-volume + volume',
'volume * volume',
'volume * -volume',
'volume + volume * -volume * volume + -volume',
'volume / -volume + volume * volume * -volume - volume - volume * -volume',
'-(volume + 3) * 5 * (volume + 2)',
]
# functions
math += [
'default(5+5, None)',
'-default(5 + 5, None)',
'(-default(5 - 5, None) + 2) * 8',
'2 + (5 * 4 + 3 * -default(5, default(6 * (3 + 4 * (6 + 2)) / 2, None)) + -56)',
]
def default_shim(arg1, arg2):
if arg1 is None:
return arg2
return arg1
async def math_test(math):
cmd = await playerctl.run("metadata --format '{{" + math + "}}'")
assert cmd.returncode == 0, cmd.stderr
assert float(cmd.stdout) == eval(math, {
'volume': mpris.volume,
'default': default_shim
}), math
await asyncio.gather(*[math_test(m) for m in math])
await mpris.disconnect()