govuk_publishing_components 17.10.0 → 17.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/govuk_publishing_components/components/feedback.js +21 -0
  3. data/app/assets/stylesheets/govuk_publishing_components/components/_translation-nav.scss +10 -10
  4. data/app/views/govuk_publishing_components/components/_feedback.html.erb +1 -1
  5. data/app/views/govuk_publishing_components/components/docs/accordion.yml +2 -1
  6. data/app/views/govuk_publishing_components/components/docs/layout_footer.yml +1 -1
  7. data/app/views/govuk_publishing_components/components/docs/layout_for_admin.yml +3 -16
  8. data/app/views/govuk_publishing_components/components/docs/layout_header.yml +1 -1
  9. data/app/views/govuk_publishing_components/components/docs/modal_dialogue.yml +2 -2
  10. data/app/views/govuk_publishing_components/components/docs/skip_link.yml +1 -1
  11. data/app/views/govuk_publishing_components/components/docs/tabs.yml +1 -2
  12. data/app/views/govuk_publishing_components/components/feedback/_survey_signup_form.html.erb +2 -5
  13. data/lib/govuk_publishing_components/version.rb +1 -1
  14. data/node_modules/accessible-autocomplete/package.json +1 -1
  15. data/node_modules/graceful-fs/package.json +15 -15
  16. data/node_modules/graceful-fs/polyfills.js +16 -9
  17. data/node_modules/jsx-ast-utils/CHANGELOG.md +4 -0
  18. data/node_modules/jsx-ast-utils/__tests__/helper.js +41 -3
  19. data/node_modules/jsx-ast-utils/__tests__/src/elementType-test.js +4 -1
  20. data/node_modules/jsx-ast-utils/__tests__/src/getProp-test.js +4 -1
  21. data/node_modules/jsx-ast-utils/__tests__/src/{getPropLiteralValue-test.js → getPropLiteralValue-babelparser-test.js} +23 -5
  22. data/node_modules/jsx-ast-utils/__tests__/src/getPropLiteralValue-flowparser-test.js +522 -0
  23. data/node_modules/jsx-ast-utils/__tests__/src/{getPropValue-test.js → getPropValue-babelparser-test.js} +38 -5
  24. data/node_modules/jsx-ast-utils/__tests__/src/getPropValue-flowparser-test.js +938 -0
  25. data/node_modules/jsx-ast-utils/__tests__/src/hasProp-test.js +4 -1
  26. data/node_modules/jsx-ast-utils/__tests__/src/propName-test.js +4 -1
  27. data/node_modules/jsx-ast-utils/lib/values/expressions/TypeCastExpression.js +19 -0
  28. data/node_modules/jsx-ast-utils/lib/values/expressions/index.js +8 -2
  29. data/node_modules/jsx-ast-utils/package.json +17 -14
  30. data/node_modules/jsx-ast-utils/src/values/expressions/TypeCastExpression.js +13 -0
  31. data/node_modules/jsx-ast-utils/src/values/expressions/index.js +3 -0
  32. data/node_modules/pkg-conf/package.json +1 -1
  33. metadata +8 -4
@@ -1,10 +1,18 @@
1
1
  /* eslint-env mocha */
2
2
  /* eslint no-template-curly-in-string: 0 */
3
3
  import assert from 'assert';
4
- import { extractProp, describeIfNotBabylon, changePlugins } from '../helper';
4
+ import {
5
+ extractProp,
6
+ describeIfNotBabylon,
7
+ changePlugins,
8
+ setParserName,
9
+ } from '../helper';
5
10
  import { getLiteralPropValue } from '../../src/getPropValue';
6
11
 
