Skip to content

Commit

Permalink
Test reporting: auto-discover widgets to test
Browse files Browse the repository at this point in the history
  • Loading branch information
kernc committed Jul 29, 2016
1 parent e3fd568 commit a21a587
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 63 deletions.
100 changes: 40 additions & 60 deletions Orange/canvas/report/tests/test_report.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
from importlib import import_module
import os
import warnings

from PyQt4.QtGui import QFont, QBrush
from PyQt4.QtCore import Qt
from Orange.data.table import Table
Expand All @@ -8,43 +12,15 @@
from Orange.distance import Euclidean
from Orange.canvas.report.owreport import OWReport
from Orange.widgets import gui
from Orange.widgets.widget import OWWidget
from Orange.widgets.tests.base import WidgetTest
from Orange.widgets.classify.owclassificationtree import OWClassificationTree
from Orange.widgets.classify.owclassificationtreegraph import OWClassificationTreeGraph
from Orange.widgets.classify.owknn import OWKNNLearner
from Orange.widgets.classify.owlogisticregression import OWLogisticRegression
from Orange.widgets.classify.owmajority import OWMajority
from Orange.widgets.classify.ownaivebayes import OWNaiveBayes
from Orange.widgets.classify.owrandomforest import OWRandomForest
from Orange.widgets.classify.owsvmclassification import OWSVMClassification
from Orange.widgets.data.owconcatenate import OWConcatenate
from Orange.widgets.data.owcontinuize import OWContinuize
from Orange.widgets.data.owdatainfo import OWDataInfo
from Orange.widgets.data.owdatasampler import OWDataSampler
from Orange.widgets.data.owdiscretize import OWDiscretize
from Orange.widgets.data.owfeatureconstructor import OWFeatureConstructor
from Orange.widgets.data.owfile import OWFile
from Orange.widgets.data.owimpute import OWImpute
from Orange.widgets.data.owmergedata import OWMergeData
from Orange.widgets.data.owoutliers import OWOutliers
from Orange.widgets.data.owpaintdata import OWPaintData
from Orange.widgets.data.owpurgedomain import OWPurgeDomain
from Orange.widgets.data.owrank import OWRank
from Orange.widgets.data.owselectcolumns import OWSelectAttributes
from Orange.widgets.data.owselectrows import OWSelectRows
from Orange.widgets.data.owsql import OWSql
from Orange.widgets.data.owtable import OWDataTable
from Orange.widgets.data.owcolor import OWColor
from Orange.widgets.data.owpreprocess import OWPreprocess
from Orange.widgets.evaluate.owcalibrationplot import OWCalibrationPlot
from Orange.widgets.evaluate.owliftcurve import OWLiftCurve
from Orange.widgets.evaluate.owrocanalysis import OWROCAnalysis
from Orange.widgets.evaluate.owtestlearners import OWTestLearners
from Orange.widgets.regression.owregressiontree import OWRegressionTree
from Orange.widgets.regression.owregressiontreegraph import OWRegressionTreeGraph
from Orange.widgets.regression.owknnregression import OWKNNRegression
from Orange.widgets.regression.owmean import OWMean
from Orange.widgets.regression.owsvmregression import OWSVMRegression
from Orange.widgets.unsupervised.owcorrespondence import OWCorrespondenceAnalysis
from Orange.widgets.unsupervised.owdistancemap import OWDistanceMap
from Orange.widgets.unsupervised.owdistances import OWDistances
Expand All @@ -53,15 +29,35 @@
from Orange.widgets.unsupervised.owmds import OWMDS
from Orange.widgets.unsupervised.owpca import OWPCA
from Orange.widgets.utils.itemmodels import PyTableModel
from Orange.widgets.visualize.owboxplot import OWBoxPlot
from Orange.widgets.visualize.owdistributions import OWDistributions
from Orange.widgets.visualize.owheatmap import OWHeatMap
from Orange.widgets.visualize.owlinearprojection import OWLinearProjection
from Orange.widgets.visualize.owmosaic import OWMosaicDisplay
from Orange.widgets.visualize.owscattermap import OWScatterMap
from Orange.widgets.visualize.owscatterplot import OWScatterPlot
from Orange.widgets.visualize.owsieve import OWSieveDiagram
from Orange.widgets.visualize.owvenndiagram import OWVennDiagram


def get_owwidgets(top_module_name):
top_module = import_module(top_module_name)
widgets = []
for root, dirs, files in os.walk(top_module.__path__[0]):
root = root[len(top_module.__path__[0]):].lstrip(os.path.sep)
for file in files:
if file.lower().startswith('ow') and file.lower().endswith('.py'):
module_name = top_module_name + '.' + os.path.join(root, file).replace(os.path.sep, '.')[:-len('.py')]
try:
module = import_module(module_name, top_module_name[:top_module_name.index('.')])
except ImportError:
warnings.warn('Failed to import module: ' + module_name)
continue
for name, value in module.__dict__.items():
if (name.upper().startswith('OW') and
isinstance(value, type) and
issubclass(value, OWWidget) and
getattr(value, 'name', None) and
getattr(value, 'send_report', None)):
widgets.append(value)
return list(set(widgets))


