Merge pull request #1638 from dbungert/lunar-2023-04-05
Lunar 2023 04 05
This commit is contained in:
commit
d1b1dce0df
|
@ -158,6 +158,12 @@ AnyStep = Union[StepPressKey, StepKeyPresent, StepResult]
|
|||
|
||||
@attr.s(auto_attribs=True)
|
||||
class KeyboardSetting:
|
||||
# This data structure represents a subset of the XKB options.
|
||||
# As explained in the XKB configuration guide, XkbLayout and
|
||||
# XkbVariant can hold multiple comma-separated values.
|
||||
# http://www.xfree86.org/current/XKB-Config2.html#4
|
||||
# Ideally, we would internally represent a keyboard setting as a
|
||||
# toggle + a list of [layout, variant].
|
||||
layout: str
|
||||
variant: str = ''
|
||||
toggle: Optional[str] = None
|
||||
|
|
|
@ -43,6 +43,15 @@ BACKSPACE="guess"
|
|||
"""
|
||||
|
||||
|
||||
class InconsistentMultiLayoutError(ValueError):
|
||||
""" Exception to raise when a multi layout has a different number of
|
||||
layouts and variants. """
|
||||
def __init__(self, layouts: str, variants: str) -> None:
|
||||
super().__init__(
|
||||
f'inconsistent multi-layout: layouts="{layouts}"'
|
||||
f' variants="{variants}"')
|
||||
|
||||
|
||||
def from_config_file(config_file):
|
||||
with open(config_file) as fp:
|
||||
content = fp.read()
|
||||
|
@ -91,13 +100,21 @@ class KeyboardModel:
|
|||
self._setting = value
|
||||
|
||||
def validate_setting(self, setting: KeyboardSetting) -> None:
|
||||
kbd_layout = self.keyboard_list.layout_map.get(setting.layout)
|
||||
if kbd_layout is None:
|
||||
raise ValueError(f'Unknown keyboard layout "{setting.layout}"')
|
||||
if not any(variant.code == setting.variant
|
||||
for variant in kbd_layout.variants):
|
||||
raise ValueError(f'Unknown keyboard variant "{setting.variant}" '
|
||||
f'for layout "{setting.layout}"')
|
||||
layout_tokens = setting.layout.split(",")
|
||||
variant_tokens = setting.variant.split(",")
|
||||
|
||||
if len(layout_tokens) != len(variant_tokens):
|
||||
raise InconsistentMultiLayoutError(
|
||||
layouts=setting.layout, variants=setting.variant)
|
||||
|
||||
for layout, variant in zip(layout_tokens, variant_tokens):
|
||||
kbd_layout = self.keyboard_list.layout_map.get(layout)
|
||||
if kbd_layout is None:
|
||||
raise ValueError(f'Unknown keyboard layout "{layout}"')
|
||||
if not any(kbd_variant.code == variant
|
||||
for kbd_variant in kbd_layout.variants):
|
||||
raise ValueError(f'Unknown keyboard variant "{variant}" '
|
||||
f'for layout "{layout}"')
|
||||
|
||||
def render_config_file(self):
|
||||
options = ""
|
||||
|
|
|
@ -18,7 +18,10 @@ from subiquitycore.tests.parameterized import parameterized
|
|||
from subiquitycore.tests import SubiTestCase
|
||||
|
||||
from subiquity.common.types import KeyboardSetting
|
||||
from subiquity.models.keyboard import KeyboardModel
|
||||
from subiquity.models.keyboard import (
|
||||
InconsistentMultiLayoutError,
|
||||
KeyboardModel,
|
||||
)
|
||||
|
||||
|
||||
class TestKeyboardModel(SubiTestCase):
|
||||
|
@ -45,6 +48,25 @@ class TestKeyboardModel(SubiTestCase):
|
|||
self.model.setting = val
|
||||
self.assertEqual(initial, self.model.setting)
|
||||
|
||||
def testMultiLayout(self):
|
||||
val = KeyboardSetting(layout='us,ara', variant=',')
|
||||
self.model.setting = val
|
||||
self.assertEqual(self.model.setting, val)
|
||||
|
||||
def testInconsistentMultiLayout(self):
|
||||
initial = self.model.setting
|
||||
val = KeyboardSetting(layout='us,ara', variant='')
|
||||
with self.assertRaises(InconsistentMultiLayoutError):
|
||||
self.model.setting = val
|
||||
self.assertEqual(self.model.setting, initial)
|
||||
|
||||
def testInvalidMultiLayout(self):
|
||||
initial = self.model.setting
|
||||
val = KeyboardSetting(layout='us,ara', variant='zz,')
|
||||
with self.assertRaises(ValueError):
|
||||
self.model.setting = val
|
||||
self.assertEqual(self.model.setting, initial)
|
||||
|
||||
@parameterized.expand([
|
||||
['ast_ES.UTF-8', 'es', 'ast'],
|
||||
['de_DE.UTF-8', 'de', ''],
|
||||
|
|
|
@ -776,7 +776,7 @@ class FilesystemController(SubiquityController, FilesystemManipulator):
|
|||
@with_context(name='probe_once', description='restricted={restricted}')
|
||||
async def _probe_once(self, *, context, restricted):
|
||||
if restricted:
|
||||
probe_types = {'blockdev'}
|
||||
probe_types = {'blockdev', 'filesystem'}
|
||||
fname = 'probe-data-restricted.json'
|
||||
key = "ProbeDataRestricted"
|
||||
else:
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import logging
|
||||
from typing import Dict, Optional, Sequence
|
||||
from typing import Dict, Optional, Sequence, Tuple
|
||||
import os
|
||||
import pwd
|
||||
|
||||
|
@ -48,7 +48,7 @@ standard_non_latin_layouts = set(
|
|||
default_desktop_user = 'ubuntu'
|
||||
|
||||
|
||||
def latinizable(layout_code, variant_code):
|
||||
def latinizable(layout_code, variant_code) -> Optional[Tuple[str, str]]:
|
||||
"""
|
||||
If this setting does not allow the typing of latin characters,
|
||||
return a setting that can be switched to one that can.
|
||||
|
|
|
@ -62,7 +62,8 @@ class TestSubiquityControllerFilesystem(IsolatedAsyncioTestCase):
|
|||
|
||||
async def test_probe_restricted(self):
|
||||
await self.fsc._probe_once(context=None, restricted=True)
|
||||
self.app.prober.get_storage.assert_called_with({'blockdev'})
|
||||
expected = {'blockdev', 'filesystem'}
|
||||
self.app.prober.get_storage.assert_called_with(expected)
|
||||
|
||||
async def test_probe_os_prober_false(self):
|
||||
self.app.opts.use_os_prober = False
|
||||
|
|
Loading…
Reference in New Issue