diff options
Diffstat (limited to 'pw_ide/py/editors_test.py')
-rw-r--r-- | pw_ide/py/editors_test.py | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/pw_ide/py/editors_test.py b/pw_ide/py/editors_test.py new file mode 100644 index 000000000..cce3722ff --- /dev/null +++ b/pw_ide/py/editors_test.py @@ -0,0 +1,342 @@ +# Copyright 2022 The Pigweed Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may not +# use this file except in compliance with the License. You may obtain a copy of +# the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations under +# the License. +"""Tests for pw_ide.editors""" + +from collections import OrderedDict +from enum import Enum +import unittest + +from pw_ide.editors import ( + dict_deep_merge, + EditorSettingsFile, + EditorSettingsManager, + JsonFileFormat, +) + +from test_cases import PwIdeTestCase + + +class TestDictDeepMerge(unittest.TestCase): + """Tests dict_deep_merge""" + + def test_invariants_with_dict_success(self): + # pylint: disable=unnecessary-lambda + dict_a = {'hello': 'world'} + dict_b = {'foo': 'bar'} + + expected = { + 'hello': 'world', + 'foo': 'bar', + } + + result = dict_deep_merge(dict_b, dict_a, lambda: dict()) + self.assertEqual(result, expected) + + def test_invariants_with_dict_implicit_ctor_success(self): + # pylint: disable=unnecessary-lambda + dict_a = {'hello': 'world'} + dict_b = {'foo': 'bar'} + + expected = { + 'hello': 'world', + 'foo': 'bar', + } + + result = dict_deep_merge(dict_b, dict_a) + self.assertEqual(result, expected) + + def test_invariants_with_dict_fails_wrong_ctor_type(self): + # pylint: disable=unnecessary-lambda + dict_a = {'hello': 'world'} + dict_b = {'foo': 'bar'} + + with self.assertRaises(TypeError): + dict_deep_merge(dict_b, dict_a, lambda: OrderedDict()) + + def test_invariants_with_ordered_dict_success(self): + # pylint: disable=unnecessary-lambda + dict_a = OrderedDict({'hello': 'world'}) + dict_b = OrderedDict({'foo': 'bar'}) + + expected = OrderedDict( + { + 'hello': 'world', + 'foo': 'bar', + } + ) + + result = dict_deep_merge(dict_b, dict_a, lambda: OrderedDict()) + self.assertEqual(result, expected) + + def test_invariants_with_ordered_dict_implicit_ctor_success(self): + # pylint: disable=unnecessary-lambda + dict_a = OrderedDict({'hello': 'world'}) + dict_b = OrderedDict({'foo': 'bar'}) + + expected = OrderedDict( + { + 'hello': 'world', + 'foo': 'bar', + } + ) + + result = dict_deep_merge(dict_b, dict_a) + self.assertEqual(result, expected) + + def test_invariants_with_ordered_dict_fails_wrong_ctor_type(self): + # pylint: disable=unnecessary-lambda + dict_a = OrderedDict({'hello': 'world'}) + dict_b = OrderedDict({'foo': 'bar'}) + + with self.assertRaises(TypeError): + dict_deep_merge(dict_b, dict_a, lambda: dict()) + + +class TestEditorSettingsFile(PwIdeTestCase): + """Tests EditorSettingsFile""" + + def test_open_new_file_and_write(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + with open(self.temp_dir_path / f'{name}.{json_fmt.ext}') as file: + settings_dict = json_fmt.load(file) + + self.assertEqual(settings_dict['hello'], 'world') + + def test_open_new_file_and_get(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + settings_dict = settings_file.get() + self.assertEqual(settings_dict['hello'], 'world') + + def test_open_new_file_no_backup(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + backup_files = [ + path + for path in self.temp_dir_path.iterdir() + if path.name != f'{name}.{json_fmt.ext}' + ] + + self.assertEqual(len(backup_files), 0) + + def test_open_existing_file_and_backup(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + with settings_file.modify() as settings: + settings['hello'] = 'mundo' + + settings_dict = settings_file.get() + self.assertEqual(settings_dict['hello'], 'mundo') + + backup_files = [ + path + for path in self.temp_dir_path.iterdir() + if path.name != f'{name}.{json_fmt.ext}' + ] + + self.assertEqual(len(backup_files), 1) + + with open(backup_files[0]) as file: + settings_dict = json_fmt.load(file) + + self.assertEqual(settings_dict['hello'], 'world') + + def test_open_existing_file_with_reinit_and_backup(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + with settings_file.modify(reinit=True) as settings: + settings['hello'] = 'mundo' + + settings_dict = settings_file.get() + self.assertEqual(settings_dict['hello'], 'mundo') + + backup_files = [ + path + for path in self.temp_dir_path.iterdir() + if path.name != f'{name}.{json_fmt.ext}' + ] + + self.assertEqual(len(backup_files), 1) + + with open(backup_files[0]) as file: + settings_dict = json_fmt.load(file) + + self.assertEqual(settings_dict['hello'], 'world') + + def open_existing_file_no_change_no_backup(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + settings_dict = settings_file.get() + self.assertEqual(settings_dict['hello'], 'world') + + backup_files = [ + path + for path in self.temp_dir_path.iterdir() + if path.name != f'{name}.{json_fmt.ext}' + ] + + self.assertEqual(len(backup_files), 0) + + with open(backup_files[0]) as file: + settings_dict = json_fmt.load(file) + + self.assertEqual(settings_dict['hello'], 'world') + + def test_write_bad_file_restore_backup(self): + name = 'settings' + json_fmt = JsonFileFormat() + settings_file = EditorSettingsFile(self.temp_dir_path, name, json_fmt) + + with settings_file.modify() as settings: + settings['hello'] = 'world' + + with self.assertRaises(TypeError): + with settings_file.modify() as settings: + settings['hello'] = object() + + settings_dict = settings_file.get() + self.assertEqual(settings_dict['hello'], 'world') + + backup_files = [ + path + for path in self.temp_dir_path.iterdir() + if path.name != f'{name}.{json_fmt.ext}' + ] + + self.assertEqual(len(backup_files), 0) + + +class EditorSettingsTestType(Enum): + SETTINGS = 'settings' + + +class TestEditorSettingsManager(PwIdeTestCase): + """Tests EditorSettingsManager""" + + def test_settings_merge(self): + """Test that settings merge as expected in isolation.""" + default_settings = OrderedDict( + { + 'foo': 'bar', + 'baz': 'qux', + 'lorem': OrderedDict( + { + 'ipsum': 'dolor', + } + ), + } + ) + + types_with_defaults = { + EditorSettingsTestType.SETTINGS: lambda _: default_settings + } + + ide_settings = self.make_ide_settings() + json_fmt = JsonFileFormat() + manager = EditorSettingsManager( + ide_settings, self.temp_dir_path, json_fmt, types_with_defaults + ) + + project_settings = OrderedDict( + { + 'alpha': 'beta', + 'baz': 'xuq', + 'foo': 'rab', + } + ) + + with manager.project( + EditorSettingsTestType.SETTINGS + ).modify() as settings: + dict_deep_merge(project_settings, settings) + + user_settings = OrderedDict( + { + 'baz': 'xqu', + 'lorem': OrderedDict( + { + 'ipsum': 'sit amet', + 'consectetur': 'adipiscing', + } + ), + } + ) + + with manager.user(EditorSettingsTestType.SETTINGS).modify() as settings: + dict_deep_merge(user_settings, settings) + + expected = { + 'alpha': 'beta', + 'foo': 'rab', + 'baz': 'xqu', + 'lorem': { + 'ipsum': 'sit amet', + 'consectetur': 'adipiscing', + }, + } + + with manager.active( + EditorSettingsTestType.SETTINGS + ).modify() as active_settings: + manager.default(EditorSettingsTestType.SETTINGS).sync_to( + active_settings + ) + manager.project(EditorSettingsTestType.SETTINGS).sync_to( + active_settings + ) + manager.user(EditorSettingsTestType.SETTINGS).sync_to( + active_settings + ) + + self.assertCountEqual( + manager.active(EditorSettingsTestType.SETTINGS).get(), expected + ) + + +if __name__ == '__main__': + unittest.main() |