DATA_WIDGETS = get_owwidgets('Orange.widgets.data')
VISUALIZATION_WIDGETS = get_owwidgets('Orange.widgets.visualize')
CLASSIFICATION_WIDGETS = get_owwidgets('Orange.widgets.classify')
REGRESSION_WIDGETS = get_owwidgets('Orange.widgets.regression')


class TestReport(WidgetTest):
Expand Down Expand Up @@ -119,32 +115,24 @@ def test_report_table(self):


class TestReportWidgets(WidgetTest):
clas_widgets = [OWClassificationTree, OWKNNLearner, OWLogisticRegression,
OWMajority, OWNaiveBayes, OWRandomForest,
OWSVMClassification]
data_widgets = [OWConcatenate, OWContinuize, OWDataInfo, OWDataSampler,
OWDiscretize, OWFeatureConstructor, OWOutliers, OWImpute,
OWMergeData, OWFile, OWPaintData, OWPurgeDomain, OWRank,
OWSelectAttributes, OWSelectRows, OWSql, OWDataTable,
OWColor, OWPreprocess]
clas_widgets = CLASSIFICATION_WIDGETS
data_widgets = DATA_WIDGETS
eval_widgets = [OWCalibrationPlot, OWLiftCurve, OWROCAnalysis]
regr_widgets = [OWRegressionTree, OWKNNRegression, OWMean, OWSVMRegression]
regr_widgets = REGRESSION_WIDGETS
unsu_widgets = [OWCorrespondenceAnalysis, OWDistances, OWKMeans,
OWMDS, OWPCA]
dist_widgets = [OWDistanceMap, OWHierarchicalClustering]
visu_widgets = [OWBoxPlot, OWDistributions, OWHeatMap, OWLinearProjection,
OWMosaicDisplay, OWScatterPlot,
OWSieveDiagram, OWScatterMap, OWVennDiagram]
visu_widgets = VISUALIZATION_WIDGETS
spec_widgets = [OWClassificationTreeGraph, OWTestLearners,
OWRegressionTreeGraph]

def _create_report(self, widgets, rep, data):
for widget in widgets:
w = self.create_widget(widget)
if w.inputs and data is not None:
if w.inputs and isinstance(data, w.inputs[0].type):
handler = getattr(w, w.inputs[0].handler)
handler(data)
w.create_report_html()
w.create_report_html()
rep.make_report(w)
# rep.show()

Expand All @@ -160,14 +148,12 @@ def test_report_widgets_classify(self):
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 8)
self._create_report(widgets, rep, data)

def test_report_widgets_data(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.data_widgets
self.assertEqual(len(widgets), 19)
self._create_report(widgets, rep, data)

def test_report_widgets_evaluate(self):
Expand All @@ -189,7 +175,6 @@ def test_report_widgets_evaluate(self):
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 4)
self._create_report(widgets, rep, results)

def test_report_widgets_regression(self):
Expand All @@ -204,35 +189,30 @@ def test_report_widgets_regression(self):
w.create_report_html()
rep.make_report(w)

self.assertEqual(len(widgets) + 1, 5)
self._create_report(widgets, rep, data)

def test_report_widgets_unsupervised(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.unsu_widgets
self.assertEqual(len(widgets), 5)
self._create_report(widgets, rep, data)

def test_report_widgets_unsupervised_dist(self):
rep = OWReport.get_instance()
data = Table("zoo")
dist = Euclidean(data)
widgets = self.dist_widgets
self.assertEqual(len(widgets), 2)
self._create_report(widgets, rep, dist)

def test_report_widgets_visualize(self):
rep = OWReport.get_instance()
data = Table("zoo")
widgets = self.visu_widgets
self.assertEqual(len(widgets), 9)
self._create_report(widgets, rep, data)

def test_report_widgets_all(self):
rep = OWReport.get_instance()
widgets = self.clas_widgets + self.data_widgets + self.eval_widgets + \
self.regr_widgets + self.unsu_widgets + self.dist_widgets + \
self.visu_widgets + self.spec_widgets
self.assertEqual(len(widgets), 52)
self._create_report(widgets, rep, None)
9 changes: 6 additions & 3 deletions Orange/widgets/data/oweditdomain.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,9 +543,12 @@ def sizeHint(self):
return sh.expandedTo(QSize(660, 550))

def send_report(self):
self.report_raw("", EditDomainReport(
old_domain=chain(self.data.domain.variables, self.data.domain.metas),
new_domain=self.domain_model).to_html())
if self.data is not None:
self.report_raw("", EditDomainReport(
old_domain=chain(self.data.domain.variables, self.data.domain.metas),
new_domain=self.domain_model).to_html())
else:
self.report_data(None)


class EditDomainReport:
Expand Down
3 changes: 3 additions & 0 deletions Orange/widgets/visualize/owsilhouetteplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ def commit(self):
self.send("Other Data", other)

def send_report(self):
if not len(self.cluster_var_model):
return

self.report_plot()
caption = "Silhouette plot ({} distance), clustered by '{}'".format(
self.Distances[self.distance_idx][0],
Expand Down

0 comments on commit a21a587

Please sign in to comment.