Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions gui/mozregui/ui/nightlies.ui
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,13 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateEdit" name="start_date">
<property name="displayFormat">
<string>yyyy-MM-dd</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>First known bad date</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateEdit" name="end_date">
<property name="displayFormat">
<string>yyyy-MM-dd</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="toolTip">
Expand All @@ -67,10 +53,24 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="NightlyInputSelection" name="start_date" native="true"/>
</item>
<item row="1" column="1">
<widget class="NightlyInputSelection" name="end_date" native="true"/>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>NightlyInputSelection</class>
<extends>QWidget</extends>
<header>mozregui.utils</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
49 changes: 48 additions & 1 deletion gui/mozregui/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
from PyQt4.QtCore import QDir
from PyQt4.QtGui import QLineEdit, QPushButton, QWidget, QHBoxLayout, \
QFileDialog, QFileSystemModel, QCompleter
QFileDialog, QFileSystemModel, QCompleter, QComboBox, QDateEdit, \
QStackedWidget

from mozregression.releases import date_of_release, releases
from mozregression.dates import parse_date
from mozregression.errors import DateFormatError


class FSLineEdit(QLineEdit):
Expand Down Expand Up @@ -44,3 +49,45 @@ def browse_dialog(self):
)
if path:
self.line_edit.setPath(path)


class NightlyInputSelection(QWidget):
"""
Allow to select a date, a build id or a release number.
"""
def __init__(self, parent=None):
QWidget.__init__(self, parent)
layout = QHBoxLayout(self)
self._create_widgets()
layout.addWidget(self.stacked)
layout.addWidget(self.select_combo)
self.setLayout(layout)

def _create_widgets(self):
self.stacked = QStackedWidget()
self.datew = QDateEdit()
self.datew.setDisplayFormat("yyyy-MM-dd")
self.stacked.addWidget(self.datew)
self.buildidw = QLineEdit()
self.stacked.addWidget(self.buildidw)
self.releasew = QComboBox()
self.releasew.addItems([str(k) for k in sorted(releases())])
self.stacked.addWidget(self.releasew)

self.select_combo = QComboBox()
self.select_combo.addItems(['date', 'buildid', 'release'])
self.select_combo.activated.connect(self.stacked.setCurrentIndex)

def get_date(self):
currentw = self.stacked.currentWidget()
if currentw == self.datew:
return self.datew.date().toPyDate()
elif currentw == self.buildidw:
buildid = unicode(self.buildidw.text())
try:
return parse_date(buildid)
except DateFormatError:
raise DateFormatError(buildid, "Not a valid build id: `%s`")
elif currentw == self.releasew:
return parse_date(
date_of_release(str(self.releasew.currentText())))
49 changes: 25 additions & 24 deletions gui/mozregui/wizard.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import mozinfo
import datetime
from PyQt4.QtGui import QWizard, QWizardPage, QStringListModel, QMessageBox
from PyQt4.QtCore import QString, QDate, QDateTime
from PyQt4.QtCore import QString, QDateTime

from ui.intro import Ui_Intro
from ui.nightlies import Ui_Nightlies
Expand All @@ -9,17 +10,8 @@

from mozregression.fetch_configs import create_config, REGISTRY
from mozregression.launchers import REGISTRY as LAUNCHER_REGISTRY
from mozregression.errors import LauncherNotRunnable


def get_all_subclasses(cls):
all_subclasses = []

for subclass in cls.__subclasses__():
all_subclasses.append(subclass)
all_subclasses.extend(get_all_subclasses(subclass))

return all_subclasses
from mozregression.errors import LauncherNotRunnable, DateFormatError
from mozregression.dates import to_datetime


def resolve_obj_name(obj, name):
Expand Down Expand Up @@ -144,20 +136,29 @@ class NightliesPage(WizardSelectionRangePage):
UI_CLASS = Ui_Nightlies
TITLE = "Date range selection"
SUBTITLE = ("Select the nightlies date range.")
FIELDS = {"start_date": "start_date", "end_date": "end_date",
"repository": "repository"}
FIELDS = {"repository": "repository"}
ID = 1

def __init__(self):
WizardPage.__init__(self)
now = QDateTime.currentDateTime()
self.ui.start_date.setDateTime(now.addYears(-1))
self.ui.end_date.setDateTime(now)
self.ui.start_date.datew.setDateTime(now.addYears(-1))
self.ui.end_date.datew.setDateTime(now)

def get_start_date(self):
return self.ui.start_date.get_date()

