<!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>[198598] trunk/Websites/perf.webkit.org</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/198598">198598</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2016-03-23 14:55:55 -0700 (Wed, 23 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Add unit tests for test-group.js
https://bugs.webkit.org/show_bug.cgi?id=155781

Reviewed by Joseph Pecoraro.

Added unit tests for test-group.js that would have caught regressions fixed in <a href="http://trac.webkit.org/projects/webkit/changeset/198503">r198503</a>.

* public/v3/components/chart-pane-base.js:
(ChartPaneBase.prototype._renderAnnotations): Added a forgotten break statement.
* public/v3/models/build-request.js:
(BuildRequest.prototype.setResult):
(BuildRequest):
* public/v3/models/test-group.js:
* unit-tests/measurement-set-tests.js: Use ./resources/v3-models.js to reduce the code duplication.
* unit-tests/resources/v3-models.js: Import more stuff from v3 models.
(beforeEach):
* unit-tests/test-groups-tests.js: Added. Added some unit tests for TestGroup.
(sampleTestGroup):
(.testGroupWithStatusList):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3componentschartpanebasejs">trunk/Websites/perf.webkit.org/public/v3/components/chart-pane-base.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelsbuildrequestjs">trunk/Websites/perf.webkit.org/public/v3/models/build-request.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicv3modelstestgroupjs">trunk/Websites/perf.webkit.org/public/v3/models/test-group.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsmeasurementsettestsjs">trunk/Websites/perf.webkit.org/unit-tests/measurement-set-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgunittestsresourcesv3modelsjs">trunk/Websites/perf.webkit.org/unit-tests/resources/v3-models.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgunitteststestgroupstestsjs">trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -1,5 +1,27 @@
</span><span class="cx"> 2016-03-22  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
</span><span class="cx"> 
</span><ins>+        Add unit tests for test-group.js
+        https://bugs.webkit.org/show_bug.cgi?id=155781
+
+        Reviewed by Joseph Pecoraro.
+
+        Added unit tests for test-group.js that would have caught regressions fixed in r198503.
+
+        * public/v3/components/chart-pane-base.js:
+        (ChartPaneBase.prototype._renderAnnotations): Added a forgotten break statement.
+        * public/v3/models/build-request.js:
+        (BuildRequest.prototype.setResult):
+        (BuildRequest):
+        * public/v3/models/test-group.js:
+        * unit-tests/measurement-set-tests.js: Use ./resources/v3-models.js to reduce the code duplication.
+        * unit-tests/resources/v3-models.js: Import more stuff from v3 models.
+        (beforeEach):
+        * unit-tests/test-groups-tests.js: Added. Added some unit tests for TestGroup.
+        (sampleTestGroup):
+        (.testGroupWithStatusList):
+
+2016-03-22  Ryosuke Niwa  &lt;rniwa@webkit.org&gt;
+
</ins><span class="cx">         Fix a typo.
</span><span class="cx"> 
</span><span class="cx">         * config.json:
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3componentschartpanebasejs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/components/chart-pane-base.js (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/components/chart-pane-base.js        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/public/v3/components/chart-pane-base.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -203,6 +203,7 @@
</span><span class="cx">             switch (task.changeType()) {
</span><span class="cx">             case 'inconclusive':
</span><span class="cx">                 fillStyle = '#fcc';
</span><ins>+                break;
</ins><span class="cx">             case 'progression':
</span><span class="cx">                 fillStyle = '#39f';
</span><span class="cx">                 break;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelsbuildrequestjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/build-request.js (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/build-request.js        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/public/v3/models/build-request.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -1,3 +1,4 @@
</span><ins>+'use strict';
</ins><span class="cx"> 
</span><span class="cx"> class BuildRequest extends DataModelObject {
</span><span class="cx"> 
</span><span class="lines">@@ -61,3 +62,6 @@
</span><span class="cx">         this._testGroup.didSetResult(this);
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
+if (typeof module != 'undefined')
+    module.exports.BuildRequest = BuildRequest;
</ins></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicv3modelstestgroupjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/v3/models/test-group.js (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/v3/models/test-group.js        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/public/v3/models/test-group.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -1,3 +1,4 @@
</span><ins>+'use strict';
</ins><span class="cx"> 
</span><span class="cx"> class TestGroup extends LabeledObject {
</span><span class="cx"> 
</span><span class="lines">@@ -241,3 +242,6 @@
</span><span class="cx">         return testGroups;
</span><span class="cx">     }
</span><span class="cx"> }
</span><ins>+
+if (typeof module != 'undefined')
+    module.exports.TestGroup = TestGroup;
</ins></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsmeasurementsettestsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/measurement-set-tests.js (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/measurement-set-tests.js        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/unit-tests/measurement-set-tests.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -3,20 +3,8 @@
</span><span class="cx"> var assert = require('assert');
</span><span class="cx"> 
</span><span class="cx"> require('./resources/mock-remote-api.js');
</span><ins>+require('./resources/v3-models.js');
</ins><span class="cx"> 
</span><del>-global.DataModelObject = require('../public/v3/models/data-model.js').DataModelObject;
-global.LabeledObject = require('../public/v3/models/data-model.js').LabeledObject;
-global.CommitLog = require('../public/v3/models/commit-log.js').CommitLog;
-global.Build = require('../public/v3/models/builder.js').Build;
-global.Builder = require('../public/v3/models/builder.js').Builder;
-global.MeasurementRootSet = require('../public/v3/models/root-set.js').MeasurementRootSet;
-global.MeasurementAdaptor = require('../public/v3/models/measurement-adaptor.js').MeasurementAdaptor;
-global.MeasurementCluster = require('../public/v3/models/measurement-cluster.js').MeasurementCluster;
-global.MeasurementSet = require('../public/v3/models/measurement-set.js').MeasurementSet;
-global.Repository = require('../public/v3/models/repository.js').Repository;
-global.RootSet = require('../public/v3/models/root-set.js').RootSet;
-global.Statistics = require('../public/shared/statistics.js');
-
</del><span class="cx"> describe('MeasurementSet', function () {
</span><span class="cx">     beforeEach(function () {
</span><span class="cx">         MeasurementSet._set = null;
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunittestsresourcesv3modelsjs"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/unit-tests/resources/v3-models.js (198597 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/resources/v3-models.js        2016-03-23 21:40:40 UTC (rev 198597)
+++ trunk/Websites/perf.webkit.org/unit-tests/resources/v3-models.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -10,16 +10,20 @@
</span><span class="cx"> importFromV3('models/data-model.js', 'LabeledObject');
</span><span class="cx"> 
</span><span class="cx"> importFromV3('models/analysis-task.js', 'AnalysisTask');
</span><ins>+importFromV3('models/build-request.js', 'BuildRequest');
</ins><span class="cx"> importFromV3('models/builder.js', 'Build');
</span><span class="cx"> importFromV3('models/builder.js', 'Builder');
</span><span class="cx"> importFromV3('models/commit-log.js', 'CommitLog');
</span><span class="cx"> importFromV3('models/measurement-adaptor.js', 'MeasurementAdaptor');
</span><ins>+importFromV3('models/measurement-cluster.js', 'MeasurementCluster');
+importFromV3('models/measurement-set.js', 'MeasurementSet');
</ins><span class="cx"> importFromV3('models/metric.js', 'Metric');
</span><span class="cx"> importFromV3('models/platform.js', 'Platform');
</span><span class="cx"> importFromV3('models/repository.js', 'Repository');
</span><span class="cx"> importFromV3('models/root-set.js', 'MeasurementRootSet');
</span><span class="cx"> importFromV3('models/root-set.js', 'RootSet');
</span><span class="cx"> importFromV3('models/test.js', 'Test');
</span><ins>+importFromV3('models/test-group.js', 'TestGroup');
</ins><span class="cx"> 
</span><span class="cx"> importFromV3('instrumentation.js', 'Instrumentation');
</span><span class="cx"> 
</span><span class="lines">@@ -30,6 +34,8 @@
</span><span class="cx">     AnalysisTask.clearStaticMap();
</span><span class="cx">     CommitLog.clearStaticMap();
</span><span class="cx">     RootSet.clearStaticMap();
</span><ins>+    TestGroup.clearStaticMap();
+    BuildRequest.clearStaticMap();
</ins><span class="cx"> 
</span><span class="cx">     global.osx = Repository.ensureSingleton(9, {name: 'OS X'});
</span><span class="cx">     global.webkit = Repository.ensureSingleton(11, {name: 'WebKit', url: 'http://trac.webkit.org/changeset/$1'});
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgunitteststestgroupstestsjs"></a>
<div class="addfile"><h4>Added: trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js (0 => 198598)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js                                (rev 0)
+++ trunk/Websites/perf.webkit.org/unit-tests/test-groups-tests.js        2016-03-23 21:55:55 UTC (rev 198598)
</span><span class="lines">@@ -0,0 +1,314 @@
</span><ins>+'use strict';
+
+var assert = require('assert');
+
+require('./resources/v3-models.js');
+
+function sampleTestGroup() {
+    return {
+        &quot;testGroups&quot;: [{
+            &quot;id&quot;: &quot;2128&quot;,
+            &quot;task&quot;: &quot;1376&quot;,
+            &quot;name&quot;: &quot;Confirm&quot;,
+            &quot;author&quot;: &quot;rniwa&quot;,
+            &quot;createdAt&quot;: 1458688514000,
+            &quot;hidden&quot;: false,
+            &quot;buildRequests&quot;: [&quot;16985&quot;, &quot;16986&quot;, &quot;16987&quot;, &quot;16988&quot;, &quot;16989&quot;, &quot;16990&quot;, &quot;16991&quot;, &quot;16992&quot;],
+            &quot;rootSets&quot;: [&quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;, &quot;4255&quot;, &quot;4256&quot;]
+        }
+        ],
+        &quot;buildRequests&quot;: [{
+            &quot;id&quot;: &quot;16985&quot;,
+            &quot;triggerable&quot;: &quot;3&quot;,
+            &quot;test&quot;: &quot;844&quot;,
+            &quot;platform&quot;: &quot;31&quot;,
+            &quot;testGroup&quot;: &quot;2128&quot;,
+            &quot;order&quot;: &quot;0&quot;,
+            &quot;rootSet&quot;: &quot;4255&quot;,
+            &quot;status&quot;: &quot;pending&quot;,
+            &quot;url&quot;: null,
+            &quot;build&quot;: null,
+            &quot;createdAt&quot;: 1458688514000
+        }, {
+            &quot;id&quot;: &quot;16986&quot;,
+            &quot;triggerable&quot;: &quot;3&quot;,
+            &quot;test&quot;: &quot;844&quot;,
+            &quot;platform&quot;: &quot;31&quot;,
+            &quot;testGroup&quot;: &quot;2128&quot;,
+            &quot;order&quot;: &quot;1&quot;,
+            &quot;rootSet&quot;: &quot;4256&quot;,
+            &quot;status&quot;: &quot;pending&quot;,
+            &quot;url&quot;: null,
+            &quot;build&quot;: null,
+            &quot;createdAt&quot;: 1458688514000
+        },
+        {
+            &quot;id&quot;: &quot;16987&quot;,
+            &quot;triggerable&quot;: &quot;3&quot;,
+            &quot;test&quot;: &quot;844&quot;,
+            &quot;platform&quot;: &quot;31&quot;,
+            &quot;testGroup&quot;: &quot;2128&quot;,
+            &quot;order&quot;: &quot;2&quot;,
+            &quot;rootSet&quot;: &quot;4255&quot;,
+            &quot;status&quot;: &quot;pending&quot;,
+            &quot;url&quot;: null,
+            &quot;build&quot;: null,
+            &quot;createdAt&quot;: 1458688514000
+        }, {
+            &quot;id&quot;: &quot;16988&quot;,
+            &quot;triggerable&quot;: &quot;3&quot;,
+            &quot;test&quot;: &quot;844&quot;,
+            &quot;platform&quot;: &quot;31&quot;,
+            &quot;testGroup&quot;: &quot;2128&quot;,
+            &quot;order&quot;: &quot;3&quot;,
+            &quot;rootSet&quot;: &quot;4256&quot;,
+            &quot;status&quot;: &quot;pending&quot;,
+            &quot;url&quot;: null,
+            &quot;build&quot;: null,
+            &quot;createdAt&quot;: 1458688514000
+        }
+        ],
+        &quot;rootSets&quot;: [{
+            &quot;id&quot;: &quot;4255&quot;,
+            &quot;roots&quot;: [&quot;87832&quot;, &quot;93116&quot;]
+        }, {
+            &quot;id&quot;: &quot;4256&quot;,
+            &quot;roots&quot;: [&quot;87832&quot;, &quot;96336&quot;]
+        }
+        ],
+        &quot;roots&quot;: [{
+            &quot;id&quot;: &quot;87832&quot;,
+            &quot;repository&quot;: &quot;9&quot;,
+            &quot;revision&quot;: &quot;10.11 15A284&quot;,
+            &quot;time&quot;: 0
+        }, {
+            &quot;id&quot;: &quot;93116&quot;,
+            &quot;repository&quot;: &quot;11&quot;,
+            &quot;revision&quot;: &quot;191622&quot;,
+            &quot;time&quot;: 1445945816878
+        }, {
+            &quot;id&quot;: &quot;87832&quot;,
+            &quot;repository&quot;: &quot;9&quot;,
+            &quot;revision&quot;: &quot;10.11 15A284&quot;,
+            &quot;time&quot;: 0
+        }, {
+            &quot;id&quot;: &quot;96336&quot;,
+            &quot;repository&quot;: &quot;11&quot;,
+            &quot;revision&quot;: &quot;192736&quot;,
+            &quot;time&quot;: 1448225325650
+        }
+        ],
+        &quot;status&quot;: &quot;OK&quot;
+    };
+}
+
+describe('TestGroup', function () {
+
+    describe('_createModelsFromFetchedTestGroups', function () {
+        it('should create test groups', function () {
+            var groups = TestGroup._createModelsFromFetchedTestGroups(sampleTestGroup());
+            assert.equal(groups.length, 1);
+
+            var group = groups[0];
+            assert.ok(group instanceof TestGroup);
+            assert.equal(group.id(), 2128);
+            assert.ok(group.createdAt() instanceof Date);
+            assert.equal(group.isHidden(), false);
+            assert.equal(+group.createdAt(), 1458688514000);
+            assert.equal(group.repetitionCount(), sampleTestGroup()['buildRequests'].length / 2);
+            assert.ok(group.hasPending());
+            assert.ok(!group.hasFinished());
+            assert.ok(!group.hasStarted());
+        });
+
+        it('should not create a new instance of TestGroup object if there is a matching entry', function () {
+            var firstObject = TestGroup._createModelsFromFetchedTestGroups(sampleTestGroup())[0];
+            assert.ok(firstObject instanceof TestGroup);
+            assert.equal(TestGroup._createModelsFromFetchedTestGroups(sampleTestGroup())[0], firstObject);
+        });
+
+        it('should create build requests for each group', function () {
+            var groups = TestGroup._createModelsFromFetchedTestGroups(sampleTestGroup());
+            assert.equal(groups.length, 1);
+            assert.equal(groups[0].buildRequests().length, sampleTestGroup()['buildRequests'].length);
+
+            var buildRequests = groups[0].buildRequests();
+            assert.equal(buildRequests[0].id(), 16985);
+            assert.equal(buildRequests[0].order(), 0);
+            assert.ok(!buildRequests[0].hasFinished());
+            assert.ok(!buildRequests[0].hasStarted());
+            assert.ok(buildRequests[0].hasPending());
+            assert.equal(buildRequests[0].statusLabel(), 'Waiting to be scheduled');
+            assert.equal(buildRequests[0].buildId(), null);
+            assert.equal(buildRequests[0].result(), null);
+
+            assert.equal(buildRequests[1].id(), 16986);
+            assert.equal(buildRequests[1].order(), 1);
+            assert.ok(!buildRequests[1].hasFinished());
+            assert.ok(!buildRequests[1].hasStarted());
+            assert.ok(buildRequests[1].hasPending());
+            assert.equal(buildRequests[1].statusLabel(), 'Waiting to be scheduled');
+            assert.equal(buildRequests[1].buildId(), null);
+            assert.equal(buildRequests[1].result(), null);
+        });
+
+        it('should create root sets for each group', function () {
+            var buildRequests = TestGroup._createModelsFromFetchedTestGroups(sampleTestGroup())[0].buildRequests();
+
+            var firstSet = buildRequests[0].rootSet();
+            assert.ok(firstSet instanceof RootSet);
+            assert.equal(firstSet, buildRequests[2].rootSet());
+
+            var secondSet = buildRequests[1].rootSet();
+            assert.ok(secondSet instanceof RootSet);
+            assert.equal(secondSet, buildRequests[3].rootSet());
+
+            assert.equal(firstSet.revisionForRepository(webkit), '191622');
+            var firstWebKitCommit = firstSet.commitForRepository(webkit);
+            assert.ok(firstWebKitCommit instanceof CommitLog);
+            assert.ok(firstWebKitCommit, buildRequests[2].rootSet().commitForRepository(webkit));
+            assert.ok(firstWebKitCommit.repository(), webkit);
+            assert.ok(firstWebKitCommit.revision(), '191622');
+            assert.ok(firstWebKitCommit.time() instanceof Date);
+            assert.ok(+firstWebKitCommit.time(), 1445945816878);
+
+            assert.equal(secondSet.revisionForRepository(webkit), '192736');
+            var secondWebKitCommit = secondSet.commitForRepository(webkit);
+            assert.ok(secondWebKitCommit instanceof CommitLog);
+            assert.ok(secondWebKitCommit, buildRequests[3].rootSet().commitForRepository(webkit));
+            assert.ok(secondWebKitCommit.repository(), webkit);
+            assert.ok(secondWebKitCommit.revision(), '192736');
+            assert.ok(secondWebKitCommit.time() instanceof Date);
+            assert.ok(+secondWebKitCommit.time(), 1445945816878);
+
+            assert.equal(firstSet.revisionForRepository(osx), '10.11 15A284');
+            var osxCommit = firstSet.commitForRepository(osx);
+            assert.ok(osxCommit instanceof CommitLog);
+            assert.equal(osxCommit, buildRequests[1].rootSet().commitForRepository(osx));
+            assert.equal(osxCommit, buildRequests[2].rootSet().commitForRepository(osx));
+            assert.equal(osxCommit, buildRequests[3].rootSet().commitForRepository(osx));
+            assert.ok(osxCommit.repository(), osx);
+            assert.ok(osxCommit.revision(), '10.11 15A284');
+        });
+    });
+
+    function testGroupWithStatusList(list) {
+        var data = sampleTestGroup();
+        data.buildRequests[0].status = list[0];
+        data.buildRequests[1].status = list[1];
+        data.buildRequests[2].status = list[2];
+        data.buildRequests[3].status = list[3];
+        return TestGroup._createModelsFromFetchedTestGroups(data)[0];
+    }
+
+    describe('hasFinished', function () {
+        it('should return true if all build requests have completed', function () {
+            assert.ok(testGroupWithStatusList(['completed', 'completed', 'completed', 'completed']).hasFinished());
+        });
+
+        it('should return true if all build requests have failed', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'failed', 'failed', 'failed']).hasFinished());
+        });
+
+        it('should return true if all build requests have been canceled', function () {
+            assert.ok(testGroupWithStatusList(['canceled', 'canceled', 'canceled', 'canceled']).hasFinished());
+        });
+
+        it('should return true if all build requests have completed or failed', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'completed', 'failed', 'failed']).hasFinished());
+        });
+
+        it('should return true if all build requests have completed, failed, or canceled', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'completed', 'canceled', 'canceled']).hasFinished());
+        });
+
+        it('should return false if all build requests are pending', function () {
+            assert.ok(!testGroupWithStatusList(['pending', 'pending', 'pending', 'pending']).hasFinished());
+        });
+
+        it('should return false if some build requests are pending', function () {
+            assert.ok(!testGroupWithStatusList(['completed', 'completed', 'completed', 'pending']).hasFinished());
+        });
+
+        it('should return false if some build requests are scheduled', function () {
+            assert.ok(!testGroupWithStatusList(['completed', 'completed', 'completed', 'scheduled']).hasFinished());
+        });
+
+        it('should return false if some build requests are running', function () {
+            assert.ok(!testGroupWithStatusList(['completed', 'canceled', 'completed', 'running']).hasFinished());
+        });
+    });
+
+    describe('hasStarted', function () {
+        it('should return true if all build requests have completed', function () {
+            assert.ok(testGroupWithStatusList(['completed', 'completed', 'completed', 'completed']).hasStarted());
+        });
+
+        it('should return true if all build requests have failed', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'failed', 'failed', 'failed']).hasStarted());
+        });
+
+        it('should return true if all build requests have been canceled', function () {
+            assert.ok(testGroupWithStatusList(['canceled', 'canceled', 'canceled', 'canceled']).hasStarted());
+        });
+
+        it('should return true if all build requests have completed or failed', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'completed', 'failed', 'failed']).hasStarted());
+        });
+
+        it('should return true if all build requests have completed, failed, or cancled', function () {
+            assert.ok(testGroupWithStatusList(['failed', 'completed', 'canceled', 'canceled']).hasStarted());
+        });
+
+        it('should return false if all build requests are pending', function () {
+            assert.ok(!testGroupWithStatusList(['pending', 'pending', 'pending', 'pending']).hasStarted());
+        });
+
+        it('should return true if some build requests have completed', function () {
+            assert.ok(testGroupWithStatusList(['completed', 'pending', 'pending', 'pending']).hasStarted());
+        });
+
+        it('should return true if some build requests are scheduled', function () {
+            assert.ok(testGroupWithStatusList(['scheduled', 'pending', 'pending', 'pending']).hasStarted());
+        });
+
+        it('should return true if some build requests are running', function () {
+            assert.ok(testGroupWithStatusList(['running', 'pending', 'pending', 'pending']).hasStarted());
+        });
+    });
+
+    describe('hasPending', function () {
+        it('should return false if all build requests have completed', function () {
+            assert.ok(!testGroupWithStatusList(['completed', 'completed', 'completed', 'completed']).hasPending());
+        });
+
+        it('should return false if all build requests have failed', function () {
+            assert.ok(!testGroupWithStatusList(['failed', 'failed', 'failed', 'failed']).hasPending());
+        });
+
+        it('should return false if all build requests have been canceled', function () {
+            assert.ok(!testGroupWithStatusList(['canceled', 'canceled', 'canceled', 'canceled']).hasPending());
+        });
+
+        it('should return false if all build requests have completed or failed', function () {
+            assert.ok(!testGroupWithStatusList(['failed', 'completed', 'failed', 'failed']).hasPending());
+        });
+
+        it('should return false if all build requests have completed, failed, or cancled', function () {
+            assert.ok(!testGroupWithStatusList(['failed', 'completed', 'canceled', 'canceled']).hasPending());
+        });
+
+        it('should return true if all build requests are pending', function () {
+            assert.ok(testGroupWithStatusList(['pending', 'pending', 'pending', 'pending']).hasPending());
+        });
+
+        it('should return true if some build requests are pending', function () {
+            assert.ok(testGroupWithStatusList(['completed', 'failed', 'canceled', 'pending']).hasPending());
+        });
+
+        it('should return false if some build requests are scheduled and others have completed', function () {
+            assert.ok(!testGroupWithStatusList(['completed', 'completed', 'completed', 'scheduled']).hasPending());
+        });
+    });
+
+});
</ins><span class="cx">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>