Conditions | 32 |
Total Lines | 183 |
Code Lines | 97 |
Lines | 0 |
Ratio | 0 % |
Tests | 81 |
CRAP Score | 32 |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
Complex classes like floatify.js ➔ floatify often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
1 | 'use strict'; |
||
3 | 1 | var floatify = function floatify(str, preferDecimalSeparator) { |
|
4 | // by default we prefer thousands separators |
||
5 | 281 | var preferThousandsSeparators = preferDecimalSeparator !== true; |
|
6 | |||
7 | 281 | var toFloatFormat = function toFloatFormat(str, ts, ds) { |
|
8 | 231 | var string = str; |
|
9 | 231 | var decimalSeparator = ds || ''; |
|
10 | |||
11 | 231 | string = string.split(ts || '').join(''); |
|
12 | 231 | if (decimalSeparator !== '') { |
|
13 | 197 | string = string.split(decimalSeparator).join('.'); |
|
14 | } |
||
15 | |||
16 | 231 | return parseFloat(string); |
|
17 | }; |
||
18 | |||
19 | 281 | var parseParts = function parseParts(str, ele, count, preferThousandsSeparators) { |
|
20 | 167 | var string = str; |
|
21 | 167 | var element = ele; |
|
22 | 167 | var parts = string.split(element); |
|
23 | |||
24 | function parseMidPart() { |
||
25 | 25 | if (current.length !== 3) { |
|
26 | 16 | return Number.NaN; |
|
27 | } |
||
28 | |||
29 | 9 | if (left.length > 3) { |
|
30 | 2 | return Number.NaN; |
|
31 | } |
||
32 | |||
33 | // no decision, continue |
||
34 | 7 | return null; |
|
35 | } |
||
36 | |||
37 | function parseEndPart() { |
||
38 | 149 | if ((leftVal === 0 || isNaN(leftVal) || left.length > 3)) { |
|
39 | 94 | return toFloatFormat(string, '', element); |
|
40 | } |
||
41 | |||
42 | 55 | if (current.length === 3) { |
|
43 | 13 | if (preferThousandsSeparators) { |
|
44 | 11 | return toFloatFormat(string, element, ''); |
|
45 | } |
||
46 | 2 | return toFloatFormat(string, '', element); |
|
47 | } |
||
48 | |||
49 | 42 | if (count === 1) { |
|
50 | 38 | return toFloatFormat(string, '', element); |
|
51 | } |
||
52 | |||
53 | 4 | return Number.NaN; |
|
54 | } |
||
55 | |||
56 | 167 | for (var i = 1; i < parts.length; i++) { |
|
57 | 174 | var current = parts[i]; |
|
58 | 174 | var left = parts[i - 1]; |
|
59 | 174 | var leftVal = parseInt(left, 10); |
|
60 | 174 | var isLast = parts.length - 1 === i; |
|
61 | var parseResult; |
||
62 | |||
63 | 174 | if (!isLast) { |
|
64 | 25 | parseResult = parseMidPart(); |
|
65 | } else { |
||
66 | 149 | parseResult = parseEndPart(); |
|
67 | } |
||
68 | |||
69 | 174 | if (parseResult !== null) { |
|
70 | 167 | break; |
|
71 | } |
||
72 | } |
||
73 | 167 | return parseResult || Number.NaN; |
|
74 | }; |
||
75 | |||
76 | 281 | var parse = function parse(str, preferThousandsSeparators) { |
|
77 | 281 | var string = str; |
|
78 | var spacePos; |
||
79 | var spaceSplit; |
||
80 | var spaceCount; |
||
81 | var dotPos; |
||
82 | var commaPos; |
||
83 | var lDotPos; |
||
84 | var lCommaPos; |
||
85 | var dotCount; |
||
86 | var commaCount; |
||
87 | |||
88 | function parseMixedSeparators() { |
||
89 | // format is using dot and comma |
||
90 | |||
91 | // last dot position |
||
92 | 68 | lDotPos = string.lastIndexOf('.'); |
|
93 | // last comma position |
||
94 | 68 | lCommaPos = string.lastIndexOf(','); |
|
95 | |||
96 | // order of 1st dot -> comma must be same as last dot -> comma |
||
97 | // 123.123.123,123 -> ok 123.123,123.123 -> not ok |
||
98 | 68 | if (Math.sign(dotPos - commaPos) !== Math.sign(lDotPos - lCommaPos)) { |
|
99 | 3 | return Number.NaN; |
|
100 | } |
||
101 | |||
102 | // check positions to guess the thousands separator |
||
103 | 65 | if (dotPos > commaPos) { |
|
104 | 57 | if (dotCount > 1) { |
|
105 | 1 | return Number.NaN; |
|
106 | } |
||
107 | // best guess: . is thousands separator and , is decimal point |
||
108 | 56 | return toFloatFormat(string, ',', '.'); |
|
109 | } |
||
110 | |||
111 | 8 | if (commaCount > 1) { |
|
112 | 1 | return Number.NaN; |
|
113 | } |
||
114 | // best guess: , is thousands separator and . is decimal point |
||
115 | 7 | return toFloatFormat(string, '.', ','); |
|
116 | } |
||
117 | |||
118 | function parseSingleSeparators() { |
||
119 | 172 | if (dotPos !== -1) { |
|
120 | // only dot(s) in format |
||
121 | 86 | return parseParts(string, '.', dotCount, preferThousandsSeparators); |
|
122 | } |
||
123 | |||
124 | 86 | if (commaPos !== -1) { |
|
125 | // only comma(s) in format |
||
126 | 81 | return parseParts(string, ',', commaCount, preferThousandsSeparators); |
|
127 | } |
||
128 | |||
129 | 5 | return toFloatFormat(string); |
|
130 | } |
||
131 | |||
132 | function precheckFormat() { |
||
133 | // only combination of 2 separators allowed |
||
134 | 263 | if (dotCount > 0 && commaCount > 0 && spaceCount > 0) { |
|
135 | 1 | return false; |
|
136 | } |
||
137 | |||
138 | // if there is any separator (space, comma, dot) found more than once, |
||
139 | // all other must not be found more than once |
||
140 | 262 | if (dotCount > 1 && (commaCount > 1 || spaceCount > 1)) { |
|
141 | 4 | return false; |
|
142 | } |
||
143 | |||
144 | 258 | return !(commaCount > 1 && spaceCount > 1); |
|
145 | } |
||
146 | |||
147 | 281 | string = string.trim(); |
|
148 | |||
149 | // 1st dot position |
||
150 | 281 | dotPos = string.indexOf('.'); |
|
151 | // 1st comma position |
||
152 | 281 | commaPos = string.indexOf(','); |
|
153 | // 1st space position |
||
154 | 281 | spacePos = string.indexOf(' '); |
|
155 | |||
156 | 281 | if (dotPos + commaPos + spacePos === -3) { |
|
157 | // life is good, no separators |
||
158 | 18 | return toFloatFormat(string); |
|
159 | } |
||
160 | |||
161 | 263 | spaceSplit = string.split(' '); |
|
162 | 263 | spaceCount = spaceSplit.length - 1; |
|
163 | 263 | dotCount = string.split('.').length - 1; |
|
164 | 263 | commaCount = string.split(',').length - 1; |
|
165 | |||
166 | 263 | if (!precheckFormat()) { |
|
167 | 6 | return Number.NaN; |
|
168 | } |
||
169 | |||
170 | 257 | if (spaceCount > 0) { |
|
171 | 72 | if (!string.match(/^(\d{1,3})?(\s\d{3})*([,\.]\d+)?$/)) { |
|
172 | 17 | return Number.NaN; |
|
173 | } |
||
174 | 55 | string = spaceSplit.join(''); |
|
175 | } |
||
176 | |||
177 | 240 | if (dotPos !== -1 && commaPos !== -1) { |
|
178 | 68 | return parseMixedSeparators(); |
|
179 | } |
||
180 | |||
181 | 172 | return parseSingleSeparators(); |
|
182 | }; |
||
183 | |||
184 | 281 | return parse(str, preferThousandsSeparators); |
|
185 | }; |
||
186 | |||
192 |