def get_end_date(self):
return self.ui.end_date.get_date()

def validatePage(self):
start_date = self.ui.start_date.date()
end_date = self.ui.end_date.date()
current = QDateTime.currentDateTime().date()
try:
start_date = to_datetime(self.get_start_date())
end_date = to_datetime(self.get_end_date())
except DateFormatError as exc:
QMessageBox.critical(self, "Error", unicode(exc))
return False
current = datetime.datetime.now()
if start_date < end_date:
if end_date <= current:
return True
Expand Down Expand Up @@ -231,8 +232,6 @@ def __init__(self, parent=None):
# associate current text to comboboxes fields instead of current index
self.setDefaultProperty("QComboBox", "currentText",
"currentIndexChanged")
# store QDate instead of QDateTime
self.setDefaultProperty("QDateEdit", "date", "dateChanged")

self.addPage(IntroPage())
self.addPage(NightliesPage())
Expand All @@ -241,17 +240,19 @@ def __init__(self, parent=None):

def options(self):
options = {}
for wizard_class in get_all_subclasses(WizardPage):
for page_id in self.pageIds():
wizard_class = self.page(page_id).__class__
for fieldname in wizard_class.FIELDS:
value = self.field(fieldname).toPyObject()
if isinstance(value, QString):
value = unicode(value)
elif isinstance(value, QDate):
value = value.toPyDate()
options[fieldname] = value
fetch_config = self.page(IntroPage.ID).fetch_config
if options['bisect_type'] == 'nightlies':
kind = "date"
nightlies_page = self.page(NightliesPage.ID)
options['start_date'] = nightlies_page.get_start_date()
options['end_date'] = nightlies_page.get_end_date()
fetch_config.set_nightly_repo(options['repository'])
else:
kind = "changeset"
Expand Down
49 changes: 49 additions & 0 deletions gui/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import pytest
import datetime

from mozregui.utils import NightlyInputSelection
from mozregression.errors import DateFormatError


@pytest.fixture
def pref_editor(qtbot):
widget = NightlyInputSelection()
qtbot.addWidget(widget)
widget.show()
qtbot.waitForWindowShown(widget)
return widget


def test_date_widget_is_visible_by_default(pref_editor):
assert pref_editor.select_combo.currentText() == 'date'
assert pref_editor.datew.isVisible()
assert not pref_editor.buildidw.isVisible()
assert not pref_editor.releasew.isVisible()


def test_switch_to_release_widget(pref_editor, qtbot):
qtbot.keyClicks(pref_editor.select_combo, "release")
assert pref_editor.select_combo.currentText() == 'release'
assert not pref_editor.datew.isVisible()
assert not pref_editor.buildidw.isVisible()
assert pref_editor.releasew.isVisible()


@pytest.mark.parametrize("widname,value,expected", [
("date", "20000101", datetime.date(2000, 1, 1)),
("buildid", "20150102101112",
datetime.datetime(2015, 1, 2, 10, 11, 12)),
("release", "40", datetime.date(2015, 5, 11)),
])
def test_get_date(pref_editor, qtbot, widname, value, expected):
qtbot.keyClicks(pref_editor.select_combo, widname)
qtbot.keyClicks(pref_editor.stacked.currentWidget(), value)
assert pref_editor.get_date() == expected


def test_get_invalid_buildid(pref_editor, qtbot):
qtbot.keyClicks(pref_editor.select_combo, "buildid")
qtbot.keyClicks(pref_editor.stacked.currentWidget(), "12345")
with pytest.raises(DateFormatError) as ctx:
pref_editor.get_date()
assert 'build id' in str(ctx.value)
2 changes: 1 addition & 1 deletion mozregression/dates.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def parse_date(date_string):
try:
return datetime.datetime.strptime(date_string, "%Y%m%d%H%M%S")
except ValueError:
raise DateFormatError(date_string)
raise DateFormatError(date_string, "Not a valid build id: `%s`")
regex = re.compile(r'(\d{4})\-(\d{1,2})\-(\d{1,2})')
matched = regex.match(date_string)
if not matched:
Expand Down
6 changes: 2 additions & 4 deletions mozregression/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ class DateFormatError(MozRegressionError):
"""
Raised when a date can not be parsed from a string.
"""
def __init__(self, date_string):
MozRegressionError.__init__(self,
"Incorrect date format: `%s`"
% date_string)
def __init__(self, date_string, format="Incorrect date format: `%s`"):
MozRegressionError.__init__(self, format % date_string)


class DownloadError(MozRegressionError):
Expand Down