From e927f8da62548ca80efa2c89129ebb95f4261b55 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 17 Jul 2024 11:11:39 +0530 Subject: [PATCH] Add some tests for easing function parsing --- kitty/options/utils.py | 33 ++++++++++++++++++++------------- kitty_tests/options.py | 20 +++++++++++++++++++- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/kitty/options/utils.py b/kitty/options/utils.py index eff704af3..415c0f2d5 100644 --- a/kitty/options/utils.py +++ b/kitty/options/utils.py @@ -1394,11 +1394,14 @@ def parse_font_spec(spec: str) -> FontSpec: return FontSpec.from_setting(spec) +JumpTypes = Literal['start', 'end', 'none', 'both'] + + class EasingFunction(NamedTuple): type: Literal['steps', 'linear', 'cubic-bezier', ''] = '' num_steps: int = 0 - jump_type: Literal['start', 'end', 'none', 'both'] = 'end' + jump_type: JumpTypes = 'end' linear_x: Tuple[float, ...] = () linear_y: Tuple[float, ...] = () @@ -1418,7 +1421,7 @@ class EasingFunction(NamedTuple): if len(parts) != 4: raise ValueError('cubic-bezier easing function must have four points') return cls(type='cubic-bezier', cubic_bezier_points=( - unit_float(parts[0]), float(parts[1]), unit_float(parts[2]), float(parts[2]))) + unit_float(parts[0]), float(parts[1]), unit_float(parts[2]), float(parts[3]))) @classmethod def linear(cls, params: str) -> 'EasingFunction': @@ -1432,12 +1435,16 @@ class EasingFunction(NamedTuple): extra = len(yaxis) - len(xaxis) if extra <= 0: return - start = xaxis[-1] if xaxis else 0 - delta = (end - start) / (extra + 1) - if delta <= 0: + start = xaxis[-1] if xaxis else 0. + delta = (end - start) / max(1, extra - 1) + if delta <= 0.: raise ValueError(f'Linear easing curve must have strictly increasing points: {params} does not') - for i in range(extra): - xaxis.append((i+1) * delta) + if xaxis: + for i in range(extra): + xaxis.append(start + (i+1) * delta) + else: + for i in range(extra): + xaxis.append(i * delta) def add_point(y: float, x: Optional[float] = None) -> None: if x is None: @@ -1463,18 +1470,18 @@ class EasingFunction(NamedTuple): balance(1) return cls(type='linear', linear_x=tuple(xaxis), linear_y=tuple(yaxis)) - @classmethod def steps(cls, params: str) -> 'EasingFunction': parts = params.replace(',', ' ').split() - jump_type = 'end' + jump_type: JumpTypes = 'end' if len(parts) == 2: n = int(parts[0]) jt = parts[1] + mapping: Dict[str, JumpTypes] = { + 'jump-start': 'start', 'start': 'start', 'end': 'end', 'jump-end': 'end', 'jump-none': 'none', 'jump-both': 'both' + } try: - jump_type = { - 'jump-start': 'start', 'start': 'start', 'end': 'end', 'jump-end': 'end', 'jump-none': 'none', 'jump-both': 'both' - }[jt.lower()] + jump_type = mapping[jt.lower()] except KeyError: raise KeyError(f'{jt} is not a valid jump type for a linear easing function') if jump_type == 'none': @@ -1483,7 +1490,7 @@ class EasingFunction(NamedTuple): n = max(1, n) else: n = max(1, int(parts[0])) - return cls(type='steps', jump_type=jump_type, num_steps=n) # type: ignore + return cls(type='steps', jump_type=jump_type, num_steps=n) def cursor_blink_interval(spec: str) -> Tuple[float, EasingFunction, EasingFunction]: diff --git a/kitty_tests/options.py b/kitty_tests/options.py index 87bddd991..0822e3a21 100644 --- a/kitty_tests/options.py +++ b/kitty_tests/options.py @@ -3,7 +3,7 @@ from kitty.fast_data_types import Color -from kitty.options.utils import DELETE_ENV_VAR +from kitty.options.utils import DELETE_ENV_VAR, EasingFunction from kitty.utils import log_error from . import BaseTest @@ -137,3 +137,21 @@ class TestConfParsing(BaseTest): " \\ blue") self.ae(opts.font_size, 12.35) self.ae(opts.color25, Color(0, 0, 255)) + + # cursor_blink_interval + def cb(src, interval=-1, first=EasingFunction(), second=EasingFunction()): + opts = p('cursor_blink_interval ' + src) + self.ae((float(interval), first, second), (float(opts.cursor_blink_interval[0]), opts.cursor_blink_interval[1], opts.cursor_blink_interval[2])) + cb('3', 3) + cb('-2.3', -2.3) + cb('linear', first=EasingFunction('cubic-bezier', cubic_bezier_points=(0, 0.0, 1.0, 1.0))) + cb('linear 19', 19, EasingFunction('cubic-bezier', cubic_bezier_points=(0, 0.0, 1.0, 1.0))) + cb('ease-in-out cubic-bezier(0.1, 0.2, 0.3, 0.4) 11', 11, + EasingFunction('cubic-bezier', cubic_bezier_points=(0.42, 0, 0.58, 1)), + EasingFunction('cubic-bezier', cubic_bezier_points=(0.1, 0.2, 0.3, 0.4)) + ) + cb('step-start', first=EasingFunction('steps', num_steps=1, jump_type='start')) + cb('steps(7, jump-none)', first=EasingFunction('steps', num_steps=7, jump_type='none')) + cb('linear(0, 0.25, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.5, 1.0), linear_y=(0, 0.25, 1.0))) + cb('linear(0, 0.25 75%, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.75, 1.0), linear_y=(0, 0.25, 1.0))) + cb('linear(0, 0.25 25% 75%, 1)', first=EasingFunction('linear', linear_x=(0.0, 0.25, 0.75, 1.0), linear_y=(0, 0.25, 0.25, 1.0)))