Commits

Wayne Werner committed c5ee5af

Added a bunch of test templates and changed up the README

Comments (0)

Files changed (3)

 What aims to be a sweet-action issue tracking system written in Python, and
 allowing for easy multiple project support.
 
-Milestone Timesheet
+# Roadmap
 
-    $ slayer task start "Doing things"
-    Starting task ...
+- Support for projects
+- Support for tasks
+- Support for users
+- Support for timesheets
 
-    ***************************************************
-    ID: <1>
-    Description: Doing things
-    Status: In Progress
-    Work history:
-     September 16, 2012
-      2:47 PM - Now
-     Total elapsed time:
-      1 Minute
-    **************************************************
+# Projects
 
-    $ slayer task start "Making a sweet program"
-    Stopping task <1>...
-    Starting task ...
+While not strictly required, each task must be assigned to a project. If none
+is provided, the *default* project will be used.
 
-    **************************************************
-    ID: <2>
-    Description: Making a sweet program
-    Status: In Progress
-    Work history:
-     September 16, 2012
-      2:50 PM - Now
-     Total elapsed time:
-      1 Minute
-    **************************************************
+In the first release, a project will consist of a unique **name**, a **desc**ription,
+and an **archived** flag.
 
-    $ slayer task list all
-    **************************************************
-    ID: <1>
-    Description: Doing things
-    Status: Pending
-    Work history:
-     September 16, 2012
-      2:47 PM - 2:50 PM
-     Total elapsed time:
-      3 Minutes
-    **************************************************
-    ID: <2>
-    Description: Making a sweet program
-    Status: In Progress
-    Work history:
-     September 16, 2012
-      2:50 PM - Now
-     Total elapsed time:
-      10 Minutes
-    **************************************************
+# Users
 
-    $ slayer task stop
-    Stopping task...
-    **************************************************
-    ID: <2>
-    Description: Making a sweet program
-    Status: Pending
-    Work history:
-     September 16, 2012
-      2:50 PM - 3:15 PM
-     Total elapsed time:
-      25 Minutes
-    **************************************************
+A user consists of a unique **id** (e.g. username, or email address - Boog Slayer
+makes no requirements of what is unique in your system), and **name**. The user
+also has a timesheet that consists of work **Interval**s
 
-    $ slayer task complete 1
-    Completing task...
-    **************************************************
-    ID: <1>
-    Description: Doing things
-    Status: Complete
-    Work history:
-     September 16, 2012
-      2:47 PM - 2:50 PM
-     Total elapsed time:
-      3 Minutes
-    **************************************************
+# Interval
+
+An interval consists of a **start** datetime, and **end** datetime, the
+**task_id** - the id of the task that has been worked on - and the **user_id** - the id of 
+the user that has done the work.
+
+# Tasks
+
+A task has a variety of information to help sort and classify it. Each task has
+a unique **id** that is automatically assigned, and it must be assigned to a
+project - the *default* one by, uh, default. Other optional values are:
+
+- **desc**: A short description of the task
+- **type**: The type of the task. *Suggested types: bug, item, feature request*
+- **status**: The status of the task. *Suggested status values: new, assigned,
+  in progress, completed, closed, won't fix*
+- **assigned_to**: The id of the user the task is assigned to. Can be None, or
+  the actual ID of a user.
+- **contact**: People to contact for the task. *Suggested use: Name
+  <email@address.com>, or IDs of users*
+- **priority**: An integer priority of the task. *Suggested values: 1 -
+  Highest, through 10 - Lowest*
+- **due**: The due datetime of the task.
+- **original_estimate**: The first estimate provided for the task.
+- **current_estimate**: The most up-to-date estimate of time left on the task.
+- **version**: *Suggested use: The version of the application this task relies
+  on.*
+- **backlog_order**: An integer describing the backlog order of the task.
+  *Suggested use: 1 - next thing to work on, N - last thing to work on*
+- **area**: The area that the task belongs to. *Suggested use: QA, Developers -
+  or UI, Backend*
+- **parent_case**: *Suggested use: A case that depends on this case being done
+  first*
     if backlog_order is not None:
         task.backlog_order = backlog_order
     if area is not None:
-        task.area = None
+        task.area = area
     if parent_case is not None:
-        task.parent_case = None
+        parent = session.query(Task).filter_by(id=parent_case).first()
+        if parent is None:
+            raise ValueError("parent_case id <{}> does not exist.".format(parent_case))
+        task.parent_case = parent_case
 
 
     session.add(task)
         task = slayer.Task()
         self.assertEqual(None, task.desc)
 
+    def test_whenTaskIsCreatedAndIdAlreadyExistsItShouldValueError(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedAndIdDoesNotExistItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithoutProjectItShouldBeDefault(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithProjectThatDoesNotExistItShouldValueError(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithProjectThatExistsItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoTypeItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithTypeItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoStatusItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithStatusItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoAssignedToItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithAssignedToAndUserDoesNotExistItShouldValueError(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithAssignedToAdnUserExistsItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithContactItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoContactItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoPriorityItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithPriorityItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoDueDateItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithDueDateItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoOriginalEstimateItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithOriginalEstimateItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoCurrentEstimateItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithCurrentEstimateItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithCurrentEstimateAndNoOriginalOriginalShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoVersionItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithVersionItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoBacklogOrderItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithBacklogOrderItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoAreaItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithAreaItShouldBeSet(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithNoParentCaseItShouldBeNone(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithBadParentCaseItShouldValueError(self):
+        self.skipTest("Write this test")
+
+    def test_whenTaskIsCreatedWithGoodParentCaseItShouldBeSet(self):
+        self.skipTest("Write this test")
+
 class IntervalTests(unittest.TestCase):
     def test_whenIntervalIsCreatedWithNoStartItShouldBeNow(self):
-        self.skipTest("Yeah, like that")
-        interval = slayer.Interval()
-        self.assertAlmostEqual(datetime.now(), interval.start, places=0)
+        interval = slayer.Interval(1, 'uwwerne')
+        self.assertAlmostEqual(datetime.now().toordinal(),
+                               interval.start.toordinal(), places=0)
 
     def test_whenIntervalIsCreatedWithStartItShouldBeTheProvidedOne(self):
-        self.skipTest("Yeah, like that")
-        expected_start = time.time()-200
-        interval = slayer.Interval(start=expected_start)
-        self.assertAlmostEqual(expected_start, interval.start)
+        expected_start = datetime.now()
+        interval = slayer.Interval(1, 'uwwerne', start=expected_start)
+        self.assertAlmostEqual(expected_start, interval.start, places=2)
 
     def test_whenIntervalIsCreatedWithNoEndItShouldBeNone(self):
-        self.skipTest("Yeah, like that")
-        interval = slayer.Interval()
+        interval = slayer.Interval(1, 'wayne')
         self.assertEqual(None, interval.end)
 
     def test_whenIntervalIsCreatedWithEndItShouldBeTheProvidedOne(self):
-        self.skipTest("Yeah, like that")
         expected_end = time.time()-42
-        interval = slayer.Interval(end=expected_end)
+        interval = slayer.Interval(3, 'wayne', end=expected_end)
         self.assertEqual(expected_end, interval.end)
 
 class SlayerTests(unittest.TestCase):
         task = slayer.get_task(id)
         self.assertEqual(expected_backlog_order, task.backlog_order)
 
+    def test_whenEditTaskIsCalledWithAreaItShouldBeUpdated(self):
+        expected_area = 'some area'
+        id = slayer.add_task().id
+        slayer.edit_task(id, area=expected_area)
+        task = slayer.get_task(id)
+        self.assertEqual(expected_area, task.area)
+
+    def test_whenEditTaskIsCalledWithParentCaseItShouldBeUpdated(self):
+        expected_parent_case = slayer.add_task().id
+        id = slayer.add_task().id
+        slayer.edit_task(id, parent_case=expected_parent_case)
+        task = slayer.get_task(id)
+        self.assertEqual(expected_parent_case, task.parent_case)
+
+    def test_whenEditTaskIsCalledWithParentCaseItShouldExist(self):
+        bad_parent_case = 70
+        id = slayer.add_task().id
+        with self.assertRaises(ValueError):
+            slayer.edit_task(id, parent_case=bad_parent_case)
+
     ##############
     # User Tests #
     ##############