1 | var test = require('tape');
|
2 | var InputView = require('../ampersand-expanding-textarea-view');
|
3 | var customTemplate = '<label class="custominput"><span data-hook="label"></span><textarea data-hook="input-mirror"></textarea><div contenteditable="true" data-hook="input-primary"></div><div data-hook="message-container"><p data-hook="message-text"></p></div></label>';
|
4 |
|
5 | if (!Function.prototype.bind) Function.prototype.bind = require('function-bind');
|
6 |
|
7 | function isHidden(el) {
|
8 | return el.style.display === 'none';
|
9 | }
|
10 |
|
11 | function hasClass(el, klass) {
|
12 | return el.classList.contains(klass);
|
13 | }
|
14 |
|
15 | test('basic initialization', function (t) {
|
16 | var input = new InputView({
|
17 | name: 'title'
|
18 | });
|
19 | input.render();
|
20 | t.equal(input.el.tagName, 'LABEL');
|
21 | t.equal(input.el.querySelectorAll('textarea').length, 2);
|
22 | t.equal(input.el.querySelector('textarea').getAttribute('name'), 'title');
|
23 | t.end();
|
24 | });
|
25 |
|
26 | test('initialize with value', function (t) {
|
27 | var input = new InputView({
|
28 | name: 'title',
|
29 | value: 'Once upon a time'
|
30 | });
|
31 |
|
32 | input.render();
|
33 |
|
34 | t.equal(input.el.querySelector('textarea').value, 'Once upon a time');
|
35 | t.end();
|
36 | });
|
37 |
|
38 | test('can initialize with template without having to extend', function (t) {
|
39 | var input = new InputView({
|
40 | name: 'title',
|
41 | value: 'Once upon a time',
|
42 | template: customTemplate
|
43 | });
|
44 |
|
45 | input.render();
|
46 |
|
47 | t.equal(input.el.className, 'custominput');
|
48 | t.end();
|
49 | });
|
50 |
|
51 | test('should be able to extend a template as well', function (t) {
|
52 | var input = new (InputView.extend({
|
53 | template: customTemplate
|
54 | }))({name: 'title',
|
55 | value: 'Once upon a time',
|
56 | });
|
57 |
|
58 | input.render();
|
59 |
|
60 | t.equal(input.el.className, 'custominput');
|
61 | t.end();
|
62 |
|
63 | input.render();
|
64 | });
|
65 |
|
66 | test('reset value', function (t) {
|
67 | var input = new InputView({
|
68 | name: 'title'
|
69 | });
|
70 | input.render();
|
71 | input.setValue('something');
|
72 | t.equal(input.input.value, 'something', 'Value should be updated');
|
73 | input.reset();
|
74 | t.equal(input.input.value, '', 'Value should be reset');
|
75 |
|
76 | var input2 = new InputView({
|
77 | name: 'title',
|
78 | value: 'start'
|
79 | });
|
80 | input2.render();
|
81 | t.equal(input2.input.value, 'start', 'Value should be set initially');
|
82 | input2.setValue('somethingelse');
|
83 | t.equal(input2.input.value, 'somethingelse', 'value should be updated');
|
84 | input2.reset();
|
85 | t.equal(input2.input.value, 'start', 'value should have been reset to original');
|
86 |
|
87 | t.end();
|
88 | });
|
89 |
|
90 | test('clear', function (t) {
|
91 | var input = new InputView({
|
92 | name: 'title',
|
93 | value: 'something'
|
94 | });
|
95 | input.render();
|
96 |
|
97 | t.equal(input.input.value, 'something');
|
98 | input.reset();
|
99 | t.equal(input.input.value, 'something', 'reset should do nothing');
|
100 | input.clear();
|
101 | t.equal(input.input.value, '');
|
102 | t.equal(input.value, '');
|
103 |
|
104 | var input2 = new InputView({
|
105 | name: 'thing'
|
106 | });
|
107 | input2.render();
|
108 | t.equal(input2.value, '');
|
109 | input2.setValue('thing');
|
110 | t.equal(input2.input.value, 'thing');
|
111 | t.equal(input2.value, 'thing');
|
112 | input2.clear();
|
113 | t.equal(input2.input.value, '');
|
114 | t.equal(input2.value, '');
|
115 |
|
116 | t.end();
|
117 | });
|
118 |
|
119 | test('initalize with a value of `0`', function(t) {
|
120 | var input = new InputView({
|
121 | name: 'title',
|
122 | type: 'number',
|
123 | value: 0
|
124 | });
|
125 |
|
126 | input.render();
|
127 |
|
128 | t.equal(parseFloat(input.el.querySelector('textarea').value), 0);
|
129 | t.end();
|
130 | });
|
131 |
|
132 | test('Tests with required true and false', function (t) {
|
133 | var inputs = [
|
134 | new InputView({
|
135 | name: 'title',
|
136 | required: true,
|
137 | tests: [
|
138 | function (val) {
|
139 | if (val.length < 5) return 'Must be 5+ characters.';
|
140 | }
|
141 | ]
|
142 | }),
|
143 | new InputView({
|
144 | name: 'title',
|
145 | required: false,
|
146 | tests: [
|
147 | function (val) {
|
148 | if (val.length < 5) return 'Must be 5+ characters.';
|
149 | }
|
150 | ]
|
151 | }),
|
152 | ];
|
153 |
|
154 | inputs.forEach(function (input) {
|
155 | input.render();
|
156 |
|
157 | var inputElement = input.el.querySelector('textarea');
|
158 | var messageContainer = input.el.querySelector('[data-hook=message-container]');
|
159 |
|
160 |
|
161 |
|
162 | inputElement.value = 'O';
|
163 | input.handleInputChanged();
|
164 |
|
165 |
|
166 | t.notOk(input.valid, 'Input should be invalid');
|
167 | t.ok(isHidden(messageContainer), 'Message should not be visible');
|
168 | t.notOk(hasClass(inputElement, 'input-invalid'), 'Does not have invalid class');
|
169 | t.notOk(hasClass(inputElement, 'input-valid'), 'Doest not have valid class');
|
170 |
|
171 |
|
172 | inputElement.value = '';
|
173 | input.handleInputChanged();
|
174 |
|
175 |
|
176 |
|
177 | t.notOk(input.valid, 'Input should be invalid');
|
178 | t.ok(isHidden(messageContainer), 'Message should not be visible');
|
179 | t.notOk(hasClass(inputElement, 'input-invalid'), 'Does not have invalid class');
|
180 | t.notOk(hasClass(inputElement, 'input-valid'), 'Doest not have valid class');
|
181 |
|
182 |
|
183 | inputElement.value = 'O';
|
184 | input.handleInputChanged();
|
185 | input.handleBlur();
|
186 |
|
187 | t.notOk(input.valid, 'Input should be invalid');
|
188 | t.notOk(isHidden(messageContainer), 'Message should be visible');
|
189 | t.ok(hasClass(inputElement, 'input-invalid'), 'Has invalid class');
|
190 | t.notOk(hasClass(inputElement, 'input-valid'), 'Does not have valid class');
|
191 |
|
192 |
|
193 | inputElement.value = 'Once upon a time!';
|
194 | input.handleInputChanged();
|
195 | input.handleBlur();
|
196 |
|
197 | t.ok(input.valid, 'Input should be valid');
|
198 | t.ok(isHidden(messageContainer), 'Message should not be visible');
|
199 | t.notOk(hasClass(inputElement, 'input-invalid'), 'Does not have invalid class');
|
200 | t.ok(hasClass(inputElement, 'input-valid'), 'Has valid class');
|
201 | });
|
202 |
|
203 | t.end();
|
204 | });
|
205 |
|
206 | test('allow setting root element class', function (t) {
|
207 | var input = new InputView();
|
208 | input.render();
|
209 | t.equal(input.el.className, '');
|
210 |
|
211 | input = new InputView({
|
212 | rootElementClass: 'something'
|
213 | });
|
214 | input.render();
|
215 |
|
216 | t.equal(input.el.className, 'something');
|
217 | input.rootElementClass = 'somethingelse';
|
218 | t.equal(input.el.className, 'somethingelse');
|
219 |
|
220 | t.end();
|
221 | });
|
222 |
|
223 | test('validityClass is present on submit even if unchanged', function (t) {
|
224 | [
|
225 | new InputView({
|
226 | name: 'title',
|
227 | required: true
|
228 | }),
|
229 | new InputView({
|
230 | name: 'title',
|
231 | required: true,
|
232 | value: ''
|
233 | })
|
234 | ].forEach(function (input) {
|
235 | input.render();
|
236 |
|
237 | var inputElement = input.el.querySelector('textarea');
|
238 | var messageContainer = input.el.querySelector('[data-hook=message-container]');
|
239 |
|
240 |
|
241 |
|
242 | input.beforeSubmit();
|
243 |
|
244 | t.notOk(input.valid, 'Input should be invalid');
|
245 | t.notOk(isHidden(messageContainer), 'Message should be visible');
|
246 | t.ok(hasClass(inputElement, 'input-invalid'), 'Has invalid class');
|
247 | t.notOk(hasClass(inputElement, 'input-valid'), 'Does not have valid class');
|
248 | });
|
249 |
|
250 | t.end();
|
251 | });
|
252 |
|
253 | test('Required views display message and class after edited', function (t) {
|
254 | [
|
255 | new InputView({
|
256 | name: 'title',
|
257 | required: true
|
258 | }),
|
259 | new InputView({
|
260 | name: 'title',
|
261 | required: true,
|
262 | value: ''
|
263 | })
|
264 | ].forEach(function (input) {
|
265 | input.render();
|
266 |
|
267 | var inputElement = input.el.querySelector('textarea');
|
268 | var messageContainer = input.el.querySelector('[data-hook=message-container]');
|
269 |
|
270 | inputElement.value = 'Required string';
|
271 | input.handleInputChanged();
|
272 | input.handleBlur();
|
273 |
|
274 | t.ok(input.valid, 'Input should be valid');
|
275 | t.ok(isHidden(messageContainer), 'Message should not be visible');
|
276 | t.notOk(hasClass(inputElement, 'input-invalid'), 'Does not have invalid class');
|
277 | t.ok(hasClass(inputElement, 'input-valid'), 'Has valid class');
|
278 |
|
279 |
|
280 |
|
281 | inputElement.value = '';
|
282 | input.handleInputChanged();
|
283 | input.handleBlur();
|
284 |
|
285 | t.notOk(input.valid, 'Input should be invalid');
|
286 | t.notOk(isHidden(messageContainer), 'Message should be visible');
|
287 | t.ok(hasClass(inputElement, 'input-invalid'), 'Has invalid class');
|
288 | t.notOk(hasClass(inputElement, 'input-valid'), 'Does not have valid class');
|
289 | });
|
290 |
|
291 | t.end();
|
292 | });
|
293 |
|
294 | test('value reports changed in cases where it shouldnt', function (t) {
|
295 | [
|
296 | new InputView({
|
297 | name: 'title'
|
298 | }),
|
299 | new InputView({
|
300 | name: 'title',
|
301 | value: ''
|
302 | }),
|
303 | new InputView({
|
304 | name: 'title',
|
305 | value: null
|
306 | })
|
307 | ].forEach(function (input) {
|
308 | input.render();
|
309 |
|
310 | var inputElement = input.el.querySelector('textarea');
|
311 |
|
312 |
|
313 | inputElement.value = '0';
|
314 | input.handleInputChanged();
|
315 | t.ok(input.changed, 'Input is changed');
|
316 |
|
317 | inputElement.value = '';
|
318 | input.handleInputChanged();
|
319 | t.notOk(input.changed, 'Input is not changed when empty string');
|
320 |
|
321 | inputElement.value = null;
|
322 | input.handleInputChanged();
|
323 | t.notOk(input.changed, 'Input is not changed when null');
|
324 |
|
325 |
|
326 | input.setValue('0');
|
327 | t.ok(input.changed, 'Input is changed');
|
328 |
|
329 | input.setValue('');
|
330 | t.notOk(input.changed, 'Input is not changed when empty string');
|
331 |
|
332 | input.setValue(null);
|
333 | t.notOk(input.changed, 'Input is not changed when null');
|
334 | });
|
335 |
|
336 | t.end();
|
337 | });
|
338 |
|
339 | test('textarea grows in height as the text wraps', function (t) {
|
340 | var input = new InputView(),
|
341 | textarea,
|
342 | initialHeight,
|
343 | singleLineHeight;
|
344 |
|
345 | input.render();
|
346 |
|
347 | textarea = input.el.querySelector('textarea');
|
348 |
|
349 | initialHeight = textarea.style.height;
|
350 | input.setValue('Test');
|
351 |
|
352 | window.setTimeout(function () {
|
353 | singleLineHeight = textarea.style.height;
|
354 |
|
355 | t.equal(initialHeight, '', 'The initial height should not be set');
|
356 | t.notEqual(initialHeight, singleLineHeight, 'Input height changes when new text is entered');
|
357 | t.end();
|
358 | }, 900);
|
359 | });
|