<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[70006] trunk/WebKitTools</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/70006">70006</a></dd>
<dt>Author</dt> <dd>eric@webkit.org</dd>
<dt>Date</dt> <dd>2010-10-18 16:08:33 -0700 (Mon, 18 Oct 2010)</dd>
</dl>

<h3>Log Message</h3>
<pre>2010-10-18  Eric Seidel  &lt;eric@webkit.org&gt;

        Reviewed by Adam Barth.

        Add Queue class and add minimal unittesting of QueueStatusServer code
        https://bugs.webkit.org/show_bug.cgi?id=47847

        * QueueStatusServer/handlers/dashboard.py:
        * QueueStatusServer/handlers/queuestatus.py:
        * QueueStatusServer/handlers/recentstatus.py:
        * QueueStatusServer/handlers/statusbubble.py:
        * QueueStatusServer/handlers/updateworkitems.py:
        * QueueStatusServer/model/attachment.py:
        * QueueStatusServer/model/queues.py:
        * QueueStatusServer/model/queues_unittest.py: Added.
        * QueueStatusServer/model/svnrevision.py:
        * Scripts/test-webkitpy:
        * Scripts/webkitpy/test/main.py:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebKitToolsChangeLog">trunk/WebKitTools/ChangeLog</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServerhandlersdashboardpy">trunk/WebKitTools/QueueStatusServer/handlers/dashboard.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServerhandlersqueuestatuspy">trunk/WebKitTools/QueueStatusServer/handlers/queuestatus.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServerhandlersrecentstatuspy">trunk/WebKitTools/QueueStatusServer/handlers/recentstatus.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServerhandlersstatusbubblepy">trunk/WebKitTools/QueueStatusServer/handlers/statusbubble.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServerhandlersupdateworkitemspy">trunk/WebKitTools/QueueStatusServer/handlers/updateworkitems.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServermodelattachmentpy">trunk/WebKitTools/QueueStatusServer/model/attachment.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServermodelqueuespy">trunk/WebKitTools/QueueStatusServer/model/queues.py</a></li>
