Merge lp:~bac/launchpad/productseries-js into lp:launchpad

Proposed by Brad Crittenden
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~bac/launchpad/productseries-js
Merge into: lp:launchpad
Diff against target: 590 lines (+571/-0)
4 files modified
lib/lp/code/javascript/productseries-setbranch.js (+88/-0)
lib/lp/code/javascript/tests/test_productseries-setbranch.html (+213/-0)
lib/lp/code/javascript/tests/test_productseries_setbranch.js (+249/-0)
lib/lp/code/windmill/tests/test_yuitests.py (+21/-0)
To merge this branch: bzr merge lp:~bac/launchpad/productseries-js
Reviewer Review Type Date Requested Status
Curtis Hovey (community) js and code Approve
Review via email: mp+21485@code.launchpad.net

Commit message

Provide javascript to control the behavior on the new productseries/+setbranch page.

Description of the change

= Summary =

While fixing bug 524302 functionality from several pages will be combined to provide
an unified view of branch creation/importing/mirroring. The page needs some JS logic
to control the select enabling of the various fields based on the state of radiobuttons.

This branch provides that JS and the tests for it only.

== Proposed fix ==

Create a new JS module to control the status of the page elements based on the
radiobuttons.

== Pre-implementation notes ==

Long discussions with Curtis during our sprint.

== Implementation details ==

As above.

== Tests ==

Load lib/canonical/launchpad/javascript/registry/tests/productseries-setbranch.html
into a browser and ensure all tests pass.

== Demo and Q/A ==

N/A

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/canonical/launchpad/javascript/registry/tests/productseries-setbranch.html
  lib/canonical/launchpad/javascript/registry/productseries-setbranch.js
  lib/canonical/launchpad/javascript/registry/tests/test_productseries_setbranch.js

== JSLint notices ==
jslint: Lint found in
'/home/bac/canonical/lp-branches/productseries-js/lib/canonical/launchpad/javascript/registry/productseries-setbranch.js':
Line 84 character 22: 'rcs_types' is already defined.
       var rcs_types = module._rcs_types();

jslint: No problem found in
'/home/bac/canonical/lp-branches/productseries-js/lib/canonical/launchpad/javascript/registry/tests/test_productseries_setbranch.js'.

jslint: 2 files to lint.

I'll take care of these lint issues before landing.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :
Download full text (9.9 KiB)

This is a very good start Brad. I have some concerns about using the underlying js engine. I
have some proposals that use YUI to minimise engine problems. There are some style issue I think
need fixing too. The test is very nice, and it will prove useful when refactoring some of this
library.

> === added file 'lib/canonical/launchpad/javascript/registry/productseries-setbranch.js'
> --- lib/canonical/launchpad/javascript/registry/productseries-setbranch.js 1970-01-01 00:00:00 +0000
> +++ lib/canonical/launchpad/javascript/registry/productseries-setbranch.js 2010-03-16 20:32:39 +0000
> @@ -0,0 +1,93 @@
> +/* Copyright 2010 Canonical Ltd. This software is licensed under the
> + * GNU Affero General Public License version 3 (see the file LICENSE).
> + *
> + * Control enabling/disabling of complex form on the
> + * productseries/+setbranch page.
> + *
> + * @module Y.registry.productseries_setbranch
> + * @requires node
> + */

This module require DOM too.

Is registry the correct location for this script? I think the code module
may be better. Consider a project that will never have code/branches; this
code will never be used. I think the code and bug configurations belong in
their respective apps. My test for placing code in registry is to ask
what happens if the app is removed? If we remove Launchpad Code, this
script would have to be removed in a separate effort.

