def test_binary(self, tmpdir): """Test with binary data.""" filename = tmpdir / 'foo' with qtutils.savefile_open(str(filename), binary=True) as f: f.write(b'\xde\xad\xbe\xef') assert tmpdir.listdir() == [filename] assert filename.read_binary() == b'\xde\xad\xbe\xef'
def test_utf8(self, data, tmpdir): """Test with UTF8 data.""" filename = tmpdir / 'foo' filename.write("Old data") with qtutils.savefile_open(str(filename)) as f: f.write(data) assert tmpdir.listdir() == [filename] assert filename.read_text(encoding='utf-8') == data
def test_failing_commit(self, tmpdir): """Test with the file being closed before committing.""" filename = tmpdir / 'foo' with pytest.raises(OSError, match='Commit failed!'): with qtutils.savefile_open(str(filename), binary=True) as f: f.write(b'Hello') f.dev.cancelWriting() # provoke failing commit assert tmpdir.listdir() == []
def test_failing_flush(self, tmpdir): """Test with the file being closed before flushing.""" filename = tmpdir / 'foo' with pytest.raises(ValueError, match="IO operation on closed device!"): with qtutils.savefile_open(str(filename), binary=True) as f: f.write(b'Hello') f.dev.commit() # provoke failing flush assert tmpdir.listdir() == [filename]
def test_exception(self, tmpdir): """Test with an exception in the block.""" filename = tmpdir / 'foo' filename.write("Old content") with pytest.raises(SavefileTestException): with qtutils.savefile_open(str(filename)) as f: f.write("Hello World!") raise SavefileTestException assert tmpdir.listdir() == [filename] assert filename.read_text(encoding='utf-8') == "Old content"
def test_mock_exception(self, qsavefile_mock): """Test with a mock and an exception in the block.""" qsavefile_mock.open.return_value = True with pytest.raises(SavefileTestException): with qtutils.savefile_open('filename'): raise SavefileTestException qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly) qsavefile_mock.cancelWriting.assert_called_once_with()
def test_existing_dir(self, tmpdir): """Test with the filename already occupied by a directory.""" filename = tmpdir / 'foo' filename.mkdir() with pytest.raises(OSError) as excinfo: with qtutils.savefile_open(str(filename)): pass errors = ["Filename refers to a directory", # Qt >= 5.4 "Commit failed!"] # older Qt versions assert str(excinfo.value) in errors assert tmpdir.listdir() == [filename]
def test_mock_open_error(self, qsavefile_mock): """Test with a mock and a failing open().""" qsavefile_mock.open.return_value = False qsavefile_mock.errorString.return_value = "Hello World" with pytest.raises(OSError, match="Hello World"): with qtutils.savefile_open('filename'): pass qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly) qsavefile_mock.cancelWriting.assert_called_once_with()
def test_mock_commit_failed(self, qsavefile_mock): """Test with a mock and an exception in the block.""" qsavefile_mock.open.return_value = True qsavefile_mock.commit.return_value = False with pytest.raises(OSError, match="Commit failed!"): with qtutils.savefile_open('filename'): pass qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly) assert not qsavefile_mock.cancelWriting.called assert not qsavefile_mock.errorString.called
def save(self): """Save the config file.""" limit = config.instance.get(self._limit) if limit == 0: return do_save = self._prepare_save() if not do_save: return assert self._configfile is not None with qtutils.savefile_open(self._configfile, self._binary) as f: self._write(f, self.data[-limit:]) self._after_save()
def test_line_endings(self, tmpdir): """Make sure line endings are translated correctly. See https://github.com/glimpsebrowser/glimpsebrowser/issues/309 """ filename = tmpdir / 'foo' with qtutils.savefile_open(str(filename)) as f: f.write('foo\nbar\nbaz') data = filename.read_binary() if utils.is_windows: assert data == b'foo\r\nbar\r\nbaz' else: assert data == b'foo\nbar\nbaz'
def test_mock_successful(self, qsavefile_mock): """Test with a mock and a successful write.""" qsavefile_mock.open.return_value = True qsavefile_mock.errorString.return_value = "Hello World" qsavefile_mock.commit.return_value = True qsavefile_mock.write.side_effect = len qsavefile_mock.isOpen.return_value = True with qtutils.savefile_open('filename') as f: f.write("Hello World") qsavefile_mock.open.assert_called_once_with(QIODevice.WriteOnly) assert not qsavefile_mock.cancelWriting.called qsavefile_mock.write.assert_called_once_with(b"Hello World")
def save(self): """Save the config file.""" if self._opened: raise IOError("Refusing to double-open LineParser.") do_save = self._prepare_save() if not do_save: return self._opened = True try: assert self._configfile is not None with qtutils.savefile_open(self._configfile, self._binary) as f: self._write(f, self.data) finally: self._opened = False self._after_save()
def save(self, name, last_window=False, load_next_time=False, only_window=None, with_private=False): """Save a named session. Args: name: The name of the session to save, or the 'default' sentinel object. last_window: If set, saves the saved self._last_window_session instead of the currently open state. load_next_time: If set, prepares this session to be load next time. only_window: If set, only tabs in the specified window is saved. with_private: Include private windows. Return: The name of the saved session. """ name = self._get_session_name(name) path = self._get_session_path(name) log.sessions.debug("Saving session {} to {}...".format(name, path)) if last_window: data = self._last_window_session if data is None: log.sessions.error("last_window_session is None while saving!") return None else: data = self._save_all(only_window=only_window, with_private=with_private) log.sessions.vdebug("Saving data: {}".format(data)) try: with qtutils.savefile_open(path) as f: utils.yaml_dump(data, f) except (OSError, UnicodeEncodeError, yaml.YAMLError) as e: raise SessionError(e) if load_next_time: configfiles.state['general']['session'] = name return name
def _save(self) -> None: """Save the settings to the YAML file if they've changed.""" if not self._dirty: return settings = {} # type: YamlConfig._SettingsType for name, values in sorted(self._values.items()): if not values: continue settings[name] = {} for scoped in values: key = ('global' if scoped.pattern is None else str(scoped.pattern)) settings[name][key] = scoped.value data = {'config_version': self.VERSION, 'settings': settings} with qtutils.savefile_open(self._filename) as f: f.write( textwrap.dedent(""" # DO NOT edit this file by hand, glimpsebrowser will overwrite it. # Instead, create a config.py - see :help for details. """.lstrip('\n'))) utils.yaml_dump(data, f)