Hello community,

here is the log from the commit of package python-schedule for openSUSE:Factory 
checked in at 2019-03-26 22:34:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-schedule (Old)
 and      /work/SRC/openSUSE:Factory/.python-schedule.new.25356 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-schedule"

Tue Mar 26 22:34:51 2019 rev:3 rq:688868 version:0.6.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-schedule/python-schedule.changes  
2018-12-24 11:46:19.341190178 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-schedule.new.25356/python-schedule.changes   
    2019-03-26 22:35:22.957655538 +0100
@@ -1,0 +2,7 @@
+Tue Mar 26 16:40:26 UTC 2019 - pgaj...@suse.com
+
+- version update to 0.6.0
+  * Make at() accept timestamps with 1 second precision (#267).
+  * Introduce proper exception hierarchy (#271).
+
+-------------------------------------------------------------------

Old:
----
  schedule-0.5.0.tar.gz

New:
----
  schedule-0.6.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-schedule.spec ++++++
--- /var/tmp/diff_new_pack.cNNgaC/_old  2019-03-26 22:35:24.817654736 +0100
+++ /var/tmp/diff_new_pack.cNNgaC/_new  2019-03-26 22:35:24.817654736 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-schedule
 #
-# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-schedule
-Version:        0.5.0
+Version:        0.6.0
 Release:        0
 Summary:        Job scheduling module for Python
 License:        MIT

++++++ schedule-0.5.0.tar.gz -> schedule-0.6.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/HISTORY.rst 
new/schedule-0.6.0/HISTORY.rst
--- old/schedule-0.5.0/HISTORY.rst      2017-11-16 15:58:47.000000000 +0100
+++ new/schedule-0.6.0/HISTORY.rst      2019-01-21 01:26:22.000000000 +0100
@@ -3,6 +3,14 @@
 History
 -------
 
+
+0.6.0 (2019-01-20)
+++++++++++++++++++
+
+- Make at() accept timestamps with 1 second precision (#267). Thanks 
@NathanWailes!
+- Introduce proper exception hierarchy (#271). Thanks @ConnorSkees!
+
+
 0.5.0 (2017-11-16)
 ++++++++++++++++++
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/PKG-INFO new/schedule-0.6.0/PKG-INFO
--- old/schedule-0.5.0/PKG-INFO 2017-11-16 16:03:22.000000000 +0100
+++ new/schedule-0.6.0/PKG-INFO 2019-01-21 02:01:43.000000000 +0100
@@ -1,13 +1,12 @@
 Metadata-Version: 1.1
 Name: schedule
-Version: 0.5.0
+Version: 0.6.0
 Summary: Job scheduling for humans.
 Home-page: https://github.com/dbader/schedule
 Author: Daniel Bader
 Author-email: m...@dbader.org
 License: MIT
-Download-URL: https://github.com/dbader/schedule/tarball/0.5.0
-Description-Content-Type: UNKNOWN
+Download-URL: https://github.com/dbader/schedule/tarball/0.6.0
 Description: schedule
         ========
         
@@ -55,9 +54,10 @@
             schedule.every(10).minutes.do(job)
             schedule.every().hour.do(job)
             schedule.every().day.at("10:30").do(job)
-            schedule.every(5).to(10).days.do(job)
+            schedule.every(5).to(10).minutes.do(job)
             schedule.every().monday.do(job)
             schedule.every().wednesday.at("13:15").do(job)
+            schedule.every().minute.at(":17").do(job)
         
             while True:
                 schedule.run_pending()
@@ -76,7 +76,7 @@
         
         Daniel Bader - `@dbader_org <https://twitter.com/dbader_org>`_ - 
m...@dbader.org
         
-        Distributed under the MIT license. See ``LICENSE.txt`` for more 
information.
+        Distributed under the MIT license. See `LICENSE.txt 
<https://github.com/dbader/schedule/blob/master/LICENSE.txt>`_ for more 
information.
         
         https://github.com/dbader/schedule
         
@@ -89,4 +89,5 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Natural Language :: English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/README.rst 
new/schedule-0.6.0/README.rst
--- old/schedule-0.5.0/README.rst       2017-11-16 16:00:14.000000000 +0100
+++ new/schedule-0.6.0/README.rst       2019-01-21 01:23:51.000000000 +0100
@@ -45,9 +45,10 @@
     schedule.every(10).minutes.do(job)
     schedule.every().hour.do(job)
     schedule.every().day.at("10:30").do(job)
-    schedule.every(5).to(10).days.do(job)
+    schedule.every(5).to(10).minutes.do(job)
     schedule.every().monday.do(job)
     schedule.every().wednesday.at("13:15").do(job)
+    schedule.every().minute.at(":17").do(job)
 
     while True:
         schedule.run_pending()
@@ -66,6 +67,6 @@
 
 Daniel Bader - `@dbader_org <https://twitter.com/dbader_org>`_ - 
m...@dbader.org
 
-Distributed under the MIT license. See ``LICENSE.txt`` for more information.
+Distributed under the MIT license. See `LICENSE.txt 
<https://github.com/dbader/schedule/blob/master/LICENSE.txt>`_ for more 
information.
 
 https://github.com/dbader/schedule
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/schedule/__init__.py 
new/schedule-0.6.0/schedule/__init__.py
--- old/schedule-0.5.0/schedule/__init__.py     2017-11-16 16:00:14.000000000 
+0100
+++ new/schedule-0.6.0/schedule/__init__.py     2019-01-21 01:57:47.000000000 
+0100
@@ -15,7 +15,7 @@
     - A simple to use API for scheduling jobs.
     - Very lightweight and no external dependencies.
     - Excellent test coverage.
-    - Works with Python 2.7 and 3.3
+    - Tested on Python 2.7, 3.5 and 3.6
 
 Usage:
     >>> import schedule
@@ -42,11 +42,27 @@
 import functools
 import logging
 import random
+import re
 import time
 
 logger = logging.getLogger('schedule')
 
 
+class ScheduleError(Exception):
+    """Base schedule exception"""
+    pass
+
+
+class ScheduleValueError(ScheduleError):
+    """Base schedule value error"""
+    pass
+
+
+class IntervalError(ScheduleValueError):
+    """An improper interval was used"""
+    pass
+
+
 class CancelJob(object):
     """
     Can be returned from a job to unschedule itself.
@@ -227,7 +243,8 @@
 
     @property
     def second(self):
-        assert self.interval == 1, 'Use seconds instead of second'
+        if self.interval != 1:
+            raise IntervalError('Use seconds instead of second')
         return self.seconds
 
     @property
@@ -237,7 +254,8 @@
 
     @property
     def minute(self):
-        assert self.interval == 1, 'Use minutes instead of minute'
+        if self.interval != 1:
+            raise IntervalError('Use minutes instead of minute')
         return self.minutes
 
     @property
@@ -247,7 +265,8 @@
 
     @property
     def hour(self):
-        assert self.interval == 1, 'Use hours instead of hour'
+        if self.interval != 1:
+            raise IntervalError('Use hours instead of hour')
         return self.hours
 
     @property
@@ -257,7 +276,8 @@
 
     @property
     def day(self):
-        assert self.interval == 1, 'Use days instead of day'
+        if self.interval != 1:
+            raise IntervalError('Use days instead of day')
         return self.days
 
     @property
@@ -267,7 +287,8 @@
 
     @property
     def week(self):
-        assert self.interval == 1, 'Use weeks instead of week'
+        if self.interval != 1:
+            raise IntervalError('Use weeks instead of week')
         return self.weeks
 
     @property
@@ -277,43 +298,50 @@
 
     @property
     def monday(self):
-        assert self.interval == 1, 'Use mondays instead of monday'
+        if self.interval != 1:
+            raise IntervalError('Use mondays instead of monday')
         self.start_day = 'monday'
         return self.weeks
 
     @property
     def tuesday(self):
-        assert self.interval == 1, 'Use tuesdays instead of tuesday'
+        if self.interval != 1:
+            raise IntervalError('Use tuesdays instead of tuesday')
         self.start_day = 'tuesday'
         return self.weeks
 
     @property
     def wednesday(self):
-        assert self.interval == 1, 'Use wedesdays instead of wednesday'
+        if self.interval != 1:
+            raise IntervalError('Use wednesdays instead of wednesday')
         self.start_day = 'wednesday'
         return self.weeks
 
     @property
     def thursday(self):
-        assert self.interval == 1, 'Use thursday instead of thursday'
+        if self.interval != 1:
+            raise IntervalError('Use thursdays instead of thursday')
         self.start_day = 'thursday'
         return self.weeks
 
     @property
     def friday(self):
-        assert self.interval == 1, 'Use fridays instead of friday'
+        if self.interval != 1:
+            raise IntervalError('Use fridays instead of friday')
         self.start_day = 'friday'
         return self.weeks
 
     @property
     def saturday(self):
-        assert self.interval == 1, 'Use saturdays instead of saturday'
+        if self.interval != 1:
+            raise IntervalError('Use saturdays instead of saturday')
         self.start_day = 'saturday'
         return self.weeks
 
     @property
     def sunday(self):
-        assert self.interval == 1, 'Use sundays instead of sunday'
+        if self.interval != 1:
+            raise IntervalError('Use sundays instead of sunday')
         self.start_day = 'sunday'
         return self.weeks
 
@@ -326,9 +354,6 @@
         :param tags: A unique list of ``Hashable`` tags.
         :return: The invoked job instance
         """
-        if any([not isinstance(tag, collections.Hashable) for tag in tags]):
-            raise TypeError('Every tag should be hashable')
-
         if not all(isinstance(tag, collections.Hashable) for tag in tags):
             raise TypeError('Tags must be hashable')
         self.tags.update(tags)
@@ -336,24 +361,54 @@
 
     def at(self, time_str):
         """
-        Schedule the job every day at a specific time.
-
-        Calling this is only valid for jobs scheduled to run
-        every N day(s).
+        Specify a particular time that the job should be run at.
 
-        :param time_str: A string in `XX:YY` format.
+        :param time_str: A string in one of the following formats: `HH:MM:SS`,
+            `HH:MM`,`:MM`, `:SS`. The format must make sense given how often
+            the job is repeating; for example, a job that repeats every minute
+            should not be given a string in the form `HH:MM:SS`. The difference
+            between `:MM` and `:SS` is inferred from the selected time-unit
+            (e.g. `every().hour.at(':30')` vs. `every().minute.at(':30')`).
         :return: The invoked job instance
         """
-        assert self.unit in ('days', 'hours') or self.start_day
-        hour, minute = time_str.split(':')
-        minute = int(minute)
+        if (self.unit not in ('days', 'hours', 'minutes')
+                and not self.start_day):
+            raise ScheduleValueError('Invalid unit')
+        if not isinstance(time_str, str):
+            raise TypeError('at() should be passed a string')
+        if self.unit == 'days' or self.start_day:
+            if not re.match(r'^([0-2]\d:)?[0-5]\d:[0-5]\d$', time_str):
+                raise ScheduleValueError('Invalid time format')
+        if self.unit == 'hours':
+            if not re.match(r'^([0-5]\d)?:[0-5]\d$', time_str):
+                raise ScheduleValueError(('Invalid time format for'
+                                          ' an hourly job'))
+        if self.unit == 'minutes':
+            if not re.match(r'^:[0-5]\d$', time_str):
+                raise ScheduleValueError(('Invalid time format for'
+                                          ' a minutely job'))
+        time_values = time_str.split(':')
+        if len(time_values) == 3:
+            hour, minute, second = time_values
+        elif len(time_values) == 2 and self.unit == 'minutes':
+            hour = 0
+            minute = 0
+            _, second = time_values
+        else:
+            hour, minute = time_values
+            second = 0
         if self.unit == 'days' or self.start_day:
             hour = int(hour)
-            assert 0 <= hour <= 23
+            if not (0 <= hour <= 23):
+                raise ScheduleValueError('Invalid number of hours')
         elif self.unit == 'hours':
             hour = 0
-        assert 0 <= minute <= 59
-        self.at_time = datetime.time(hour, minute)
+        elif self.unit == 'minutes':
+            hour = 0
+            minute = 0
+        minute = int(minute)
+        second = int(second)
+        self.at_time = datetime.time(hour, minute, second)
         return self
 
     def to(self, latest):
@@ -417,10 +472,12 @@
         """
         Compute the instant when this job should run next.
         """
-        assert self.unit in ('seconds', 'minutes', 'hours', 'days', 'weeks')
+        if self.unit not in ('seconds', 'minutes', 'hours', 'days', 'weeks'):
+            raise ScheduleValueError('Invalid unit')
 
         if self.latest is not None:
-            assert self.latest >= self.interval
+            if not (self.latest >= self.interval):
+                raise ScheduleError('`latest` is greater than `interval`')
             interval = random.randint(self.interval, self.latest)
         else:
             interval = self.interval
@@ -428,7 +485,8 @@
         self.period = datetime.timedelta(**{self.unit: interval})
         self.next_run = datetime.datetime.now() + self.period
         if self.start_day is not None:
-            assert self.unit == 'weeks'
+            if self.unit != 'weeks':
+                raise ScheduleValueError('`unit` should be \'weeks\'')
             weekdays = (
                 'monday',
                 'tuesday',
@@ -438,21 +496,26 @@
                 'saturday',
                 'sunday'
             )
-            assert self.start_day in weekdays
+            if self.start_day not in weekdays:
+                raise ScheduleValueError('Invalid start day')
             weekday = weekdays.index(self.start_day)
             days_ahead = weekday - self.next_run.weekday()
             if days_ahead <= 0:  # Target day already happened this week
                 days_ahead += 7
             self.next_run += datetime.timedelta(days_ahead) - self.period
         if self.at_time is not None:
-            assert self.unit in ('days', 'hours') or self.start_day is not None
+            if (self.unit not in ('days', 'hours', 'minutes')
+                    and self.start_day is None):
+                raise ScheduleValueError(('Invalid unit without'
+                                          ' specifying start day'))
             kwargs = {
-                'minute': self.at_time.minute,
                 'second': self.at_time.second,
                 'microsecond': 0
             }
             if self.unit == 'days' or self.start_day is not None:
                 kwargs['hour'] = self.at_time.hour
+            if self.unit in ['days', 'hours'] or self.start_day is not None:
+                kwargs['minute'] = self.at_time.minute
             self.next_run = self.next_run.replace(**kwargs)
             # If we are running for the first time, make sure we run
             # at the specified time *today* (or *this hour*) as well
@@ -461,8 +524,15 @@
                 if (self.unit == 'days' and self.at_time > now.time() and
                         self.interval == 1):
                     self.next_run = self.next_run - datetime.timedelta(days=1)
-                elif self.unit == 'hours' and self.at_time.minute > now.minute:
+                elif self.unit == 'hours' \
+                        and self.at_time.minute > now.minute \
+                        or (self.at_time.minute == now.minute
+                            and self.at_time.second > now.second):
                     self.next_run = self.next_run - datetime.timedelta(hours=1)
+                elif self.unit == 'minutes' \
+                        and self.at_time.second > now.second:
+                    self.next_run = self.next_run - \
+                                    datetime.timedelta(minutes=1)
         if self.start_day is not None and self.at_time is not None:
             # Let's see if we will still make that time we specified today
             if (self.next_run - datetime.datetime.now()).days >= 7:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/schedule.egg-info/PKG-INFO 
new/schedule-0.6.0/schedule.egg-info/PKG-INFO
--- old/schedule-0.5.0/schedule.egg-info/PKG-INFO       2017-11-16 
16:03:22.000000000 +0100
+++ new/schedule-0.6.0/schedule.egg-info/PKG-INFO       2019-01-21 
02:01:43.000000000 +0100
@@ -1,13 +1,12 @@
 Metadata-Version: 1.1
 Name: schedule
-Version: 0.5.0
+Version: 0.6.0
 Summary: Job scheduling for humans.
 Home-page: https://github.com/dbader/schedule
 Author: Daniel Bader
 Author-email: m...@dbader.org
 License: MIT
-Download-URL: https://github.com/dbader/schedule/tarball/0.5.0
-Description-Content-Type: UNKNOWN
+Download-URL: https://github.com/dbader/schedule/tarball/0.6.0
 Description: schedule
         ========
         
@@ -55,9 +54,10 @@
             schedule.every(10).minutes.do(job)
             schedule.every().hour.do(job)
             schedule.every().day.at("10:30").do(job)
-            schedule.every(5).to(10).days.do(job)
+            schedule.every(5).to(10).minutes.do(job)
             schedule.every().monday.do(job)
             schedule.every().wednesday.at("13:15").do(job)
+            schedule.every().minute.at(":17").do(job)
         
             while True:
                 schedule.run_pending()
@@ -76,7 +76,7 @@
         
         Daniel Bader - `@dbader_org <https://twitter.com/dbader_org>`_ - 
m...@dbader.org
         
-        Distributed under the MIT license. See ``LICENSE.txt`` for more 
information.
+        Distributed under the MIT license. See `LICENSE.txt 
<https://github.com/dbader/schedule/blob/master/LICENSE.txt>`_ for more 
information.
         
         https://github.com/dbader/schedule
         
@@ -89,4 +89,5 @@
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3.5
 Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
 Classifier: Natural Language :: English
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/setup.py new/schedule-0.6.0/setup.py
--- old/schedule-0.5.0/setup.py 2017-11-16 15:59:38.000000000 +0100
+++ new/schedule-0.6.0/setup.py 2019-01-21 01:24:51.000000000 +0100
@@ -14,11 +14,12 @@
 from setuptools import setup
 
 
-SCHEDULE_VERSION = '0.5.0'
+SCHEDULE_VERSION = '0.6.0'
 SCHEDULE_DOWNLOAD_URL = (
     'https://github.com/dbader/schedule/tarball/' + SCHEDULE_VERSION
 )
 
+
 def read_file(filename):
     """
     Read a utf8 encoded text file and return its contents.
@@ -26,6 +27,7 @@
     with codecs.open(filename, 'r', 'utf8') as f:
         return f.read()
 
+
 setup(
     name='schedule',
     packages=['schedule'],
@@ -49,6 +51,7 @@
         'Programming Language :: Python :: 2.7',
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
+        'Programming Language :: Python :: 3.7',
         'Natural Language :: English',
     ],
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/schedule-0.5.0/test_schedule.py 
new/schedule-0.6.0/test_schedule.py
--- old/schedule-0.5.0/test_schedule.py 2017-11-16 16:00:14.000000000 +0100
+++ new/schedule-0.6.0/test_schedule.py 2019-01-21 01:57:17.000000000 +0100
@@ -9,7 +9,7 @@
 # pylint: disable-msg=R0201,C0111,E0102,R0904,R0901
 
 import schedule
-from schedule import every
+from schedule import every, ScheduleError, ScheduleValueError, IntervalError
 
 
 def make_mock_job(name=None):
@@ -22,12 +22,13 @@
     """
     Monkey-patch datetime for predictable results
     """
-    def __init__(self, year, month, day, hour, minute):
+    def __init__(self, year, month, day, hour, minute, second=0):
         self.year = year
         self.month = month
         self.day = day
         self.hour = hour
         self.minute = minute
+        self.second = second
 
     def __enter__(self):
         class MockDate(datetime.datetime):
@@ -38,7 +39,7 @@
             @classmethod
             def now(cls):
                 return cls(self.year, self.month, self.day,
-                           self.hour, self.minute)
+                           self.hour, self.minute, self.second)
         self.original_datetime = datetime.datetime
         datetime.datetime = MockDate
 
@@ -57,6 +58,70 @@
         assert every().days.unit == 'days'
         assert every().weeks.unit == 'weeks'
 
+        job_instance = schedule.Job(interval=2)
+        # without a context manager, it incorrectly raises an error because
+        # it is not callable
+        with self.assertRaises(IntervalError):
+            job_instance.minute
+        with self.assertRaises(IntervalError):
+            job_instance.hour
+        with self.assertRaises(IntervalError):
+            job_instance.day
+        with self.assertRaises(IntervalError):
+            job_instance.week
+        with self.assertRaises(IntervalError):
+            job_instance.monday
+        with self.assertRaises(IntervalError):
+            job_instance.tuesday
+        with self.assertRaises(IntervalError):
+            job_instance.wednesday
+        with self.assertRaises(IntervalError):
+            job_instance.thursday
+        with self.assertRaises(IntervalError):
+            job_instance.friday
+        with self.assertRaises(IntervalError):
+            job_instance.saturday
+        with self.assertRaises(IntervalError):
+            job_instance.sunday
+
+        # test an invalid unit
+        job_instance.unit = "foo"
+        self.assertRaises(ScheduleValueError, job_instance.at, "1:0:0")
+        self.assertRaises(ScheduleValueError, job_instance._schedule_next_run)
+
+        # test start day exists but unit is not 'weeks'
+        job_instance.unit = "days"
+        job_instance.start_day = 1
+        self.assertRaises(ScheduleValueError, job_instance._schedule_next_run)
+
+        # test weeks with an invalid start day
+        job_instance.unit = "weeks"
+        job_instance.start_day = "bar"
+        self.assertRaises(ScheduleValueError, job_instance._schedule_next_run)
+
+        # test a valid unit with invalid hours/minutes/seconds
+        job_instance.unit = "days"
+        self.assertRaises(ScheduleValueError, job_instance.at, "25:00:00")
+        self.assertRaises(ScheduleValueError, job_instance.at, "00:61:00")
+        self.assertRaises(ScheduleValueError, job_instance.at, "00:00:61")
+
+        # test invalid time format
+        self.assertRaises(ScheduleValueError, job_instance.at, "25:0:0")
+        self.assertRaises(ScheduleValueError, job_instance.at, "0:61:0")
+        self.assertRaises(ScheduleValueError, job_instance.at, "0:0:61")
+
+        # test (very specific) seconds with unspecified start_day
+        job_instance.unit = "seconds"
+        job_instance.at_time = datetime.datetime.now()
+        job_instance.start_day = None
+        self.assertRaises(ScheduleValueError, job_instance._schedule_next_run)
+
+        # test self.latest >= self.interval
+        job_instance.latest = 1
+        self.assertRaises(ScheduleError, job_instance._schedule_next_run)
+        job_instance.latest = 3
+        self.assertRaises(ScheduleError, job_instance._schedule_next_run)
+
     def test_singular_time_units_match_plural_units(self):
         assert every().second.unit == every().seconds.unit
         assert every().minute.unit == every().minutes.unit
@@ -91,16 +156,84 @@
         mock_job = make_mock_job()
         assert every().day.at('10:30').do(mock_job).next_run.hour == 10
         assert every().day.at('10:30').do(mock_job).next_run.minute == 30
+        assert every().day.at('10:30:50').do(mock_job).next_run.second == 50
+
+        self.assertRaises(ScheduleValueError, every().day.at, '2:30:000001')
+        self.assertRaises(ScheduleValueError, every().day.at, '::2')
+        self.assertRaises(ScheduleValueError, every().day.at, '.2')
+        self.assertRaises(ScheduleValueError, every().day.at, '2')
+        self.assertRaises(ScheduleValueError, every().day.at, ':2')
+        self.assertRaises(ScheduleValueError, every().day.at, ' 2:30:00')
+        self.assertRaises(ScheduleValueError, every().do, lambda: 0)
+        self.assertRaises(TypeError, every().day.at, 2)
+
+        # without a context manager, it incorrectly raises an error because
+        # it is not callable
+        with self.assertRaises(IntervalError):
+            every(interval=2).second
+        with self.assertRaises(IntervalError):
+            every(interval=2).minute
+        with self.assertRaises(IntervalError):
+            every(interval=2).hour
+        with self.assertRaises(IntervalError):
+            every(interval=2).day
+        with self.assertRaises(IntervalError):
+            every(interval=2).week
+        with self.assertRaises(IntervalError):
+            every(interval=2).monday
+        with self.assertRaises(IntervalError):
+            every(interval=2).tuesday
+        with self.assertRaises(IntervalError):
+            every(interval=2).wednesday
+        with self.assertRaises(IntervalError):
+            every(interval=2).thursday
+        with self.assertRaises(IntervalError):
+            every(interval=2).friday
+        with self.assertRaises(IntervalError):
+            every(interval=2).saturday
+        with self.assertRaises(IntervalError):
+            every(interval=2).sunday
 
     def test_at_time_hour(self):
         with mock_datetime(2010, 1, 6, 12, 20):
             mock_job = make_mock_job()
             assert every().hour.at(':30').do(mock_job).next_run.hour == 12
             assert every().hour.at(':30').do(mock_job).next_run.minute == 30
+            assert every().hour.at(':30').do(mock_job).next_run.second == 0
             assert every().hour.at(':10').do(mock_job).next_run.hour == 13
             assert every().hour.at(':10').do(mock_job).next_run.minute == 10
+            assert every().hour.at(':10').do(mock_job).next_run.second == 0
             assert every().hour.at(':00').do(mock_job).next_run.hour == 13
             assert every().hour.at(':00').do(mock_job).next_run.minute == 0
+            assert every().hour.at(':00').do(mock_job).next_run.second == 0
+
+            self.assertRaises(ScheduleValueError, every().hour.at, '2:30:00')
+            self.assertRaises(ScheduleValueError, every().hour.at, '::2')
+            self.assertRaises(ScheduleValueError, every().hour.at, '.2')
+            self.assertRaises(ScheduleValueError, every().hour.at, '2')
+            self.assertRaises(ScheduleValueError, every().hour.at, ' 2:30')
+            self.assertRaises(ScheduleValueError, every().hour.at, "61:00")
+            self.assertRaises(ScheduleValueError, every().hour.at, "00:61")
+            self.assertRaises(ScheduleValueError, every().hour.at, "01:61")
+            self.assertRaises(TypeError, every().hour.at, 2)
+
+    def test_at_time_minute(self):
+        with mock_datetime(2010, 1, 6, 12, 20, 30):
+            mock_job = make_mock_job()
+            assert every().minute.at(':40').do(mock_job).next_run.hour == 12
+            assert every().minute.at(':40').do(mock_job).next_run.minute == 20
+            assert every().minute.at(':40').do(mock_job).next_run.second == 40
+            assert every().minute.at(':10').do(mock_job).next_run.hour == 12
+            assert every().minute.at(':10').do(mock_job).next_run.minute == 21
+            assert every().minute.at(':10').do(mock_job).next_run.second == 10
+
+            self.assertRaises(ScheduleValueError, every().minute.at, '::2')
+            self.assertRaises(ScheduleValueError, every().minute.at, '.2')
+            self.assertRaises(ScheduleValueError, every().minute.at, '2')
+            self.assertRaises(ScheduleValueError, every().minute.at, '2:30:00')
+            self.assertRaises(ScheduleValueError, every().minute.at, '2:30')
+            self.assertRaises(ScheduleValueError, every().minute.at, ' :30')
+            self.assertRaises(TypeError, every().minute.at, 2)
 
     def test_next_run_time(self):
         with mock_datetime(2010, 1, 6, 12, 15):


Reply via email to