UNPKG

4.11 kBJavaScriptView Raw
1/**
2 * Requires space before and/or after `?` or `:` in conditional expressions.
3 *
4 * Types: `Object` or `Boolean`
5 *
6 * Values: `"afterTest"`, `"beforeConsequent"`, `"afterConsequent"`, `"beforeAlternate"` as child properties,
7 * or `true` to set all properties to `true`. Child properties must be set to `true`.
8 *
9 * #### Example
10 *
11 * ```js
12 * "requireSpacesInConditionalExpression": {
13 * "afterTest": true,
14 * "beforeConsequent": true,
15 * "afterConsequent": true,
16 * "beforeAlternate": true
17 * }
18 * ```
19 *
20 * ##### Valid
21 *
22 * ```js
23 * var a = b ? c : d;
24 * var a= b ? c : d;
25 * ```
26 *
27 * ##### Invalid
28 *
29 * ```js
30 * var a = b? c : d;
31 * var a = b ?c : d;
32 * var a = b ? c: d;
33 * var a = b ? c :d;
34 * ```
35 */
36
37var assert = require('assert');
38
39module.exports = function() {};
40
41module.exports.prototype = {
42 configure: function(options) {
43 var validProperties = [
44 'afterTest',
45 'beforeConsequent',
46 'afterConsequent',
47 'beforeAlternate'
48 ];
49 var optionName = this.getOptionName();
50
51 if (options === true) {
52 options = {
53 'afterTest': true,
54 'beforeConsequent': true,
55 'afterConsequent': true,
56 'beforeAlternate': true
57 };
58 }
59
60 assert(
61 typeof options === 'object',
62 optionName + ' option requires a true value or an object'
63 );
64
65 var isProperlyConfigured = validProperties.some(function(key) {
66 var isPresent = key in options;
67
68 if (isPresent) {
69 assert(
70 options[key] === true,
71 optionName + '.' + key + ' property requires true value or should be removed'
72 );
73 }
74
75 return isPresent;
76 });
77
78 assert(
79 isProperlyConfigured,
80 optionName + ' must have at least 1 of the following properties: ' + validProperties.join(', ')
81 );
82
83 validProperties.forEach(function(property) {
84 this['_' + property] = Boolean(options[property]);
85 }.bind(this));
86 },
87
88 getOptionName: function() {
89 return 'requireSpacesInConditionalExpression';
90 },
91
92 check: function(file, errors) {
93 file.iterateNodesByType(['ConditionalExpression'], function(node) {
94 var consequent = node.consequent;
95 var alternate = node.alternate;
96 var consequentToken = file.getFirstNodeToken(consequent);
97 var alternateToken = file.getFirstNodeToken(alternate);
98 var questionMarkToken = file.findPrevOperatorToken(consequentToken, '?');
99 var colonToken = file.findPrevOperatorToken(alternateToken, ':');
100 var token;
101
102 if (this._afterTest) {
103 token = file.getPrevToken(questionMarkToken);
104 errors.assert.whitespaceBetween({
105 token: token,
106 nextToken: questionMarkToken,
107 message: 'Missing space after test'
108 });
109 }
110
111 if (this._beforeConsequent) {
112 token = file.getNextToken(questionMarkToken);
113 errors.assert.whitespaceBetween({
114 token: questionMarkToken,
115 nextToken: token,
116 message: 'Missing space before consequent'
117 });
118 }
119
120 if (this._afterConsequent) {
121 token = file.getPrevToken(colonToken);
122 errors.assert.whitespaceBetween({
123 token: token,
124 nextToken: colonToken,
125 message: 'Missing space after consequent'
126 });
127 }
128
129 if (this._beforeAlternate) {
130 token = file.getNextToken(colonToken);
131 errors.assert.whitespaceBetween({
132 token: colonToken,
133 nextToken: token,
134 message: 'Missing space before alternate'
135 });
136 }
137 }.bind(this));
138 }
139
140};