7
12
  describe('getLiteralPropValue', () => {
13
+ beforeEach(() => {
14
+ setParserName('babel');
15
+ });
8
16
  it('should export a function', () => {
9
17
  const expected = 'function';
10
18
  const actual = typeof getLiteralPropValue;
@@ -26,12 +34,22 @@ describe('getLiteralPropValue', () => {
26
34
  type: 'JSXExpressionContainer',
27
35
  },
28
36
  };
29
-
37
+ let counter = 0;
38
+ // eslint-disable-next-line no-console
39
+ const errorOrig = console.error;
40
+ // eslint-disable-next-line no-console
41
+ console.error = () => {
42
+ counter += 1;
43
+ };
44
+ let value;
30
45
  assert.doesNotThrow(() => {
31
- getLiteralPropValue(prop);
46
+ value = getLiteralPropValue(prop);
32
47
  }, Error);
33
48
 
34
- assert.equal(null, getLiteralPropValue(prop));
49
+ assert.equal(null, value);
50
+ assert.equal(counter, 1);
51
+ // eslint-disable-next-line no-console
52
+ console.error = errorOrig;
35
53
  });
36
54
 
37
55
  describe('Null', () => {
@@ -121,7 +139,7 @@ describe('getLiteralPropValue', () => {
121
139
 
122
140
  describe('JSXElement', () => {
123
141
  it('should return null', () => {
124
- const prop = extractProp('<div foo=<bar /> />');
142
+ const prop = extractProp('<div foo={<bar />} />');
125
143
 
126
144
  const expected = null;
127
145
  const actual = getLiteralPropValue(prop);
@@ -0,0 +1,522 @@
1
+ /* eslint-env mocha */
2
+ /* eslint no-template-curly-in-string: 0 */
3
+ import assert from 'assert';
4
+ import {
5
+ extractProp,
6
+ describeIfNotBabylon,
7
+ changePlugins,
8
+ setParserName,
9
+ } from '../helper';
10
+ import { getLiteralPropValue } from '../../src/getPropValue';
11
+
12
+ describe('getLiteralPropValue', () => {
13
+ beforeEach(() => {
14
+ setParserName('flow');
15
+ });
16
+ it('should export a function', () => {
17
+ const expected = 'function';
18
+ const actual = typeof getLiteralPropValue;
19
+
20
+ assert.equal(expected, actual);
21
+ });
22
+
23
+ it('should return undefined when not provided with a JSXAttribute', () => {
24
+ const expected = undefined;
25
+ const actual = getLiteralPropValue(1);
26
+
27
+ assert.equal(expected, actual);
28
+ });
29
+
30
+ it('should not throw error when trying to get value from unknown node type', () => {
31
+ const prop = {
32
+ type: 'JSXAttribute',
33
+ value: {
34
+ type: 'JSXExpressionContainer',
35
+ },
36
+ };
37
+ let counter = 0;
38
+ // eslint-disable-next-line no-console
39
+ const errorOrig = console.error;
40
+ // eslint-disable-next-line no-console
41
+ console.error = () => {
42
+ counter += 1;
43
+ };
44
+ let value;
45
+ assert.doesNotThrow(() => {
46
+ value = getLiteralPropValue(prop);
47
+ }, Error);
48
+
49
+ assert.equal(null, value);
50
+ assert.equal(counter, 1);
51
+ // eslint-disable-next-line no-console
52
+ console.error = errorOrig;
53
+ });
54
+
55
+ describe('Null', () => {
56
+ it('should return true when no value is given', () => {
57
+ const prop = extractProp('<div foo />');
58
+
59
+ const expected = true;
60
+ const actual = getLiteralPropValue(prop);
61
+
62
+ assert.equal(expected, actual);
63
+ });
64
+ });
65
+
66
+ describe('Literal', () => {
67
+ it('should return correct string if value is a string', () => {
68
+ const prop = extractProp('<div foo="bar" />');
69
+
70
+ const expected = 'bar';
71
+ const actual = getLiteralPropValue(prop);
72
+
73
+ assert.equal(expected, actual);
74
+ });
75
+
76
+ it('should return correct string if value is a string expression', () => {
77
+ const prop = extractProp('<div foo={"bar"} />');
78
+
79
+ const expected = 'bar';
80
+ const actual = getLiteralPropValue(prop);
81
+
82
+ assert.equal(expected, actual);
83
+ });
84
+
85
+ it('should return correct integer if value is a integer expression', () => {
86
+ const prop = extractProp('<div foo={1} />');
87
+
88
+ const expected = 1;
89
+ const actual = getLiteralPropValue(prop);
90
+
91
+ assert.equal(expected, actual);
92
+ });
93
+
94
+ it('should convert "true" to boolean type', () => {
95
+ const prop = extractProp('<div foo="true" />');
96
+
97
+ const expected = true;
98
+ const actual = getLiteralPropValue(prop);
99
+
100
+ assert.equal(expected, actual);
101
+ });
102
+
103
+ it('should convert "TrUE" to boolean type', () => {
104
+ const prop = extractProp('<div foo="TrUE" />');
105
+
106
+ const expected = true;
107
+ const actual = getLiteralPropValue(prop);
108
+
109
+ assert.equal(expected, actual);
110
+ });
111
+
112
+ it('should convert "false" to boolean type', () => {
113
+ const prop = extractProp('<div foo="false" />');
114
+
115
+ const expected = false;
116
+ const actual = getLiteralPropValue(prop);
117
+
118
+ assert.equal(expected, actual);
119
+ });
120
+
121
+ it('should convert "FaLsE" to boolean type', () => {
122
+ const prop = extractProp('<div foo="FaLsE" />');
123
+
124
+ const expected = false;
125
+ const actual = getLiteralPropValue(prop);
126
+
127
+ assert.equal(expected, actual);
128
+ });
129
+
130
+ it('should return String null when value is null', () => {
131
+ const prop = extractProp('<div foo={null} />');
132
+
133
+ const expected = 'null';
134
+ const actual = getLiteralPropValue(prop);
135
+
136
+ assert.equal(expected, actual);
137
+ });
138
+ });
139
+
140
+ describe('JSXElement', () => {
141
+ it('should return null', () => {
142
+ const prop = extractProp('<div foo={<bar />} />');
143
+
144
+ const expected = null;
145
+ const actual = getLiteralPropValue(prop);
146
+
147
+ assert.equal(expected, actual);
148
+ });
149
+ });
150
+
151
+ describe('Identifier', () => {
152
+ it('should return null', () => {
153
+ const prop = extractProp('<div foo={bar} />');
154
+
155
+ const expected = null;
156
+ const actual = getLiteralPropValue(prop);
157
+
158
+ assert.equal(expected, actual);
159
+ });
160
+
161
+ it('should return undefined when identifier is literally `undefined`', () => {
162
+ const prop = extractProp('<div foo={undefined} />');
163
+
164
+ const expected = undefined;
165
+ const actual = getLiteralPropValue(prop);
166
+
167
+ assert.equal(expected, actual);
168
+ });
169
+ });
170
+
171
+ describe('Template literal', () => {
172
+ it('should return template literal with vars wrapped in curly braces', () => {
173
+ const prop = extractProp('<div foo={`bar ${baz}`} />');
174
+
175
+ const expected = 'bar {baz}';
176
+ const actual = getLiteralPropValue(prop);
177
+
178
+ assert.equal(expected, actual);
179
+ });
180
+
181
+ it('should return string "undefined" for expressions that evaluate to undefined', () => {
182
+ const prop = extractProp('<div foo={`bar ${undefined}`} />');
183
+
184
+ const expected = 'bar undefined';
185
+ const actual = getLiteralPropValue(prop);
186
+
187
+ assert.equal(expected, actual);
188
+ });
189
+ });
190
+
191
+ describe('Tagged Template literal', () => {
192
+ it('should return template literal with vars wrapped in curly braces', () => {
193
+ const prop = extractProp('<div foo={noop`bar ${baz}`} />');
194
+
195
+ const expected = 'bar {baz}';
196
+ const actual = getLiteralPropValue(prop);
197
+
198
+ assert.equal(expected, actual);
199
+ });
200
+
201
+ it('should return string "undefined" for expressions that evaluate to undefined', () => {
202
+ const prop = extractProp('<div foo={noop`bar ${undefined}`} />');
203
+
204
+ const expected = 'bar undefined';
205
+ const actual = getLiteralPropValue(prop);
206
+
207
+ assert.equal(expected, actual);
208
+ });
209
+ });
210
+
211
+ describe('Arrow function expression', () => {
212
+ it('should return null', () => {
213
+ const prop = extractProp('<div foo={ () => { return "bar"; }} />');
214
+
215
+ const expected = null;
216
+ const actual = getLiteralPropValue(prop);
217
+
218
+ assert.equal(expected, actual);
219
+ });
220
+ });
221
+
222
+ describe('Function expression', () => {
223
+ it('should return null', () => {
224
+ const prop = extractProp('<div foo={ function() { return "bar"; } } />');
225
+
226
+ const expected = null;
227
+ const actual = getLiteralPropValue(prop);
228
+
229
+ assert.equal(expected, actual);
230
+ });
231
+ });
232
+
233
+ describe('Logical expression', () => {
234
+ it('should return null for && operator', () => {
235
+ const prop = extractProp('<div foo={bar && baz} />');
236
+
237
+ const expected = null;
238
+ const actual = getLiteralPropValue(prop);
239
+
240
+ assert.equal(expected, actual);
241
+ });
242
+
243
+ it('should return null for || operator', () => {
244
+ const prop = extractProp('<div foo={bar || baz} />');
245
+
246
+ const expected = null;
247
+ const actual = getLiteralPropValue(prop);
248
+
249
+ assert.equal(expected, actual);
250
+ });
251
+ });
252
+
253
+ describe('Member expression', () => {
254
+ it('should return null', () => {
255
+ const prop = extractProp('<div foo={bar.baz} />');
256
+
257
+ const expected = null;
258
+ const actual = getLiteralPropValue(prop);
259
+
260
+ assert.equal(expected, actual);
261
+ });
262
+ });
263
+
264
+ describe('Call expression', () => {
265
+ it('should return null', () => {
266
+ const prop = extractProp('<div foo={bar()} />');
267
+
268
+ const expected = null;
269
+ const actual = getLiteralPropValue(prop);
270
+
271
+ assert.equal(expected, actual);
272
+ });
273
+ });
274
+
275
+ describe('Unary expression', () => {
276
+ it('should correctly evaluate an expression that prefixes with -', () => {
277
+ const prop = extractProp('<div foo={-bar} />');
278
+
279
+ // -"bar" => NaN
280
+ const expected = true;
281
+ const actual = Number.isNaN(getLiteralPropValue(prop));
282
+
283
+ assert.equal(expected, actual);
284
+ });
285
+
286
+ it('should correctly evaluate an expression that prefixes with -', () => {
287
+ const prop = extractProp('<div foo={-42} />');
288
+
289
+ const expected = -42;
290
+ const actual = getLiteralPropValue(prop);
291
+
292
+ assert.equal(expected, actual);
293
+ });
294
+
295
+ it('should correctly evaluate an expression that prefixes with +', () => {
296
+ const prop = extractProp('<div foo={+bar} />');
297
+
298
+ // +"bar" => NaN
299
+ const expected = true;
300
+ const actual = Number.isNaN(getLiteralPropValue(prop));
301
+
302
+ assert.equal(expected, actual);
303
+ });
304
+
305
+ it('should correctly evaluate an expression that prefixes with +', () => {
306
+ const prop = extractProp('<div foo={+42} />');
307
+
308
+ const expected = 42;
309
+ const actual = getLiteralPropValue(prop);
310
+
311
+ assert.equal(expected, actual);
312
+ });
313
+
314
+ it('should correctly evaluate an expression that prefixes with !', () => {
315
+ const prop = extractProp('<div foo={!bar} />');
316
+
317
+ const expected = false; // !"bar" === false
318
+ const actual = getLiteralPropValue(prop);
319
+
320
+ assert.equal(expected, actual);
321
+ });
322
+
323
+ it('should correctly evaluate an expression that prefixes with ~', () => {
324
+ const prop = extractProp('<div foo={~bar} />');
325
+
326
+ const expected = -1; // ~"bar" === -1
327
+ const actual = getLiteralPropValue(prop);
328
+
329
+ assert.equal(expected, actual);
330
+ });
331
+
332
+ it('should return true when evaluating `delete foo`', () => {
333
+ const prop = extractProp('<div foo={delete x} />');
334
+
335
+ const expected = true;
336
+ const actual = getLiteralPropValue(prop);
337
+
338
+ assert.equal(expected, actual);
339
+ });
340
+
341
+ it('should return undefined when evaluating `void foo`', () => {
342
+ const prop = extractProp('<div foo={void x} />');
343
+
344
+ const expected = undefined;
345
+ const actual = getLiteralPropValue(prop);
346
+
347
+ assert.equal(expected, actual);
348
+ });
349
+
350
+ // TODO: We should fix this to check to see if we can evaluate it.
351
+ it('should return undefined when evaluating `typeof foo`', () => {
352
+ const prop = extractProp('<div foo={typeof x} />');
353
+
354
+ const expected = undefined;
355
+ const actual = getLiteralPropValue(prop);
356
+
357
+ assert.equal(expected, actual);
358
+ });
359
+ });
360
+
361
+ describe('Update expression', () => {
362
+ it('should correctly evaluate an expression that prefixes with ++', () => {
363
+ const prop = extractProp('<div foo={++bar} />');
364
+
365
+ // ++"bar" => NaN
366
+ const expected = true;
367
+ const actual = Number.isNaN(getLiteralPropValue(prop));
368
+
369
+ assert.equal(expected, actual);
370
+ });
371
+
372
+ it('should correctly evaluate an expression that prefixes with --', () => {
373
+ const prop = extractProp('<div foo={--bar} />');
374
+
375
+ // --"bar" => NaN
376
+ const expected = true;
377
+ const actual = Number.isNaN(getLiteralPropValue(prop));
378
+
379
+ assert.equal(expected, actual);
380
+ });
381
+
382
+ it('should correctly evaluate an expression that suffixes with ++', () => {
383
+ const prop = extractProp('<div foo={bar++} />');
384
+
385
+ // "bar"++ => NaN
386
+ const expected = true;
387
+ const actual = Number.isNaN(getLiteralPropValue(prop));
388
+
389
+ assert.equal(expected, actual);
390
+ });
391
+
392
+ it('should correctly evaluate an expression that suffixes with --', () => {
393
+ const prop = extractProp('<div foo={bar--} />');
394
+
395
+ // "bar"-- => NaN
396
+ const expected = true;
397
+ const actual = Number.isNaN(getLiteralPropValue(prop));
398
+
399
+ assert.equal(expected, actual);
400
+ });
401
+ });
402
+
403
+ describe('This expression', () => {
404
+ it('should return null', () => {
405
+ const prop = extractProp('<div foo={this} />');
406
+
407
+ const expected = null;
408
+ const actual = getLiteralPropValue(prop);
409
+
410
+ assert.equal(expected, actual);
411
+ });
412
+ });
413
+
414
+ describe('Conditional expression', () => {
415
+ it('should return null', () => {
416
+ const prop = extractProp('<div foo={bar ? baz : bam} />');
417
+
418
+ const expected = null;
419
+ const actual = getLiteralPropValue(prop);
420
+
421
+ assert.equal(expected, actual);
422
+ });
423
+ });
424
+
425
+ describe('Binary expression', () => {
426
+ it('should return null', () => {
427
+ const prop = extractProp('<div foo={1 == "1"} />');
428
+
429
+ const expected = null;
430
+ const actual = getLiteralPropValue(prop);
431
+
432
+ assert.equal(expected, actual);
433
+ });
434
+ });
435
+
436
+ describe('Object expression', () => {
437
+ it('should return null', () => {
438
+ const prop = extractProp('<div foo={ { bar: "baz" } } />');
439
+
440
+ const expected = null;
441
+ const actual = getLiteralPropValue(prop);
442
+
443
+ assert.deepEqual(expected, actual);
444
+ });
445
+ });
446
+
447
+ describe('New expression', () => {
448
+ it('should return null', () => {
449
+ const prop = extractProp('<div foo={new Bar()} />');
450
+
451
+ const expected = null;
452
+ const actual = getLiteralPropValue(prop);
453
+
454
+ assert.deepEqual(expected, actual);
455
+ });
456
+ });
457
+
458
+ describe('Array expression', () => {
459
+ it('should evaluate to correct representation of the the array in props', () => {
460
+ const prop = extractProp('<div foo={["bar", 42, null]} />');
461
+
462
+ const expected = ['bar', 42];
463
+ const actual = getLiteralPropValue(prop);
464
+
465
+ assert.deepEqual(expected, actual);
466
+ });
467
+ });
468
+
469
+ it('should return an empty array provided an empty array in props', () => {
470
+ const prop = extractProp('<div foo={[]} />');
471
+
472
+ const expected = [];
473
+ const actual = getLiteralPropValue(prop);
474
+
475
+ assert.deepEqual(expected, actual);
476
+ });
477
+
478
+ describe('Bind expression', () => {
479
+ it('should return null', () => {
480
+ const prop = extractProp('<div foo={::this.handleClick} />');
481
+
482
+ const expected = 'null';
483
+ const actual = getLiteralPropValue(prop);
484
+
485
+ assert.deepEqual(expected, actual);
486
+ });
487
+ });
488
+
489
+ describeIfNotBabylon('Typescript', () => {
490
+ beforeEach(() => {
491
+ changePlugins(pls => [...pls, 'typescript']);
492
+ });
493
+
494
+ it('should return string representation of variable identifier wrapped in a Typescript non-null assertion', () => {
495
+ const prop = extractProp('<div foo={bar!} />');
496
+
497
+ const expected = null;
498
+ const actual = getLiteralPropValue(prop);
499
+
500
+ assert.equal(expected, actual);
501
+ });
502
+
503
+ it('should return string representation of variable identifier wrapped in a deep Typescript non-null assertion', () => {
504
+ const prop = extractProp('<div foo={(bar!)!} />');
505
+
506
+ const expected = null;
507
+ const actual = getLiteralPropValue(prop);
508
+
509
+ assert.equal(expected, actual);
510
+ });
511
+
512
+ it('should return string representation of variable identifier wrapped in a Typescript type coercion', () => {
513
+ changePlugins(pls => [...pls, 'typescript']);
514
+ const prop = extractProp('<div foo={bar as any} />');
515
+
516
+ const expected = null;
517
+ const actual = getLiteralPropValue(prop);
518
+
519
+ assert.equal(expected, actual);
520
+ });
521
+ });
522
+ });