Merge lp:~methanal-developers/methanal/coerce-MockHTMLSelectElement-value into lp:methanal

Proposed by Jonathan Jacobs
Status: Merged
Approved by: Tristan Seligmann
Approved revision: 145
Merged at revision: 147
Proposed branch: lp:~methanal-developers/methanal/coerce-MockHTMLSelectElement-value
Merge into: lp:methanal
Diff against target: 183 lines (+129/-4)
3 files modified
methanal/js/Methanal/Tests/MockBrowser.js (+79/-0)
methanal/js/Methanal/Tests/TestView.js (+3/-4)
methanal/js/Methanal/Tests/Util.js (+47/-0)
To merge this branch: bzr merge lp:~methanal-developers/methanal/coerce-MockHTMLSelectElement-value
Reviewer Review Type Date Requested Status
Tristan Seligmann Approve
Review via email: mp+29864@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Tristan Seligmann (mithrandi) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'methanal/js/Methanal/Tests/MockBrowser.js'
2--- methanal/js/Methanal/Tests/MockBrowser.js 2010-01-09 13:29:56 +0000
3+++ methanal/js/Methanal/Tests/MockBrowser.js 2010-07-14 12:14:42 +0000
4@@ -31,6 +31,17 @@
5
6 /**
7 * HTMLSelectElement mock implementation.
8+ *
9+ * Assigning to the C{'value'} attribute tries to follow the behaviour of HTML5
10+ * (which is generally the behaviour that Firefox (as of 3.6.7) follows too)::
11+ * The value IDL attribute, on getting, must return the value of the first option
12+ * element in the list of options in tree order that has its selectedness set to
13+ * true, if any. If there isn't one, then it must return the empty string.
14+ *
15+ * On setting, the value attribute must set the selectedness of all the option
16+ * elements in the list of options to false, and then first the option element in
17+ * the list of options, in tree order, whose value is equal to the given new
18+ * value, if any, must have its selectedness set to true.
19 */
20 Methanal.Tests.MockBrowser.Element.subclass(
21 Methanal.Tests.MockBrowser, 'MockHTMLSelectElement').methods(
22@@ -38,6 +49,29 @@
23 Methanal.Tests.MockBrowser.MockHTMLSelectElement.upcall(
24 self, '__init__', 'select');
25 self.options = [];
26+
27+ Methanal.Tests.Util.defineGetter(self, 'value', function () {
28+ for (var i = 0; i < self.options.length; ++i) {
29+ var option = self.options[i];
30+ if (option.selected) {
31+ return option.value;
32+ }
33+ }
34+ return '';
35+ });
36+
37+ Methanal.Tests.Util.defineSetter(self, 'value', function (v) {
38+ var found = false;
39+ for (var i = 0; i < self.options.length; ++i) {
40+ var option = self.options[i];
41+ if (found === false && v == option.value) {
42+ option.selected = true;
43+ found = true;
44+ } else {
45+ option.selected = false;
46+ }
47+ }
48+ });
49 },
50
51
52@@ -58,6 +92,49 @@
53
54
55 /**
56+ * HTMLOptionElement mock implementation.
57+ *
58+ * Assignments to the C{'value'} attribute try to follow the behaviour of
59+ * Firefox (as of 3.6.7), generally this means the value is coerced to a
60+ * C{String}.
61+ */
62+Methanal.Tests.MockBrowser.Element.subclass(
63+ Methanal.Tests.MockBrowser, 'MockHTMLOptionElement').methods(
64+ function __init__(self) {
65+ Methanal.Tests.MockBrowser.MockHTMLOptionElement.upcall(
66+ self, '__init__', 'option');
67+ self.selected = false;
68+ self._value = '';
69+
70+ Methanal.Tests.Util.defineGetter(self, 'value', function () {
71+ return self._value;
72+ });
73+
74+ Methanal.Tests.Util.defineSetter(self, 'value', function (v) {
75+ if (v === undefined) {
76+ /* Seriously, this is real (Firefox 3.6.7):
77+ * >>> o
78+ * <option value="">
79+ * >>> o.value = undefined;
80+ * >>> o.value
81+ * "undefined"
82+ * >>> o.value = null;
83+ * >>> o.value
84+ * ""
85+ */
86+ v = 'undefined';
87+ } else if (v === null) {
88+ v = '';
89+ } else {
90+ v = v.toString();
91+ }
92+ self._value = v;
93+ });
94+ });
95+
96+
97+
98+/**
99 * HTMLTableRowElement mock implementation.
100 */
101 Methanal.Tests.MockBrowser.Element.subclass(
102@@ -191,6 +268,8 @@
103 document.registerElementTag(
104 'select', Methanal.Tests.MockBrowser.MockHTMLSelectElement);
105 document.registerElementTag(
106+ 'option', Methanal.Tests.MockBrowser.MockHTMLOptionElement);
107+ document.registerElementTag(
108 'table', Methanal.Tests.MockBrowser.MockHTMLTableElement);
109 document.registerElementTag(
110 'thead', Methanal.Tests.MockBrowser.MockHTMLTableSectionElement);
111
112=== modified file 'methanal/js/Methanal/Tests/TestView.js'
113--- methanal/js/Methanal/Tests/TestView.js 2010-07-14 10:13:31 +0000
114+++ methanal/js/Methanal/Tests/TestView.js 2010-07-14 12:14:42 +0000
115@@ -421,10 +421,9 @@
116 control.append(1, 'd2');
117 control.setValue('1');
118 self.assertIdentical(control.inputNode.value, '1');
119- // XXX: This should work, but the mock DOM stuff doesn't coerce
120- // the values of select inputs.
121- //control.setValue(1);
122- //self.assertIdentical(control.inputNode.value, '1');
123+ // Coerce values of select inputs and options.
124+ control.setValue(1);
125+ self.assertIdentical(control.inputNode.value, '1');
126 });
127 },
128
129
130=== modified file 'methanal/js/Methanal/Tests/Util.js'
131--- methanal/js/Methanal/Tests/Util.js 2010-07-02 20:46:39 +0000
132+++ methanal/js/Methanal/Tests/Util.js 2010-07-14 12:14:42 +0000
133@@ -63,3 +63,50 @@
134 form.node.appendChild(actions.node);
135 document.body.appendChild(form.node);
136 };
137+
138+
139+
140+/**
141+ * Create an accessor descriptor for a setter or getter property.
142+ */
143+Methanal.Tests.Util.accessorDescriptor =
144+function accessorDescriptor(field, fun) {
145+ var desc = {
146+ enumerable: true,
147+ configurable: true};
148+ desc[field] = fun;
149+ return desc;
150+}
151+
152+
153+
154+/**
155+ * Define a getter property for an attribute named C{prop} on C{obj} with the
156+ * function C{get}.
157+ */
158+Methanal.Tests.Util.defineGetter = function defineGetter(obj, prop, get) {
159+ if (Object.defineProperty) {
160+ return Object.defineProperty(
161+ obj, prop, Methanal.Tests.Util.accessorDescriptor('get', get));
162+ }
163+ if (Object.prototype.__defineGetter__) {
164+ return obj.__defineGetter__(prop, get);
165+ }
166+ throw new Error('Getter properties not supported!');
167+}
168+
169+
170+/**
171+ * Define a setter property for an attribute named C{prop} on C{obj} with the
172+ * function C{set}.
173+ */
174+Methanal.Tests.Util.defineSetter = function defineSetter(obj, prop, set) {
175+ if (Object.defineProperty) {
176+ return Object.defineProperty(
177+ obj, prop, Methanal.Tests.Util.accessorDescriptor('set', set));
178+ }
179+ if (Object.prototype.__defineSetter__) {
180+ return obj.__defineSetter__(prop, set);
181+ }
182+ throw new Error('Setter properties not supported!');
183+}

Subscribers

People subscribed via source and target branches