| # 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() |