def test_update(self): """Test updating the rcParams""" w = prefs.GuiRcParamsWidget() w.initialize() fname = tempfile.NamedTemporaryFile( prefix='psyplot_gui_test', suffix='.yml').name self._created_files.add(fname) gui_rcParams.find_all('console').dump(fname) keys = [] for item in w.tree.top_level_items: if asstring(item.text(0)).startswith('help_explorer'): item.setSelected(True) keys.append(asstring(item.text(0))) self.assertEqual(len(w.tree.selectedItems()), len(keys)) action = w.save_settings_action(update=True, target=fname) action.trigger() self.assertTrue(osp.exists(fname)) rc = GuiRcParams(defaultParams=gui_rcParams.defaultParams) rc.load_from_file(fname) self.assertEqual( dict(rc), {key: gui_rcParams[key] for key in gui_rcParams if key.startswith('console') or key.startswith('help_explorer')})
def check_figs(msg=None): arrays = iter(sp) for i, (fig, val) in enumerate(sp.figs.items()): top = self.tree.topLevelItem(i) self.assertEqual(asstring(top.text(0)), fig.canvas.get_window_title()) for child in map(top.child, range(top.childCount())): self.assertEqual(asstring(child.text(0)), next(arrays).psy._short_info(), msg=msg)
def test_plusplus(self): """Test the add all button""" # loag a dataset self.test_load_external_file() QTest.mouseClick(self.pc.bt_add_all, Qt.LeftButton) atab = self.pc.array_table vtab = self.pc.variables_table self.assertEqual( [asstring(atab.item(irow, 0).text()) for irow in range( atab.rowCount())], [asstring(vtab.item(irow, 0).text()) for irow in range( vtab.rowCount())])
def test_content_update(self): """Test whether the list is updated correctly""" w = self.content_widget lists = w.lists # currently it should be empty self.assertEqual(w.count(), 1) self.assertEqual(w.indexOf(lists['All']), 0) self.assertFalse(w.isItemEnabled(0), msg='List "All" is enabled!') # create some plots sp = psy.plot.plot2d(self.get_file('test-t2m-u-v.nc'), name='t2m') sp2 = psy.plot.lineplot(self.get_file('test-t2m-u-v.nc'), name='t2m', t=0, x=0, y=0) d = defaultdict(lambda: 1) d['All'] = 2 d['simple'] = 2 for name in ['All', 'simple', 'lineplot', 'plot2d']: self.assertIn(name, lists) l = lists[name] i = self.content_widget.indexOf(l) self.assertNotEqual(i, -1, msg='Missing the list in the widget!') self.assertTrue(self.content_widget.isItemEnabled(i), msg='%s is not enabled!' % name) self.assertEqual(l.count(), d[name], msg='Wrong number of arrays in %s' % name) if name == 'plot2d': self.assertEqual(asstring(l.item(0).text()), sp[0].psy._short_info(), msg='Wrong text in plot2d') else: self.assertEqual(asstring(l.item(d[name] - 1).text()), sp2[0]._short_info(), msg='Wrong text in %s' % name) self.assertEqual(self._selected_rows('plot2d'), [], msg='Array in %s is wrongly selected!' % name) self.assertEqual(self._selected_rows('lineplot'), [0], msg='Array in %s is not selected!' % name) self.assertEqual(self._selected_rows('simple'), [1], msg='Wrong selection!') self.assertEqual(self._selected_rows('All'), [1], msg='Wrong selection!') # close the project full = sp + sp2 full.close(True, True, True) self.assertEqual(w.count(), 1) self.assertEqual(w.indexOf(lists['All']), 0) self.assertFalse(w.isItemEnabled(0), msg='List "All" is enabled!')
def _get_rc(self, filter_func=None): """Iterate over the rcParams This function applies the given `filter_func` to check whether the item should be included or not Parameters ---------- filter_func: function A function that accepts the following arguments: item The QTreeWidgetItem key The rcParams key val The proposed value orig The current value Yields ------ QTreeWidgetItem The corresponding topLevelItem str The rcParams key object The proposed value object The current value """ def no_check(item, key, val, orig): return True rc = self.rc filter_func = filter_func or no_check for item in self.top_level_items: key = asstring(item.text(0)) editor = self.itemWidget(item.child(0), self.value_col) val = yaml.load(asstring(editor.toPlainText()), Loader=yaml.Loader) try: val = rc.validate[key](val) except: pass try: include = filter_func(item, key, val, rc[key]) except: warn('Could not check state for %s key' % key, RuntimeWarning) else: if include: yield (item, key, val, rc[key])
def _get_rc(self, filter_func=None): """Iterate over the rcParams This function applies the given `filter_func` to check whether the item should be included or not Parameters ---------- filter_func: function A function that accepts the following arguments: item The QTreeWidgetItem key The rcParams key val The proposed value orig The current value Yields ------ QTreeWidgetItem The corresponding topLevelItem str The rcParams key object The proposed value object The current value """ def no_check(item, key, val, orig): return True rc = self.rc filter_func = filter_func or no_check for item in self.top_level_items: key = asstring(item.text(0)) editor = self.itemWidget(item.child(0), self.value_col) val = yaml.load(asstring(editor.toPlainText())) try: val = rc.validate[key](val) except: pass try: include = filter_func(item, key, val, rc[key]) except: warn('Could not check state for %s key' % key, RuntimeWarning) else: if include: yield (item, key, val, rc[key])
def test_plus(self): """Test the add button""" self.test_load_external_file() vtab = self.pc.variables_table atab = self.pc.array_table nvar = vtab.rowCount() rows = [nvar - 2, nvar - 1] for row in rows: vtab.item(row, 0).setSelected(True) QTest.mouseClick(self.pc.bt_add, Qt.LeftButton) self.assertEqual( [asstring(atab.item(irow, 0).text()) for irow in range( atab.rowCount())], [asstring(vtab.item(irow, 0).text()) for irow in rows])
def _test_ds_representation(self, ds): toplevel = self._get_toplevel_item(ds) coords = set(ds.coords) variables = set(ds.variables) - coords for child in map(toplevel.variables.child, range(toplevel.variables.childCount())): variables.remove(asstring(child.text(0))) self.assertEqual(len(variables), 0, msg='Variables not found: %s' % ( variables)) for child in map(toplevel.coords.child, range(toplevel.coords.childCount())): coords.remove(asstring(child.text(0))) self.assertEqual(len(coords), 0, msg='Coordinates not found: %s' % ( coords))
def test_content_update(self): """Test whether the list is updated correctly""" w = self.content_widget lists = w.lists # currently it should be empty self.assertEqual(w.count(), 1) self.assertEqual(w.indexOf(lists['All']), 0) self.assertFalse(w.isItemEnabled(0), msg='List "All" is enabled!') # create some plots sp = psy.plot.plot2d(self.get_file('test-t2m-u-v.nc'), name='t2m') sp2 = psy.plot.lineplot(self.get_file('test-t2m-u-v.nc'), name='t2m', t=0, x=0, y=0) d = defaultdict(lambda: 1) d['All'] = 2 d['simple'] = 2 for name in ['All', 'simple', 'lineplot', 'plot2d']: self.assertIn(name, lists) l = lists[name] i = self.content_widget.indexOf(l) self.assertNotEqual(i, -1, msg='Missing the list in the widget!') self.assertTrue(self.content_widget.isItemEnabled(i), msg='%s is not enabled!' % name) self.assertEqual(l.count(), d[name], msg='Wrong number of arrays in %s' % name) if name == 'plot2d': self.assertEqual(asstring(l.item(0).text()), sp[0].psy._short_info(), msg='Wrong text in plot2d') else: self.assertEqual( asstring(l.item(d[name] - 1).text()), sp2[0]._short_info(), msg='Wrong text in %s' % name) self.assertEqual(self._selected_rows('plot2d'), [], msg='Array in %s is wrongly selected!' % name) self.assertEqual(self._selected_rows('lineplot'), [0], msg='Array in %s is not selected!' % name) self.assertEqual(self._selected_rows('simple'), [1], msg='Wrong selection!') self.assertEqual(self._selected_rows('All'), [1], msg='Wrong selection!') # close the project full = sp + sp2 full.close(True, True, True) self.assertEqual(w.count(), 1) self.assertEqual(w.indexOf(lists['All']), 0) self.assertFalse(w.isItemEnabled(0), msg='List "All" is enabled!')
def browse(self, url): """Reimplemented to add file paths to the url string""" url = asstring(url) html_file = osp.join(self.sphinx_dir, '_build', 'html', url + '.html') if osp.exists(html_file): url = file2html(html_file) super(UrlHelp, self).browse(url)
def test_browsing(self): """Test browsing""" rcParams['help_explorer.online'] = True self.viewer.browse('www.google.de') url = asstring(self.viewer.html.url().toString()) self.assertTrue(url.startswith('https://www.google.de'), msg='Wrong url ' + url)
def check_figs(msg=None): figs = iter(sp.figs) for item in map(self.tree.topLevelItem, range(self.tree.topLevelItemCount())): self.assertEqual(asstring(item.text(0)), next(figs).canvas.get_window_title(), msg=msg)
def _test_ds_representation(self, ds): toplevel = self._get_toplevel_item(ds) coords = set(ds.coords) variables = set(ds.variables) - coords for child in map(toplevel.variables.child, range(toplevel.variables.childCount())): variables.remove(asstring(child.text(0))) self.assertEqual(len(variables), 0, msg='Variables not found: %s' % (variables)) for child in map(toplevel.coords.child, range(toplevel.coords.childCount())): coords.remove(asstring(child.text(0))) self.assertEqual(len(coords), 0, msg='Coordinates not found: %s' % (coords))
def test_minus(self): """Test the minus button""" self.test_plusplus() vtab = self.pc.variables_table atab = self.pc.array_table nvar = atab.rowCount() rows = [nvar - 2, nvar - 1] for row in rows: atab.item(row, 0).setSelected(True) QTest.mouseClick(self.pc.bt_remove, Qt.LeftButton) variables = [asstring(vtab.item(row, 0).text()) for row in range(vtab.rowCount()) if row not in rows] self.assertEqual( [asstring(atab.item(irow, 0).text()) for irow in range( atab.rowCount())], variables)
def test_loading(self): """Test whether the rcParams are loaded correctly""" # create the preferences window w = prefs.GuiRcParamsWidget() w.initialize() items = list(w.tree.top_level_items) self.assertEqual(len(items), len(gui_rcParams)) # test keys keys = set(gui_rcParams) for item in items: keys.remove(asstring(item.text(0))) self.assertFalse(keys) # test values for item in items: key = asstring(item.text(0)) s_val = asstring(w.tree.itemWidget(item.child(0), 2).toPlainText()) val = yaml.load(s_val, Loader=yaml.Loader) self.assertEqual(val, gui_rcParams[key], msg='Failed item %s: %s' % (key, s_val))
def set_viewer(self, name): """Sets the current documentation viewer Parameters ---------- name: str or object A string must be one of the :attr:`viewers` attribute. An object can be one of the values in the :attr:`viewers` attribute""" if isstring(name) and asstring(name) not in self.viewers: raise ValueError("Don't have a viewer named %s" % (name, )) elif not isstring(name): viewer = name else: name = asstring(name) viewer = self.viewers[name] self.viewer.hide() self.viewer = viewer self.viewer.show() if (isstring(name) and not self.combo.currentText() == name): self.combo.setCurrentIndex(list(self.viewers).index(name))
def test_loading(self): """Test whether the rcParams are loaded correctly""" # create the preferences window w = prefs.GuiRcParamsWidget() w.initialize() items = list(w.tree.top_level_items) self.assertEqual(len(items), len(gui_rcParams)) # test keys keys = set(gui_rcParams) for item in items: keys.remove(asstring(item.text(0))) self.assertFalse(keys) # test values for item in items: key = asstring(item.text(0)) s_val = asstring(w.tree.itemWidget(item.child(0), 2).toPlainText()) val = yaml.load(s_val) self.assertEqual(val, gui_rcParams[key], msg='Failed item %s: %s' % (key, s_val))
def url_changed(self, url): """Reimplemented to remove file paths from the url string""" try: url = asstring(url.toString()) except AttributeError: pass if url.startswith('file://'): fname = html2file(url) if osp.samefile(self.build_dir, osp.commonprefix([ fname, self.build_dir])): url = osp.splitext(osp.basename(fname))[0] super(UrlHelp, self).url_changed(url)
def test_load_external_file(self): """Test whether an external netCDF file can be loaded""" fname = self.get_file('test-t2m-u-v.nc') self.pc.open_dataset([fname]) vtab = self.pc.variables_table ds = psy.open_dataset(fname) self.assertIn(fname, self.pc.ds_combo.currentText()) self.assertEqual( {asstring(vtab.item(irow, 0).text()) for irow in range( vtab.rowCount())}, set(ds.variables) - set(ds.coords)) ds.close()
def url_changed(self, url): """Reimplemented to remove file paths from the url string""" try: url = asstring(url.toString()) except AttributeError: pass if url.startswith('file://'): fname = html2file(url) if osp.samefile(self.build_dir, osp.commonprefix([fname, self.build_dir])): url = osp.splitext(osp.basename(fname))[0] super(UrlHelp, self).url_changed(url)
def get_current_object(self, to_end=False): """Get the name of the object at cursor position""" c = self._control if not _with_prompt: try: # qtconsole >4.3 uses the _prompt_cursor attribute cursor = self._prompt_cursor except AttributeError: cursor = c.textCursor() else: cursor = c.textCursor() curr = cursor.position() start = curr - cursor.positionInBlock() txt = c.toPlainText()[start:curr] eol = '' if to_end: cursor.movePosition(QTextCursor.EndOfBlock) end = cursor.position() if end > curr: eol = c.toPlainText()[curr:end] m = symbols_patt.search(eol) if m: eol = eol[:m.start()] if not txt: return txt txt = asstring(txt) txt = txt.rsplit('\n', 1)[-1] txt_end = "" for startchar, endchar in ["[]", "()"]: if txt.endswith(endchar): pos = txt.rfind(startchar) if pos: txt_end = txt[pos:] txt = txt[:pos] tokens = symbols_patt.split(txt) token = None try: while token is None or symbols_patt.match(token): token = tokens.pop() if token.endswith('.'): token = token[:-1] if token.startswith('.'): # Invalid object name return None token += txt_end if token: return token + eol except IndexError: return None
def test_toplevel(self): """Test whether the toplevel items are shown correctly""" fname = self.get_file('test-t2m-u-v.nc') sp1 = psy.plot.plot2d(fname, name='t2m') sp2 = psy.plot.plot2d(fname, name='t2m') count = next(psyd._ds_counter) - 1 fname = osp.basename(fname) ds1 = sp1[0].psy.base ds2 = sp2[0].psy.base self.assertEqual(self.tree.topLevelItemCount(), 2) self.assertEqual(asstring(self._get_toplevel_item(ds1).text(0)), '%i: %s' % (count - 1, fname)) self.assertEqual(asstring(self._get_toplevel_item(ds2).text(0)), '*%i: %s' % (count, fname)) psy.scp(sp1) self.assertEqual(asstring(self._get_toplevel_item(ds1).text(0)), '*%i: %s' % (count - 1, fname)) self.assertEqual(asstring(self._get_toplevel_item(ds2).text(0)), '%i: %s' % (count, fname)) sp2.close(True, True) self.assertEqual(asstring(self._get_toplevel_item(ds1).text(0)), '*%i: %s' % (count - 1, fname)) self.assertEqual(self.tree.topLevelItemCount(), 1)
def test_load_from_console(self): """Test whether a dataset can be loaded that is defined in the console""" fname = self.get_file('test-t2m-u-v.nc') if sys.platform == 'win32': fname = fname.replace('\\', '\\\\') self.window.console.execute( "ds = psy.open_dataset('%s')" % fname) vtab = self.pc.variables_table ds = psy.open_dataset(self.get_file('test-t2m-u-v.nc')) self.pc.bt_get_ds.get_from_shell('ds') self.assertIn('ds', self.pc.ds_combo.currentText()) self.assertEqual( {asstring(vtab.item(irow, 0).text()) for irow in range( vtab.rowCount())}, set(ds.variables) - set(ds.coords)) ds.close() self.window.console.execute("ds.close()")
def func(): editor = self.itemWidget(item.child(0), self.value_col) s = asstring(editor.toPlainText()) try: val = yaml.load(s, Loader=yaml.Loader) except Exception as e: item.setIcon(1, QIcon(get_icon('warning.png'))) item.setToolTip(1, "Could not parse yaml code: %s" % e) self.set_valid(i, False) return try: validator(val) except Exception as e: item.setIcon(1, QIcon(get_icon('invalid.png'))) item.setToolTip(1, "Wrong value: %s" % e) self.set_valid(i, False) else: item.setIcon(1, QIcon(get_icon('valid.png'))) self.set_valid(i, True) self.propose_changes.emit(self.parent() or self)
def func(): editor = self.itemWidget(item.child(0), self.value_col) s = asstring(editor.toPlainText()) try: val = yaml.load(s) except Exception as e: item.setIcon(1, QIcon(get_icon('warning.png'))) item.setToolTip(1, "Could not parse yaml code: %s" % e) self.set_valid(i, False) return try: validator(val) except Exception as e: item.setIcon(1, QIcon(get_icon('invalid.png'))) item.setToolTip(1, "Wrong value: %s" % e) self.set_valid(i, False) else: item.setIcon(1, QIcon(get_icon('valid.png'))) self.set_valid(i, True) self.propose_changes.emit(self.parent() or self)
def show_help(self, obj, oname='', files=None): """ Show the documentaion of the given object We first try to use the current viewer based upon it's :attr:`HelpMixin.can_document_object` attribute. If this does not work, we check the other viewers Parameters ---------- %(HelpMixin.show_help.parameters)s""" oname = asstring(oname) ret = None if self.viewer.can_document_object: try: ret = self.viewer.show_help(obj, oname=oname, files=files) except Exception: logger.debug("Could not document %s with %s viewer!", oname, self.combo.currentText(), exc_info=True) else: curr_i = self.combo.currentIndex() for i, (viewername, viewer) in enumerate(six.iteritems(self.viewers)): if i != curr_i and viewer.can_document_object: self.set_viewer(viewername) self.combo.blockSignals(True) self.combo.setCurrentIndex(i) self.combo.blockSignals(False) try: ret = viewer.show_help(obj, oname=oname, files=files) except Exception: logger.debug("Could not document %s with %s viewer!", oname, viewername, exc_info=True) if ret: self.parent().raise_() return ret
def test_save_02_some(self): """Test saving some parts the rcParams""" w = prefs.GuiRcParamsWidget() w.initialize() keys = [] for item in islice(w.tree.top_level_items, 0, None, 2): item.setSelected(True) keys.append(asstring(item.text(0))) self.assertEqual(len(w.tree.selectedItems()), len(keys)) fname = tempfile.NamedTemporaryFile( prefix='psyplot_gui_test', suffix='.yml').name self._created_files.add(fname) action = w.save_settings_action(target=fname) action.trigger() self.assertTrue(osp.exists(fname)) rc = GuiRcParams(defaultParams=gui_rcParams.defaultParams) rc.load_from_file(fname) self.assertEqual(dict(rc), {key: gui_rcParams[key] for key in keys})
def show_help(self, obj, oname='', files=None): """ Show the documentaion of the given object We first try to use the current viewer based upon it's :attr:`HelpMixin.can_document_object` attribute. If this does not work, we check the other viewers Parameters ---------- %(HelpMixin.show_help.parameters)s""" oname = asstring(oname) ret = None if self.viewer.can_document_object: try: ret = self.viewer.show_help(obj, oname=oname, files=files) except Exception: logger.debug("Could not document %s with %s viewer!", oname, self.combo.currentText(), exc_info=True) else: curr_i = self.combo.currentIndex() for i, (viewername, viewer) in enumerate( six.iteritems(self.viewers)): if i != curr_i and viewer.can_document_object: self.set_viewer(viewername) self.combo.blockSignals(True) self.combo.setCurrentIndex(i) self.combo.blockSignals(False) try: ret = viewer.show_help(obj, oname=oname, files=files) except Exception: logger.debug("Could not document %s with %s viewer!", oname, viewername, exc_info=True) if ret: self.parent().raise_() return ret
def test_validation(self): """Test whether the validation works correctly""" self.window.showMaximized() w = prefs.GuiRcParamsWidget() w.initialize() # choose an item for i, item in enumerate(w.tree.top_level_items): if asstring(item.text(0)) == 'console.auto_set_mp': break self.assertTrue(w.is_valid, msg=w.tree.valid) # set an invalid value w.tree.itemWidget(item.child(0), 2).setPlainText('tg') self.assertFalse(w.tree.valid[i]) self.assertFalse(w.is_valid) w.tree.itemWidget(item.child(0), 2).setPlainText('t') self.assertTrue(w.tree.valid[i]) self.assertTrue(w.is_valid) # set a value that cannot be loaded by yaml w.tree.itemWidget(item.child(0), 2).setPlainText('"t') self.assertFalse(w.tree.valid[i]) self.assertFalse(w.is_valid)
def html2file(url): p = urlparse(asstring(url)) # skip the first '/' on windows platform return osp.abspath(osp.join(p.netloc, p.path[int(sys.platform == 'win32'):]))
def html2file(url): p = urlparse(asstring(url)) # skip the first '/' on windows platform return osp.abspath( osp.join(p.netloc, p.path[int(sys.platform == 'win32'):]))