<li><a href="#trunkWebKitToolsQueueStatusServermodelsvnrevisionpy">trunk/WebKitTools/QueueStatusServer/model/svnrevision.py</a></li>
<li><a href="#trunkWebKitToolsScriptstestwebkitpy">trunk/WebKitTools/Scripts/test-webkitpy</a></li>
<li><a href="#trunkWebKitToolsScriptswebkitpytestmainpy">trunk/WebKitTools/Scripts/webkitpy/test/main.py</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkWebKitToolsQueueStatusServermodelqueues_unittestpy">trunk/WebKitTools/QueueStatusServer/model/queues_unittest.py</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebKitToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/ChangeLog (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/ChangeLog        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/ChangeLog        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -1,3 +1,22 @@
</span><ins>+2010-10-18  Eric Seidel  &lt;eric@webkit.org&gt;
+
+        Reviewed by Adam Barth.
+
+        Add Queue class and add minimal unittesting of QueueStatusServer code
+        https://bugs.webkit.org/show_bug.cgi?id=47847
+
+        * QueueStatusServer/handlers/dashboard.py:
+        * QueueStatusServer/handlers/queuestatus.py:
+        * QueueStatusServer/handlers/recentstatus.py:
+        * QueueStatusServer/handlers/statusbubble.py:
+        * QueueStatusServer/handlers/updateworkitems.py:
+        * QueueStatusServer/model/attachment.py:
+        * QueueStatusServer/model/queues.py:
+        * QueueStatusServer/model/queues_unittest.py: Added.
+        * QueueStatusServer/model/svnrevision.py:
+        * Scripts/test-webkitpy:
+        * Scripts/webkitpy/test/main.py:
+
</ins><span class="cx"> 2010-10-18  Anders Carlsson  &lt;andersca@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix build.
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServerhandlersdashboardpy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/handlers/dashboard.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/handlers/dashboard.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/handlers/dashboard.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -32,31 +32,16 @@
</span><span class="cx"> from google.appengine.ext.webapp import template
</span><span class="cx"> 
</span><span class="cx"> from model.attachment import Attachment
</span><del>-from model.queues import queues
</del><ins>+from model.queues import Queue
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class Dashboard(webapp.RequestHandler):
</span><ins>+    # We may want to sort these?
+    _ordered_queues = Queue.all()
+    _header_names = [queue.short_name() for queue in _ordered_queues]
</ins><span class="cx"> 
</span><del>-    # FIXME: This list probably belongs as part of a Queue object in queues.py
-    # Arrays are bubble_name, queue_name
-    # FIXME: Can this be unified with StatusBubble._queues_to_display?
-    _queues_to_display = [
-        [&quot;Style&quot;, &quot;style-queue&quot;],
-        [&quot;Cr-Linux&quot;, &quot;chromium-ews&quot;],
-        [&quot;Qt&quot;, &quot;qt-ews&quot;],
-        [&quot;Gtk&quot;, &quot;gtk-ews&quot;],
-        [&quot;Mac&quot;, &quot;mac-ews&quot;],
-        [&quot;Win&quot;, &quot;win-ews&quot;],
-        [&quot;Commit&quot;, &quot;commit-queue&quot;],
-    ]
-    # Split the zipped list into component parts
-    _header_names, _ordered_queue_names = zip(*_queues_to_display)
-
-    # This asserts that all of the queues listed above are valid queue names.
-    assert(reduce(operator.and_, map(lambda name: name in queues, _ordered_queue_names)))
-
-    def _build_bubble(self, attachment, queue_name):
-        queue_status = attachment.status_for_queue(queue_name)
</del><ins>+    def _build_bubble(self, attachment, queue):
+        queue_status = attachment.status_for_queue(queue.name())
</ins><span class="cx">         bubble = {
</span><span class="cx">             &quot;status_class&quot;: attachment.state_from_queue_status(queue_status) if queue_status else &quot;none&quot;,
</span><span class="cx">             &quot;status_date&quot;: queue_status.date if queue_status else None,
</span><span class="lines">@@ -67,7 +52,7 @@
</span><span class="cx">         row = {
</span><span class="cx">             &quot;bug_id&quot;: attachment.bug_id(),
</span><span class="cx">             &quot;attachment_id&quot;: attachment.id,
</span><del>-            &quot;bubbles&quot;: [self._build_bubble(attachment, queue_name) for queue_name in self._ordered_queue_names],
</del><ins>+            &quot;bubbles&quot;: [self._build_bubble(attachment, queue) for queue in self._ordered_queues],
</ins><span class="cx">         }
</span><span class="cx">         return row
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServerhandlersqueuestatuspy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/handlers/queuestatus.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/handlers/queuestatus.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/handlers/queuestatus.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> from google.appengine.ext import webapp
</span><span class="cx"> from google.appengine.ext.webapp import template
</span><span class="cx"> 
</span><del>-from model.queues import queues, display_name_for_queue
</del><ins>+from model.queues import Queue
</ins><span class="cx"> from model.workitems import WorkItems
</span><span class="cx"> from model.activeworkitems import ActiveWorkItems
</span><span class="cx"> 
</span><span class="lines">@@ -50,10 +50,15 @@
</span><span class="cx">         return rows
</span><span class="cx"> 
</span><span class="cx">     def get(self, queue_name):
</span><del>-        queued_items = WorkItems.all().filter(&quot;queue_name =&quot;, queue_name).get()
-        active_items = ActiveWorkItems.all().filter(&quot;queue_name =&quot;, queue_name).get()
-        statuses = queuestatus.QueueStatus.all().filter(&quot;queue_name =&quot;, queue_name).order(&quot;-date&quot;).fetch(15)
</del><ins>+        queue_name = queue_name.lowercase()
+        queue = Queue.queue_with_name(queue_name)
+        if not queue:
+            self.error(404)
</ins><span class="cx"> 
</span><ins>+        queued_items = WorkItems.all().filter(&quot;queue_name =&quot;, queue.name()).get()
+        active_items = ActiveWorkItems.all().filter(&quot;queue_name =&quot;, queue.name()).get()
+        statuses = queuestatus.QueueStatus.all().filter(&quot;queue_name =&quot;, queue.name()).order(&quot;-date&quot;).fetch(15)
+
</ins><span class="cx">         status_groups = []
</span><span class="cx">         last_patch_id = None
</span><span class="cx">         synthetic_patch_id_counter = 0
</span><span class="lines">@@ -69,7 +74,7 @@
</span><span class="cx">             last_patch_id = patch_id
</span><span class="cx"> 
</span><span class="cx">         template_values = {
</span><del>-            &quot;display_queue_name&quot;: display_name_for_queue(queue_name),
</del><ins>+            &quot;display_queue_name&quot;: queue.display_name(),
</ins><span class="cx">             &quot;work_item_rows&quot;: self._rows_for_work_items(queued_items, active_items),
</span><span class="cx">             &quot;status_groups&quot;: status_groups,
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServerhandlersrecentstatuspy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/handlers/recentstatus.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/handlers/recentstatus.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/handlers/recentstatus.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -31,23 +31,24 @@
</span><span class="cx"> from google.appengine.ext import webapp
</span><span class="cx"> from google.appengine.ext.webapp import template
</span><span class="cx"> 
</span><del>-from model.queues import queues, display_name_for_queue
</del><ins>+from model.queues import Queue
</ins><span class="cx"> from model.queuestatus import QueueStatus
</span><span class="cx"> from model.workitems import WorkItems
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class QueueBubble(object):
</span><span class="cx">     &quot;&quot;&quot;View support class for recentstatus.html&quot;&quot;&quot;
</span><del>-    def __init__(self, queue_name):
-        self._queue_name = queue_name
-        self._work_items = WorkItems.all().filter(&quot;queue_name =&quot;, queue_name).get()
-        self._last_status = QueueStatus.all().filter(&quot;queue_name =&quot;, queue_name).order(&quot;-date&quot;).get()
</del><ins>+    def __init__(self, queue):
+        self._queue = queue
+        self._work_items = WorkItems.all().filter(&quot;queue_name =&quot;, queue.name()).get()
+        self._last_status = QueueStatus.all().filter(&quot;queue_name =&quot;, queue.name()).order(&quot;-date&quot;).get()
</ins><span class="cx"> 
</span><ins>+    # FIXME: name and display_name should be replaced by a .queue() accessor.
</ins><span class="cx">     def name(self):
</span><del>-        return self._queue_name
</del><ins>+        return self._queue.name()
</ins><span class="cx"> 
</span><span class="cx">     def display_name(self):
</span><del>-        return display_name_for_queue(self._queue_name)
</del><ins>+        return self._queue.display_name()
</ins><span class="cx"> 
</span><span class="cx">     def _last_status_date(self):
</span><span class="cx">         if not self._last_status:
</span><span class="lines">@@ -88,6 +89,6 @@
</span><span class="cx"> 
</span><span class="cx">     def get(self):
</span><span class="cx">         template_values = {
</span><del>-            &quot;queues&quot;: [QueueBubble(queue_name) for queue_name in queues],
</del><ins>+            &quot;queues&quot;: [QueueBubble(queue) for queue in Queue.all()],
</ins><span class="cx">         }
</span><span class="cx">         self.response.out.write(template.render(&quot;templates/recentstatus.html&quot;, template_values))
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServerhandlersstatusbubblepy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/handlers/statusbubble.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/handlers/statusbubble.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/handlers/statusbubble.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -33,34 +33,18 @@
</span><span class="cx"> 
</span><span class="cx"> from model.attachment import Attachment
</span><span class="cx"> from model.workitems import WorkItems
</span><del>-from model.queues import queues, name_with_underscores
</del><ins>+from model.queues import Queue
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> class StatusBubble(webapp.RequestHandler):
</span><del>-    # FIXME: This list probably belongs as part of a Queue object in queues.py
-    # Arrays are bubble_name, queue_name
-    _queues_to_display = [
-        [&quot;style&quot;, &quot;style-queue&quot;],
-        [&quot;cr-linux&quot;, &quot;chromium-ews&quot;],
-        [&quot;gtk&quot;, &quot;gtk-ews&quot;],
-        [&quot;qt&quot;, &quot;qt-ews&quot;],
-        [&quot;mac&quot;, &quot;mac-ews&quot;],
-        [&quot;win&quot;, &quot;win-ews&quot;],
-        [&quot;efl&quot;, &quot;efl-ews&quot;],
-    ]
</del><ins>+    _queues_to_display = [queue for queue in Queue.all() if queue.is_ews()]
</ins><span class="cx"> 
</span><del>-    # This asserts that all of the queues listed above are valid queue names.
-    assert(reduce(operator.and_, map(lambda name_pair: name_pair[1] in queues, _queues_to_display)))
-
-    def _build_bubble(self, queue_name_pair, attachment):
-        bubble_name = queue_name_pair[0]
-        queue_name = queue_name_pair[1]
-
-        queue_status = attachment.status_for_queue(queue_name)
</del><ins>+    def _build_bubble(self, queue, attachment):
+        queue_status = attachment.status_for_queue(queue.name())
</ins><span class="cx">         bubble = {
</span><del>-            &quot;name&quot;: bubble_name,
</del><ins>+            &quot;name&quot;: queue.short_name().lowercase(),
</ins><span class="cx">             &quot;attachment_id&quot;: attachment.id,
</span><del>-            &quot;queue_position&quot;: attachment.position_in_queue(queue_name),
</del><ins>+            &quot;queue_position&quot;: attachment.position_in_queue(queue.name()),
</ins><span class="cx">             &quot;state&quot;: attachment.state_from_queue_status(queue_status) if queue_status else &quot;none&quot;,
</span><span class="cx">             &quot;status&quot;: queue_status,
</span><span class="cx">         }
</span><span class="lines">@@ -68,7 +52,7 @@
</span><span class="cx"> 
</span><span class="cx">     def get(self, attachment_id):
</span><span class="cx">         attachment = Attachment(int(attachment_id))
</span><del>-        bubbles = [self._build_bubble(name_pair, attachment) for name_pair in self._queues_to_display]
</del><ins>+        bubbles = [self._build_bubble(queue, attachment) for queue in self._queues_to_display]
</ins><span class="cx">         template_values = {
</span><span class="cx">             &quot;bubbles&quot;: bubbles,
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServerhandlersupdateworkitemspy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/handlers/updateworkitems.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/handlers/updateworkitems.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/handlers/updateworkitems.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> from google.appengine.ext.webapp import template
</span><span class="cx"> 
</span><span class="cx"> from handlers.updatebase import UpdateBase
</span><del>-from model.queues import queues
</del><ins>+from model.queues import Queue
</ins><span class="cx"> from model.workitems import WorkItems
</span><span class="cx"> 
</span><span class="cx"> from datetime import datetime
</span><span class="lines">@@ -41,8 +41,9 @@
</span><span class="cx">         self.response.out.write(template.render(&quot;templates/updateworkitems.html&quot;, None))
</span><span class="cx"> 
</span><span class="cx">     def _work_items_for_queue(self, queue_name):
</span><del>-        if queue_name not in queues:
-            self.response.out.write(&quot;\&quot;%s\&quot; is not in queues %s&quot; % (queue_name, queues))
</del><ins>+        queue = Queue.queue_for_name(queue_name)
+        if queue:
+            self.response.out.write(&quot;\&quot;%s\&quot; is not in queues %s&quot; % (queue_name, Queue.all()))
</ins><span class="cx">             return None
</span><span class="cx">         work_items = WorkItems.all().filter(&quot;queue_name =&quot;, queue_name).get()
</span><span class="cx">         if not work_items:
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServermodelattachmentpy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/model/attachment.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/model/attachment.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/model/attachment.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -30,7 +30,7 @@
</span><span class="cx"> 
</span><span class="cx"> from google.appengine.api import memcache
</span><span class="cx"> 
</span><del>-from model.queues import queues, name_with_underscores
</del><ins>+from model.queues import Queue
</ins><span class="cx"> from model.queuestatus import QueueStatus
</span><span class="cx"> from model.workitems import WorkItems
</span><span class="cx"> 
</span><span class="lines">@@ -91,7 +91,7 @@
</span><span class="cx">         return self._queue_positions().get(queue_name)
</span><span class="cx"> 
</span><span class="cx">     def status_for_queue(self, queue_name):
</span><del>-        underscore_queue_name = name_with_underscores(queue_name)
</del><ins>+        underscore_queue_name = Queue(queue_name).name_with_underscores()
</ins><span class="cx">         # summary() is a horrible API and should be killed.
</span><span class="cx">         queue_summary = self.summary().get(underscore_queue_name)
</span><span class="cx">         if not queue_summary:
</span><span class="lines">@@ -134,7 +134,9 @@
</span><span class="cx">             summary[queue] = None
</span><span class="cx">             status = QueueStatus.all().filter('queue_name =', queue).filter('active_patch_id =', self.id).order('-date').get()
</span><span class="cx">             if status:
</span><del>-                summary[name_with_underscores(queue)] = {
</del><ins>+                queue_name = Queue(queue_name).name_with_underscores()
+                # summary() is a horrible API and should be killed.
+                summary[queue_name] = {
</ins><span class="cx">                     &quot;state&quot;: self.state_from_queue_status(status),
</span><span class="cx">                     &quot;status&quot;: status,
</span><span class="cx">                 }
</span></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServermodelqueuespy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/model/queues.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/model/queues.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/model/queues.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -26,39 +26,66 @@
</span><span class="cx"> # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
</span><span class="cx"> # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> import re
</span><span class="cx"> 
</span><span class="cx"> 
</span><del>-queues = [
-    &quot;commit-queue&quot;,
-    &quot;style-queue&quot;,
-    &quot;chromium-ews&quot;,
-    &quot;qt-ews&quot;,
-    &quot;gtk-ews&quot;,
-    &quot;mac-ews&quot;,
-    &quot;win-ews&quot;,
-    &quot;efl-ews&quot;,
-]
</del><ins>+class Queue(object):
</ins><span class="cx"> 
</span><ins>+    # Eventually the list of queues may be stored in the data store.
+    _all_queue_names = [
+        &quot;commit-queue&quot;,
+        &quot;style-queue&quot;,
+        &quot;chromium-ews&quot;,
+        &quot;qt-ews&quot;,
+        &quot;gtk-ews&quot;,
+        &quot;mac-ews&quot;,
+        &quot;win-ews&quot;,
+        &quot;efl-ews&quot;,
+    ]
</ins><span class="cx"> 
</span><del>-# FIXME: We need some sort of Queue object.
-def _title_case(string):
-    words = string.split(&quot; &quot;)
-    words = map(lambda word: word.capitalize(), words)
-    return &quot; &quot;.join(words)
</del><ins>+    def __init__(self, name):
+        assert(name in self._all_queue_names)
+        self._name = name
</ins><span class="cx"> 
</span><ins>+    @classmethod
+    def queue_with_name(cls, queue_name):
+        if queue_name not in cls._all_queue_names:
+            return None
+        return Queue(queue_name)
</ins><span class="cx"> 
</span><del>-def display_name_for_queue(queue_name):
-    # HACK: chromium-ews is incorrectly named.
-    display_name = queue_name.replace(&quot;chromium-ews&quot;, &quot;cr-linux-ews&quot;)
</del><ins>+    @classmethod
+    def all(cls):
+        return [Queue(name) for name in cls._all_queue_names]
</ins><span class="cx"> 
</span><del>-    display_name = display_name.replace(&quot;-&quot;, &quot; &quot;)
-    display_name = display_name.replace(&quot;cr&quot;, &quot;chromium&quot;)
-    display_name = _title_case(display_name)
-    display_name = display_name.replace(&quot;Ews&quot;, &quot;EWS&quot;)
-    return display_name
</del><ins>+    def name(self):
+        return self._name
</ins><span class="cx"> 
</span><ins>+    def _caplitalize_after_dash(self, string):
+        return &quot;-&quot;.join([word[0].upper() + word[1:] for word in string.split(&quot;-&quot;)])
</ins><span class="cx"> 
</span><del>-def name_with_underscores(dashed_name):
-    regexp = re.compile(&quot;-&quot;)
-    return regexp.sub(&quot;_&quot;, dashed_name)
</del><ins>+    # For use in status bubbles or table headers
+    def short_name(self):
+        # HACK: chromium-ews is incorrectly named.
+        short_name = self._name.replace(&quot;chromium-ews&quot;, &quot;Cr-Linux-ews&quot;)
+        short_name = short_name.replace(&quot;-ews&quot;, &quot;&quot;)
+        short_name = short_name.replace(&quot;-queue&quot;, &quot;&quot;)
+        return self._caplitalize_after_dash(short_name.capitalize())
+
+    def display_name(self):
+        # HACK: chromium-ews is incorrectly named.
+        display_name = self._name.replace(&quot;chromium-ews&quot;, &quot;cr-linux-ews&quot;)
+
+        display_name = display_name.replace(&quot;-&quot;, &quot; &quot;)
+        display_name = display_name.replace(&quot;cr&quot;, &quot;chromium&quot;)
+        display_name = display_name.title()
+        display_name = display_name.replace(&quot;Ews&quot;, &quot;EWS&quot;)
+        return display_name
+
+    _dash_regexp = re.compile(&quot;-&quot;)
+
+    def name_with_underscores(self):
+        return self._dash_regexp.sub(&quot;_&quot;, self._name)
+
+    def is_ews(self):
+        return self._name.endswith(&quot;-ews&quot;)
</ins></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServermodelqueues_unittestpy"></a>
<div class="addfile"><h4>Added: trunk/WebKitTools/QueueStatusServer/model/queues_unittest.py (0 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/model/queues_unittest.py                                (rev 0)
+++ trunk/WebKitTools/QueueStatusServer/model/queues_unittest.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -0,0 +1,73 @@
</span><ins>+# Copyright (C) 2010 Google, Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#    * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#    * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#    * Neither the name of Research in Motion Ltd. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+
+from model.queues import Queue
+
+
+class QueueTest(unittest.TestCase):
+    def test_is_ews(self):
+        mac_ews = Queue(&quot;mac-ews&quot;)
+        self.assertTrue(mac_ews.is_ews())
+
+    def test_queue_with_name(self):
+        self.assertEqual(Queue.queue_with_name(&quot;bogus&quot;), None)
+        self.assertEqual(Queue.queue_with_name(&quot;mac-ews&quot;).name(), &quot;mac-ews&quot;)
+        self.assertRaises(AssertionError, Queue, (&quot;bogus&quot;))
+
+    def _assert_short_name(self, queue_name, short_name):
+        self.assertEquals(Queue(queue_name).short_name(), short_name)
+
+    def test_short_name(self):
+        self._assert_short_name(&quot;mac-ews&quot;, &quot;Mac&quot;)
+        self._assert_short_name(&quot;chromium-ews&quot;, &quot;Cr-Linux&quot;)
+        self._assert_short_name(&quot;commit-queue&quot;, &quot;Commit&quot;)
+        self._assert_short_name(&quot;style-queue&quot;, &quot;Style&quot;)
+
+    def _assert_display_name(self, queue_name, short_name):
+        self.assertEquals(Queue(queue_name).display_name(), short_name)
+
+    def test_display_name(self):
+        self._assert_display_name(&quot;mac-ews&quot;, &quot;Mac EWS&quot;)
+        self._assert_display_name(&quot;chromium-ews&quot;, &quot;Chromium Linux EWS&quot;)
+        self._assert_display_name(&quot;commit-queue&quot;, &quot;Commit Queue&quot;)
+        self._assert_display_name(&quot;style-queue&quot;, &quot;Style Queue&quot;)
+
+    def _assert_name_with_underscores(self, queue_name, short_name):
+        self.assertEquals(Queue(queue_name).name_with_underscores(), short_name)
+
+    def test_name_with_underscores(self):
+        self._assert_name_with_underscores(&quot;mac-ews&quot;, &quot;mac_ews&quot;)
+        self._assert_name_with_underscores(&quot;chromium-ews&quot;, &quot;chromium_ews&quot;)
+        self._assert_name_with_underscores(&quot;commit-queue&quot;, &quot;commit_queue&quot;)
+
+
+if __name__ == '__main__':
+    unittest.main()
</ins></span></pre></div>
<a id="trunkWebKitToolsQueueStatusServermodelsvnrevisionpy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/QueueStatusServer/model/svnrevision.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/QueueStatusServer/model/svnrevision.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/QueueStatusServer/model/svnrevision.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> from google.appengine.ext import db
</span><span class="cx"> 
</span><ins>+
</ins><span class="cx"> class SVNRevision(db.Model):
</span><span class="cx">     number = db.IntegerProperty()
</span><span class="cx">     broken_bots = db.StringListProperty(default=[])
</span></span></pre></div>
<a id="trunkWebKitToolsScriptstestwebkitpy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/Scripts/test-webkitpy (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/Scripts/test-webkitpy        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/Scripts/test-webkitpy        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -227,9 +227,30 @@
</span><span class="cx">         _log.warn(message)
</span><span class="cx"> 
</span><span class="cx"> 
</span><ins>+def _path_from_webkit_root(*components):
+    webkit_root = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
+    return os.path.join(webkit_root, *components)
+
+
+def _test_import(module_path):
+    try:
+        sys.path.append(os.path.dirname(module_path))
+        module_name = os.path.basename(module_path)
+        __import__(module_name)
+        return True
+    except Exception, e:
+        message = &quot;Skipping tests in %s due to failure (%s).&quot; % (module_path, e)
+        if module_name.endswith(&quot;QueueStatusServer&quot;):
+            message += &quot;  This module is optional.  The failure is likely due to a missing Google AppEngine install.  (http://code.google.com/appengine/downloads.html)&quot;
+        _log.warn(message)
+        return False
+
</ins><span class="cx"> if __name__ == &quot;__main__&quot;:
</span><del>-
-    external_package_paths = [os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(__file__))), 'WebKit2', 'Scripts', 'webkit2')]
</del><ins>+    # FIXME: We should probably test each package separately to avoid naming conflicts.
+    external_package_paths = [
+        _path_from_webkit_root('WebKit2', 'Scripts', 'webkit2'),
+        _path_from_webkit_root('WebKitTools', 'QueueStatusServer'),
+    ]
</ins><span class="cx">     init(sys.argv[1:], external_package_paths)
</span><span class="cx"> 
</span><span class="cx">     # We import the unit test code after init() to ensure that any
</span><span class="lines">@@ -240,4 +261,6 @@
</span><span class="cx">     # running the unit tests.
</span><span class="cx">     from webkitpy.test.main import Tester
</span><span class="cx"> 
</span><ins>+    external_package_paths = filter(_test_import, external_package_paths)
+
</ins><span class="cx">     Tester().run_tests(sys.argv, external_package_paths)
</span></span></pre></div>
<a id="trunkWebKitToolsScriptswebkitpytestmainpy"></a>
<div class="modfile"><h4>Modified: trunk/WebKitTools/Scripts/webkitpy/test/main.py (70005 => 70006)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/WebKitTools/Scripts/webkitpy/test/main.py        2010-10-18 22:44:03 UTC (rev 70005)
+++ trunk/WebKitTools/Scripts/webkitpy/test/main.py        2010-10-18 23:08:33 UTC (rev 70006)
</span><span class="lines">@@ -50,12 +50,12 @@
</span><span class="cx"> 
</span><span class="cx">         return unittest_paths
</span><span class="cx"> 
</span><del>-    def _modules_from_paths(self, webkitpy_dir, paths):
</del><ins>+    def _modules_from_paths(self, package_root, paths):
</ins><span class="cx">         &quot;&quot;&quot;Return a list of fully-qualified module names given paths.&quot;&quot;&quot;
</span><del>-        webkitpy_dir = os.path.abspath(webkitpy_dir)
-        webkitpy_name = os.path.split(webkitpy_dir)[1]  # Equals &quot;webkitpy&quot;.
</del><ins>+        package_path = os.path.abspath(package_root)
+        root_package_name = os.path.split(package_path)[1]  # Equals &quot;webkitpy&quot;.
</ins><span class="cx"> 
</span><del>-        prefix_length = len(webkitpy_dir)
</del><ins>+        prefix_length = len(package_path)
</ins><span class="cx"> 
</span><span class="cx">         modules = []
</span><span class="cx">         for path in paths:
</span><span class="lines">@@ -72,7 +72,8 @@
</span><span class="cx">                     break
</span><span class="cx">                 parts.insert(0, tail)
</span><span class="cx">             # We now have, for example: common.config.ports_unittest
</span><del>-            parts.insert(0, webkitpy_name)  # Put &quot;webkitpy&quot; at the beginning.
</del><ins>+            # FIXME: This is all a hack around the fact that we always prefix webkitpy includes with &quot;webkitpy.&quot;
+            parts.insert(0, root_package_name)  # Put &quot;webkitpy&quot; at the beginning.
</ins><span class="cx">             module = &quot;.&quot;.join(parts)
</span><span class="cx">             modules.append(module)
</span><span class="cx"> 
</span><span class="lines">@@ -91,6 +92,9 @@
</span><span class="cx">         if external_package_paths is None:
</span><span class="cx">             external_package_paths = []
</span><span class="cx">         else:
</span><ins>+            # FIXME: We should consider moving webkitpy off of using &quot;webkitpy.&quot; to prefix
+            # all includes.  If we did that, then this would use path instead of dirname(path).
+            # QueueStatusServer.__init__ has a sys.path import hack due to this code.
</ins><span class="cx">             sys.path.extend(set(os.path.dirname(path) for path in external_package_paths))
</span><span class="cx"> 
</span><span class="cx">         if len(sys_argv) &gt; 1 and not sys_argv[-1].startswith(&quot;-&quot;):
</span><span class="lines">@@ -101,6 +105,7 @@
</span><span class="cx"> 
</span><span class="cx">         # Otherwise, auto-detect all unit tests.
</span><span class="cx"> 
</span><ins>+        # FIXME: This should be combined with the external_package_paths code above.
</ins><span class="cx">         webkitpy_dir = os.path.dirname(webkitpy.__file__)
</span><span class="cx"> 
</span><span class="cx">         modules = []
</span></span></pre>
</div>
</div>

</body>
</html>