blob: cce3722ff05386557d252c87a5901a2cf00f98c7 [file] [log] [blame]
# 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()