> +YUI.add('registry.productseries_setbranch', function(Y) {
> + Y.log('loading registry.productseries_setbranch');
> + var module = Y.namespace('registry.productseries_setbranch');
> +
> + module._getSelectedRCS = function() {

We use PEP 8 for function and method names. These names should be lower
case with underscores. When you see someone setting a module method with
studlyCaps, it is probably because that method is defined in a prototype
or event.

Review all your method names.

> + var rcs_types = module._rcs_types();
> + var selected = 'None';
> + for (var i = 0; i < rcs_types.length; i++) {
> + if (rcs_types[i].checked) {
> + selected = rcs_types[i].value;
> + break;
> + }
> + }
> + return selected;
> + };
> +
> + module.__rcs_types = null;
> +
> + module._rcs_types = function() {
> + if (module.__rcs_types === null) {
> + module.__rcs_types = document.getElementsByName('field.rcs_type');
> + }
> + return module.__rcs_types;
> + };
> +
> + module.setEnabled = function(field_id, is_enabled) {
> + var field = Y.DOM.byId(field_id);
> + field.disabled = !is_enabled;
> + };
> +
> + module.onclickRcsType = function() {
> + /* Which rcs type radio button has been selected? */
> + // CVS
> + var rcs_types = module._rcs_types();
> + var selectedRCS = module._getSelectedRCS();
> + module.setEnabled('field.cvs_module', selectedRCS == 'CVS');
> + };

Event handler functions receive an event argument, traditionally named 'e'

    module.onclick_rcs_type = function(e) {

You need to update all of these methods, though you are not required to
use e, so no other changes are needed.

> + module.onclickBranchType = f...

review: Needs Fixing (js)
Revision history for this message
Brad Crittenden (bac) wrote :

Thanks for the review Curtis and your help with the testing issues.

I've incorporated all of your suggestions, cleaned up the testing, and added support for two new fields: branch_name and branch_owner.

Incremental diff at http://pastebin.ubuntu.com/397846/

Revision history for this message
Curtis Hovey (sinzui) wrote :

This looks good to land, but I ask that you refrain until YUI unittests run automatically.

> === renamed file 'lib/canonical/launchpad/javascript/registry/productseries-setbranch.js' => 'lib/canonical/launchpad/javascript/code/productseries-setbranch.js'
> --- lib/canonical/launchpad/javascript/registry/productseries-setbranch.js 2010-03-15 21:13:23 +0000
> +++ lib/canonical/launchpad/javascript/code/productseries-setbranch.js 2010-03-19 13:35:15 +0000
...
> + module.setup = function() {
> + Y.all('input[name=field.rcs_type]').each(function(field) {
> + field.on('click', module.onclick_rcs_type);});
> + Y.all('input[name=field.branch_type]').each(function(field) {
> + field.on('click', module.onclick_branch_type);});

I think these could use the ListNode.on() method to make the code a little
easier to read.

        Y.all('input[name=field.rcs_type]').on(
            'click', module.onclick_rcs_type);
        Y.all('input[name=field.branch_type]').on(
            'click', module.onclick_branch_type);
...

> === renamed file 'lib/canonical/launchpad/javascript/registry/tests/test_productseries_setbranch.js' => 'lib/canonical/launchpad/javascript/code/tests/test_productseries_setbranch.js'
> --- lib/canonical/launchpad/javascript/registry/tests/test_productseries_setbranch.js 2010-03-15 21:13:23 +0000
> +++ lib/canonical/launchpad/javascript/code/tests/test_productseries_setbranch.js 2010-03-19 14:29:27 +0000
...
> @@ -48,31 +50,50 @@
>
> tearDown: function() {
> delete this.tbody;
> - },
> + },
>
> test_handlers_connected: function() {
> - Y.Assert.areEqual('onclickBranchType()',
> - this.link_lp_bzr.getAttribute('onclick'),
> - 'branch type onclick handler not correct');
> - Y.Assert.areEqual('onclickBranchType()',
> - this.create_new.getAttribute('onclick'),
> - 'branch type onclick handler not correct');
> - Y.Assert.areEqual('onclickBranchType()',
> - this.import_external.getAttribute('onclick'),
> - 'branch type onclick handler not correct');
> -
> + // Manually invoke the setup function to ensure the handlers are set.+ module.setup();

Wrap the code at 78 characters.
...

@@ -202,7 +234,8 @@
     var console = new Y.Console({newestOnTop: false});
     console.render('#log');

- Y.on('domready', function() {
+ // Start the test runner on Y.after to ensure all setup has had a chance to complete.

Wrap the code at 78 characters.
...

review: Approve (js)
Revision history for this message
Curtis Hovey (sinzui) :
review: Approve (js and code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'lib/lp/code/javascript/productseries-setbranch.js'
2--- lib/lp/code/javascript/productseries-setbranch.js 1970-01-01 00:00:00 +0000
3+++ lib/lp/code/javascript/productseries-setbranch.js 2010-04-05 23:04:33 +0000
4@@ -0,0 +1,88 @@
5+/* Copyright 2010 Canonical Ltd. This software is licensed under the
6+ * GNU Affero General Public License version 3 (see the file LICENSE).
7+ *
8+ * Control enabling/disabling of complex form on the
9+ * productseries/+setbranch page.
10+ *
11+ * @module Y.lp.code.productseries_setbranch
12+ * @requires node, DOM
13+ */
14+YUI.add('lp.code.productseries_setbranch', function(Y) {
15+ Y.log('loading lp.code.productseries_setbranch');
16+ var module = Y.namespace('lp.code.productseries_setbranch');
17+
18+ module._get_selected_rcs = function() {
19+ var rcs_types = module._rcs_types();
20+ var selected = 'None';
21+ for (var i = 0; i < rcs_types.length; i++) {
22+ if (rcs_types[i].checked) {
23+ selected = rcs_types[i].value;
24+ break;
25+ }
26+ }
27+ return selected;
28+ };
29+
30+
31+ module.__rcs_types = null;
32+
33+ module._rcs_types = function() {
34+ if (module.__rcs_types === null) {
35+ module.__rcs_types = document.getElementsByName('field.rcs_type');
36+ }
37+ return module.__rcs_types;
38+ };
39+
40+ module.set_enabled = function(field_id, is_enabled) {
41+ var field = Y.DOM.byId(field_id);
42+ field.disabled = !is_enabled;
43+ };
44+
45+ module.onclick_rcs_type = function(e) {
46+ /* Which rcs type radio button has been selected? */
47+ // CVS
48+ var rcs_types = module._rcs_types();
49+ var selectedRCS = module._get_selected_rcs();
50+ module.set_enabled('field.cvs_module', selectedRCS == 'CVS');
51+ };
52+
53+ module.onclick_branch_type = function(e) {
54+ /* Which branch type radio button was selected? */
55+ var selectedRCS = module._get_selected_rcs();
56+ var types = document.getElementsByName('field.branch_type');
57+ var type = 'None';
58+ for (var i = 0; i < types.length; i++) {
59+ if (types[i].checked) {
60+ type = types[i].value;
61+ break;
62+ }
63+ }
64+ // Linked
65+ module.set_enabled('field.branch_location', type == 'link-lp-bzr');
66+ module.set_enabled('field.branch_name', type != 'link-lp-bzr');
67+ module.set_enabled('field.branch_owner', type != 'link-lp-bzr');
68+ // New, empty branch.
69+ // Import
70+ var is_external = (type == 'import-external');
71+ module.set_enabled('field.repo_url', is_external);
72+ module.set_enabled('field.cvs_module',
73+ (is_external & selectedRCS == 'CVS'));
74+ var rcs_types = module._rcs_types();
75+ for (var j = 0; j < rcs_types.length; j++) {
76+ rcs_types[j].disabled = !is_external;
77+ }
78+ };
79+
80+ module.setup = function() {
81+ Y.all('input[name=field.rcs_type]').on(
82+ 'click', module.onclick_rcs_type);
83+ Y.all('input[name=field.branch_type]').on(
84+ 'click', module.onclick_branch_type);
85+
86+ // Set the initial state.
87+ module.onclick_rcs_type();
88+ module.onclick_branch_type();
89+ };
90+
91+ }, "0.1", {"requires": ["node", "DOM"]}
92+);
93
94=== added file 'lib/lp/code/javascript/tests/test_productseries-setbranch.html'
95--- lib/lp/code/javascript/tests/test_productseries-setbranch.html 1970-01-01 00:00:00 +0000
96+++ lib/lp/code/javascript/tests/test_productseries-setbranch.html 2010-04-05 23:04:33 +0000
97@@ -0,0 +1,213 @@
98+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
99+
100+<html>
101+ <head>
102+ <title>stroppy trunk series : Series trunk : stroppy</title>
103+
104+ <!-- YUI 3.0 Setup -->
105+ <script type="text/javascript" src="../../../../canonical/launchpad/icing/yui/yui/yui.js"></script>
106+ <script type="text/javascript" src="../../../../canonical/launchpad/icing/lazr/build/lazr.js"></script>
107+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssreset/reset.css"/>
108+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssfonts/fonts.css"/>
109+ <link rel="stylesheet" href="../../../../canonical/launchpad/icing/yui/cssbase/base.css"/>
110+ <link rel="stylesheet" href="../../../../canonical/launchpad/javascript/test.css" />
111+ <script type="text/javascript" src="../../../../canonical/launchpad/lp/lp.js"></script>
112+
113+ <!-- The module under test -->
114+ <script type="text/javascript" src="../productseries-setbranch.js"></script>
115+ <script type="text/javascript">
116+ YUI().use('lp.code.productseries_setbranch', function(Y) {
117+ Y.on('domready', Y.lp.code.productseries_setbranch.setup);
118+ });
119+ </script>
120+
121+ <!-- The test suite -->
122+ <script type="text/javascript" src="test_productseries_setbranch.js"></script>
123+ </head>
124+
125+<body class="yui-skin-sam">
126+ <div id="productseries-setbranch">
127+ <form action="." name="launchpadform" method="post"
128+ enctype="multipart/form-data"
129+ accept-charset="UTF-8">
130+
131+ <table class="form">
132+ <tbody>
133+ <tr>
134+ <td>
135+ <label>
136+ <input class="radioType" checked="checked"
137+ id="field.branch_type.0"
138+ name="field.branch_type" type="radio" value="link-lp-bzr">
139+ Link to a Bazaar branch already in Launchpad
140+ </label>
141+ <table>
142+ <tbody>
143+ <tr>
144+ <td colspan="2">
145+ <label for="field.branch_location">Branch:</label>
146+ <span class="fieldRequired">(Optional)</span>
147+ <div>
148+ <input type="text" value="" id="field.branch_location"
149+ name="field.branch_location" size="35">
150+
151+ </div>
152+ <p class="formHelp">The Bazaar branch for this series in
153+ Launchpad, if one exists.</p>
154+ </td>
155+ </tr>
156+ </tbody>
157+ </table>
158+ </td>
159+ </tr>
160+
161+ <tr>
162+ <td>
163+ <label>
164+ <input class="radioType" id="field.branch_type.1"
165+ name="field.branch_type"
166+ type="radio" value="create-new">
167+ Create a new, empty branch in Launchpad and link
168+ to this series
169+ </label>
170+ </td>
171+ </tr>
172+
173+ <tr>
174+ <td>
175+ <label>
176+ <input class="radioType" id="field.branch_type.2"
177+ name="field.branch_type" type="radio"
178+ value="import-external">
179+ Import a branch hosted somewhere else
180+ </label>
181+ <table>
182+ <tbody>
183+ <tr>
184+ <td colspan="2">
185+ <label for="field.repo_url">Branch URL:</label>
186+ <span class="fieldRequired">(Optional)</span>
187+ <div>
188+ <input class="urlTextType textType" id="field.repo_url"
189+ name="field.repo_url" size="44" type="text"
190+ value="" disabled="">
191+ </div>
192+ </td>
193+ </tr>
194+
195+ <tr>
196+ <td>
197+ <label>
198+ <input class="radioType" id="field.rcs_type.6"
199+ name="field.rcs_type" type="radio" value="BZR"
200+ disabled="">
201+ Bazaar, hosted externally
202+ </label>
203+ </td>
204+ </tr>
205+
206+ <tr>
207+ <td>
208+ <label>
209+ <input class="radioType" id="field.rcs_type.4"
210+ name="field.rcs_type" type="radio" value="GIT"
211+ disabled="">
212+ Git
213+ </label>
214+ </td>
215+ </tr>
216+
217+ <tr>
218+ <td>
219+ <label>
220+ <input class="radioType" id="field.rcs_type.3"
221+ name="field.rcs_type" type="radio"
222+ value="BZR_SVN" disabled="">
223+ SVN
224+ </label>
225+ </td>
226+ </tr>
227+
228+ <tr>
229+ <td>
230+ <label>
231+ <input class="radioType" id="field.rcs_type.5"
232+ name="field.rcs_type" type="radio" value="HG" disabled="">
233+ Mercurial
234+ </label>
235+ </td>
236+ </tr>
237+
238+ <tr>
239+ <td>
240+ <label>
241+ <input class="radioType" id="field.rcs_type.1"
242+ name="field.rcs_type" type="radio" value="CVS"
243+ disabled="">
244+ CVS
245+ </label>
246+
247+ <table>
248+ <tbody>
249+ <tr>
250+ <td colspan="2">
251+ <label for="field.cvs_module">Module:</label>
252+ <span class="fieldRequired">(Optional)</span>
253+
254+ <div>
255+ <input class="textType" id="field.cvs_module"
256+ name="field.cvs_module" size="20"
257+ type="text"
258+ value="" disabled="">
259+ </div>
260+ </td>
261+ </tr>
262+ </tbody>
263+ </table>
264+ </td>
265+ </tr>
266+ </tbody>
267+ </table>
268+ </td>
269+ </tr>
270+
271+ <tr>
272+ <td colspan="2">
273+ <label for="field.branch_name">Branch name:</label>
274+ <div>
275+ <input class="textType" id="field.branch_name" name="field.branch_name" size="20" type="text" value="" />
276+ </div>
277+ </td>
278+ </tr>
279+
280+ <tr>
281+ <td colspan="2">
282+ <label for="field.branch_owner">Branch owner:</label>
283+ <div>
284+ <div class="value">
285+ <select id="field.branch_owner" name="field.branch_owner" size="1" >
286+ <option value="mark">Mark Shuttleworth (mark)</option>
287+ <option value="guadamen">GuadaMen (guadamen)</option>
288+ <option value="hwdb-team">HWDB Team (hwdb-team)</option>
289+ <option value="admins">Launchpad Administrators (admins)</option>
290+ <option value="mailing-list-experts">Mailing List Experts (mailing-list-experts)</option>
291+ <option value="ubuntu-mirror-admins">Mirror Administrators (ubuntu-mirror-admins)</option>
292+ <option value="registry">Registry Administrators (registry)</option>
293+ <option value="testing-spanish-team">testing Spanish team (testing-spanish-team)</option>
294+ <option value="ubuntu-team">Ubuntu Team (ubuntu-team)</option>
295+ </select>
296+ </div>
297+ <input name="field.branch_owner-empty-marker" type="hidden" value="1" />
298+ </div>
299+ </td>
300+ </tr>
301+ </tbody>
302+ </table>
303+ <input type="submit" id="field.actions.update"
304+ name="field.actions.update" value="Update" class="button">
305+ or&nbsp;
306+ <a href="https://launchpad.dev/zyc/trunk">Cancel</a>
307+ </form>
308+ </div>
309+</body>
310+</html>
311
312=== added file 'lib/lp/code/javascript/tests/test_productseries_setbranch.js'
313--- lib/lp/code/javascript/tests/test_productseries_setbranch.js 1970-01-01 00:00:00 +0000
314+++ lib/lp/code/javascript/tests/test_productseries_setbranch.js 2010-04-05 23:04:33 +0000
315@@ -0,0 +1,249 @@
316+/* Copyright 2010 Canonical Ltd. This software is licensed under the
317+ * GNU Affero General Public License version 3 (see the file LICENSE).
318+ *
319+ * Test driver for productseries_setbranch.js.
320+ *
321+ */
322+
323+YUI({
324+ base: '../../../../canonical/launchpad/icing/yui/',
325+ filter: 'raw', combine: false
326+ }).use('node-event-simulate', 'test', 'console', 'Event', 'CustomEvent',
327+ 'lp.code.productseries_setbranch', function(Y) {
328+
329+ var module = Y.lp.code.productseries_setbranch;
330+ var suite = new Y.Test.Suite("productseries_setbranch Tests");
331+
332+ suite.add(new Y.Test.Case({
333+ // Test the onclick results.
334+ name: 'select_branchtype',
335+
336+ _should: {
337+ error: {
338+ //test_config_undefined: true,
339+ //test_missing_tbody_is_an_error: true
340+ }
341+ },
342+
343+ setUp: function() {
344+ this.tbody = Y.one('#productseries-setbranch');
345+
346+ // Get the individual branch type radio buttons.
347+ this.link_lp_bzr = Y.DOM.byId('field.branch_type.0');
348+ this.create_new = Y.DOM.byId('field.branch_type.1');
349+ this.import_external = Y.DOM.byId('field.branch_type.2');
350+
351+ // Get the input widgets.
352+ this.branch_location = Y.DOM.byId('field.branch_location');
353+ this.cvs_module = Y.DOM.byId('field.cvs_module');
354+ this.repo_url = Y.DOM.byId('field.repo_url');
355+ this.branch_name = Y.DOM.byId('field.branch_name');
356+ this.branch_owner = Y.DOM.byId('field.branch_owner');
357+
358+ // Get the individual rcs type radio buttons.
359+ this.cvs = Y.DOM.byId('field.rcs_type.1');
360+ this.svn = Y.DOM.byId('field.rcs_type.3');
361+ this.git = Y.DOM.byId('field.rcs_type.4');
362+ this.hg = Y.DOM.byId('field.rcs_type.5');
363+ this.bzr = Y.DOM.byId('field.rcs_type.6');
364+ },
365+
366+ tearDown: function() {
367+ delete this.tbody;
368+ },
369+
370+ test_handlers_connected: function() {
371+ // Manually invoke the setup function to ensure the handlers are
372+ // set.
373+ module.setup();
374+
375+ var check_handler = function(field, expected) {
376+ var custom_events = Y.Event.getListeners(field, 'click');
377+ var click_event = custom_events[0];
378+ var subscribers = click_event.subscribers;
379+ for (var sub in subscribers) {
380+ Y.Assert.isTrue(subscribers[sub].contains(expected),
381+ 'branch_type_onclick handler setup');
382+ };
383+ };
384+
385+ check_handler(this.link_lp_bzr, module.onclick_branch_type);
386+ check_handler(this.create_new, module.onclick_branch_type);
387+ check_handler(this.import_external, module.onclick_branch_type);
388+
389+ check_handler(this.cvs, module.onclick_rcs_type);
390+ check_handler(this.svn, module.onclick_rcs_type);
391+ check_handler(this.git, module.onclick_rcs_type);
392+ check_handler(this.hg, module.onclick_rcs_type);
393+ check_handler(this.bzr, module.onclick_rcs_type);
394+ },
395+
396+ test_select_link_lp_bzr: function() {
397+ this.link_lp_bzr.checked = true;
398+ module.onclick_branch_type();
399+ // The branch location is enabled.
400+ Y.Assert.isFalse(this.branch_location.disabled,
401+ 'branch_location disabled');
402+ module.onclick_rcs_type();
403+ // The CVS module and repo url are disabled.
404+ Y.Assert.isTrue(this.cvs_module.disabled,
405+ 'cvs_module not disabled');
406+ Y.Assert.isTrue(this.repo_url.disabled,
407+ 'repo_url not disabled');
408+ // The branch name and owner are disabled.
409+ Y.Assert.isTrue(this.branch_name.disabled,
410+ 'branch_name not disabled');
411+ Y.Assert.isTrue(this.branch_owner.disabled,
412+ 'branch_owner not disabled');
413+ // All of the radio buttons are disabled.
414+ Y.Assert.isTrue(this.cvs.disabled,
415+ 'cvs button not disabled');
416+ Y.Assert.isTrue(this.svn.disabled,
417+ 'svn button not disabled');
418+ Y.Assert.isTrue(this.git.disabled,
419+ 'git button not disabled');
420+ Y.Assert.isTrue(this.hg.disabled,
421+ 'hg button not disabled');
422+ Y.Assert.isTrue(this.bzr.disabled,
423+ 'bzr button not disabled');
424+ },
425+
426+ test_select_create_new: function() {
427+ this.create_new.checked = true;
428+ module.onclick_branch_type();
429+ // The branch location is disabled.
430+ Y.Assert.isTrue(this.branch_location.disabled,
431+ 'branch_location not disabled');
432+ module.onclick_rcs_type();
433+ // The CVS module and repo url are disabled.
434+ Y.Assert.isTrue(this.cvs_module.disabled,
435+ 'cvs_module not disabled');
436+ Y.Assert.isTrue(this.repo_url.disabled,
437+ 'repo_url not disabled');
438+ // The branch name and owner are enabled.
439+ Y.Assert.isFalse(this.branch_name.disabled,
440+ 'branch_name disabled');
441+ Y.Assert.isFalse(this.branch_owner.disabled,
442+ 'branch_owner disabled');
443+ // All of the radio buttons are disabled.
444+ Y.Assert.isTrue(this.cvs.disabled,
445+ 'cvs button not disabled');
446+ Y.Assert.isTrue(this.svn.disabled,
447+ 'svn button not disabled');
448+ Y.Assert.isTrue(this.git.disabled,
449+ 'git button not disabled');
450+ Y.Assert.isTrue(this.hg.disabled,
451+ 'hg button not disabled');
452+ Y.Assert.isTrue(this.bzr.disabled,
453+ 'bzr button not disabled');
454+ },
455+
456+ test_select_import_external: function() {
457+ this.import_external.checked = true;
458+ module.onclick_branch_type();
459+ // The branch location is disabled.
460+ Y.Assert.isTrue(this.branch_location.disabled,
461+ 'branch_location not disabled');
462+ // The repo url is enabled.
463+ Y.Assert.isFalse(this.repo_url.disabled,
464+ 'repo_url disabled');
465+ module.onclick_rcs_type();
466+ // The branch name and owner are enabled.
467+ Y.Assert.isFalse(this.branch_name.disabled,
468+ 'branch_name disabled');
469+ Y.Assert.isFalse(this.branch_owner.disabled,
470+ 'branch_owner disabled');
471+ // All of the radio buttons are disabled.
472+ Y.Assert.isFalse(this.cvs.disabled,
473+ 'cvs button disabled');
474+ Y.Assert.isFalse(this.svn.disabled,
475+ 'svn button disabled');
476+ Y.Assert.isFalse(this.git.disabled,
477+ 'git button disabled');
478+ Y.Assert.isFalse(this.hg.disabled,
479+ 'hg button disabled');
480+ Y.Assert.isFalse(this.bzr.disabled,
481+ 'bzr button disabled');
482+
483+ },
484+
485+ test_select_import_external_bzr: function() {
486+ this.import_external.checked = true;
487+ module.onclick_branch_type();
488+ Y.Assert.isFalse(this.repo_url.disabled,
489+ 'repo_url disabled');
490+ this.bzr.checked = true;
491+ module.onclick_rcs_type();
492+ // The CVS module input is disabled.
493+ Y.Assert.isTrue(this.cvs_module.disabled,
494+ 'cvs_module disabled');
495+ },
496+
497+ test_select_import_external_hg: function() {
498+ this.import_external.checked = true;
499+ module.onclick_branch_type();
500+ Y.Assert.isFalse(this.repo_url.disabled,
501+ 'repo_url disabled');
502+ this.hg.checked = true;
503+ module.onclick_rcs_type();
504+ // The CVS module input is disabled.
505+ Y.Assert.isTrue(this.cvs_module.disabled,
506+ 'cvs_module disabled');
507+ },
508+
509+ test_select_import_external_git: function() {
510+ this.import_external.checked = true;
511+ module.onclick_branch_type();
512+ Y.Assert.isFalse(this.repo_url.disabled,
513+ 'repo_url disabled');
514+ this.git.checked = true;
515+ module.onclick_rcs_type();
516+ // The CVS module input is disabled.
517+ Y.Assert.isTrue(this.cvs_module.disabled,
518+ 'cvs_module disabled');
519+ },
520+
521+ test_select_import_external_svn: function() {
522+ this.import_external.checked = true;
523+ module.onclick_branch_type();
524+ Y.Assert.isFalse(this.repo_url.disabled,
525+ 'repo_url disabled');
526+ this.svn.checked = true;
527+ module.onclick_rcs_type();
528+ // The CVS module input is disabled.
529+ Y.Assert.isTrue(this.cvs_module.disabled,
530+ 'cvs_module disabled');
531+ },
532+
533+ test_select_import_external_cvs: function() {
534+ this.import_external.checked = true;
535+ module.onclick_branch_type();
536+ Y.Assert.isFalse(this.repo_url.disabled,
537+ 'repo_url disabled');
538+ this.cvs.checked = true;
539+ module.onclick_rcs_type();
540+ // The CVS module input is enabled
541+ Y.Assert.isFalse(this.cvs_module.disabled,
542+ 'cvs_module disabled');
543+ }
544+
545+ }));
546+
547+ // Lock, stock, and two smoking barrels.
548+ var handle_complete = function(data) {
549+ status_node = Y.Node.create(
550+ '<p id="complete">Test status: complete</p>');
551+ Y.get('body').appendChild(status_node);
552+ };
553+ Y.Test.Runner.on('complete', handle_complete);
554+ Y.Test.Runner.add(suite);
555+
556+ var console = new Y.Console({newestOnTop: false});
557+ console.render('#log');
558+
559+ // Start the test runner on Y.after to ensure all setup has had a
560+ // chance to complete.
561+ Y.after('domready', function() {
562+ Y.Test.Runner.run();
563+ });
564+});
565
566=== added file 'lib/lp/code/windmill/tests/test_yuitests.py'
567--- lib/lp/code/windmill/tests/test_yuitests.py 1970-01-01 00:00:00 +0000
568+++ lib/lp/code/windmill/tests/test_yuitests.py 2010-04-05 23:04:33 +0000
569@@ -0,0 +1,21 @@
570+# Copyright 2010 Canonical Ltd. This software is licensed under the
571+# GNU Affero General Public License version 3 (see the file LICENSE).
572+
573+"""Run YUI.test tests."""
574+
575+__metaclass__ = type
576+__all__ = []
577+
578+from lp.testing import build_yui_unittest_suite, YUIUnitTestCase
579+from lp.code.windmill.testing import CodeWindmillLayer
580+
581+
582+class CodeYUIUnitTestCase(YUIUnitTestCase):
583+
584+ layer = CodeWindmillLayer
585+ suite_name = 'CodeYUIUnitTests'
586+
587+
588+def test_suite():
589+ app_testing_path = 'lp/code/javascript/tests'
590+ return build_yui_unittest_suite(app_testing_path, CodeYUIUnitTestCase)