commit
message
[ISURL] formula added and tested
author
Ben Vogt <[email protected]>
date
2017-06-30 15:59:47
stats
8 file(s) changed,
131 insertions(+),
9 deletions(-)
files
DOCS.md
TODO.md
dist/Formulas/AllFormulas.js
dist/Formulas/Info.js
src/Formulas/AllFormulas.ts
src/Formulas/Info.ts
tests/Formulas/InfoTest.ts
tests/SheetFormulaTest.ts
1diff --git a/DOCS.md b/DOCS.md
2index 26296ba..204a770 100644
3--- a/DOCS.md
4+++ b/DOCS.md
5@@ -589,11 +589,20 @@
6 ### ISEMAIL
7
8 ```
9- Returns true if input is a valid email. Valid domains are Original top-level domains and Country code top-level domains,
10+ Returns true if input is a valid email. Valid domains are Original top-level domains and Country code top-level domains.
11 @param value - Value to check whether it is an email or not.
12 @returns {boolean}
13 @constructor
14 ```
15+
16+### ISURL
17+
18+```
19+ Returns true if the input is a valid URL.
20+@param value - Value to check
21+@returns {boolean}
22+@constructor
23+```
24 ## Logical
25
26
27diff --git a/TODO.md b/TODO.md
28index f6e3e20..fc591c6 100644
29--- a/TODO.md
30+++ b/TODO.md
31@@ -32,7 +32,6 @@ For example 64 tbs to a qt.
32 * ISFORMULA - Requires changes to parser.js
33 * ISNA - Requires changes to parser.js
34 * ISREF - Requires changes to parser.js
35-* ISURL
36 * N
37 * TYPE - Requires changes to parser.js
38 * CELL - Requires changes to parser.js
39diff --git a/dist/Formulas/AllFormulas.js b/dist/Formulas/AllFormulas.js
40index b1c1cfd..5916e90 100644
41--- a/dist/Formulas/AllFormulas.js
42+++ b/dist/Formulas/AllFormulas.js
43@@ -83,6 +83,7 @@ exports.ISLOGICAL = Info_1.ISLOGICAL;
44 exports.ISNUMBER = Info_1.ISNUMBER;
45 exports.ISNONTEXT = Info_1.ISNONTEXT;
46 exports.ISEMAIL = Info_1.ISEMAIL;
47+exports.ISURL = Info_1.ISURL;
48 var Lookup_1 = require("./Lookup");
49 exports.CHOOSE = Lookup_1.CHOOSE;
50 var Logical_1 = require("./Logical");
51diff --git a/dist/Formulas/Info.js b/dist/Formulas/Info.js
52index a9c027b..148fe8e 100644
53--- a/dist/Formulas/Info.js
54+++ b/dist/Formulas/Info.js
55@@ -58,7 +58,7 @@ var ISNUMBER = function (value) {
56 exports.ISNUMBER = ISNUMBER;
57 /**
58 * Returns true if input is a valid email. Valid domains are Original top-level domains and Country code top-level
59- * domains,
60+ * domains.
61 * @param value - Value to check whether it is an email or not.
62 * @returns {boolean}
63 * @constructor
64@@ -68,7 +68,44 @@ var ISEMAIL = function (value) {
65 if (typeof value !== "string") {
66 return false;
67 }
68- var EMAIL_REGEX = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil||edu||int|biz|info|mobi|name|aero|jobs|museum|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/;
69- return EMAIL_REGEX.test(value);
70+ var EMAIL_REGEX = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|edu|int|biz|info|mobi|name|aero|jobs|museum|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/;
71+ return EMAIL_REGEX.test(TypeConverter_1.TypeConverter.firstValueAsString(value));
72 };
73 exports.ISEMAIL = ISEMAIL;
74+/**
75+ * Returns true if the input is a valid URL.
76+ * @param value - Value to check
77+ * @returns {boolean}
78+ * @constructor
79+ */
80+var ISURL = function (value) {
81+ ArgsChecker_1.ArgsChecker.checkLength(arguments, 1, "ISURL");
82+ value = TypeConverter_1.TypeConverter.firstValueAsString(value);
83+ var matches = value.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
84+ if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) {
85+ return false;
86+ }
87+ if (/%[^0-9a-f]/i.test(value)) {
88+ return false;
89+ }
90+ if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) {
91+ return false;
92+ }
93+ var authority = matches[2];
94+ var path = matches[3];
95+ if (!(path.length >= 0)) {
96+ return false;
97+ }
98+ if (authority && authority.length) {
99+ if (!(path.length === 0 || /^\//.test(path))) {
100+ return false;
101+ }
102+ }
103+ else {
104+ if (/^\/\//.test(path)) {
105+ return false;
106+ }
107+ }
108+ return true;
109+};
110+exports.ISURL = ISURL;
111diff --git a/src/Formulas/AllFormulas.ts b/src/Formulas/AllFormulas.ts
112index 610867b..0bf1855 100644
113--- a/src/Formulas/AllFormulas.ts
114+++ b/src/Formulas/AllFormulas.ts
115@@ -82,7 +82,8 @@ import {
116 ISLOGICAL,
117 ISNUMBER,
118 ISNONTEXT,
119- ISEMAIL
120+ ISEMAIL,
121+ ISURL
122 } from "./Info";
123 import {
124 CHOOSE
125@@ -385,5 +386,6 @@ export {
126 IRR,
127 IPMT,
128 FV,
129- ISEMAIL
130+ ISEMAIL,
131+ ISURL
132 }
133\ No newline at end of file
134diff --git a/src/Formulas/Info.ts b/src/Formulas/Info.ts
135index 7243245..706efb6 100644
136--- a/src/Formulas/Info.ts
137+++ b/src/Formulas/Info.ts
138@@ -69,7 +69,7 @@ var ISNUMBER = function (value) {
139
140 /**
141 * Returns true if input is a valid email. Valid domains are Original top-level domains and Country code top-level
142- * domains,
143+ * domains.
144 * @param value - Value to check whether it is an email or not.
145 * @returns {boolean}
146 * @constructor
147@@ -79,8 +79,45 @@ var ISEMAIL = function (value) {
148 if (typeof value !== "string") {
149 return false;
150 }
151- const EMAIL_REGEX = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil||edu||int|biz|info|mobi|name|aero|jobs|museum|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/;
152- return EMAIL_REGEX.test(value);
153+ const EMAIL_REGEX = /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|gov|mil|edu|int|biz|info|mobi|name|aero|jobs|museum|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bl|bm|bn|bo|bq|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cw|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mf|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sx|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)\b/;
154+ return EMAIL_REGEX.test(TypeConverter.firstValueAsString(value));
155+};
156+
157+
158+/**
159+ * Returns true if the input is a valid URL.
160+ * @param value - Value to check
161+ * @returns {boolean}
162+ * @constructor
163+ */
164+var ISURL = function (value) {
165+ ArgsChecker.checkLength(arguments, 1, "ISURL");
166+ value = TypeConverter.firstValueAsString(value);
167+ var matches = value.match(/(?:([^:\/?#]+):)?(?:\/\/([^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/);
168+ if (/[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~\%]/i.test(value)) {
169+ return false;
170+ }
171+ if (/%[^0-9a-f]/i.test(value)) {
172+ return false;
173+ }
174+ if (/%[0-9a-f](:?[^0-9a-f]|$)/i.test(value)) {
175+ return false;
176+ }
177+ var authority = matches[2];
178+ var path = matches[3];
179+ if (!(path.length >= 0)) {
180+ return false;
181+ }
182+ if (authority && authority.length) {
183+ if (!(path.length === 0 || /^\//.test(path))) {
184+ return false;
185+ }
186+ } else {
187+ if (/^\/\//.test(path)) {
188+ return false;
189+ }
190+ }
191+ return true;
192 };
193
194
195@@ -90,5 +127,6 @@ export {
196 ISLOGICAL,
197 ISNUMBER,
198 ISNONTEXT,
199- ISEMAIL
200+ ISEMAIL,
201+ ISURL
202 }
203\ No newline at end of file
204diff --git a/tests/Formulas/InfoTest.ts b/tests/Formulas/InfoTest.ts
205index de88146..4b67de7 100644
206--- a/tests/Formulas/InfoTest.ts
207+++ b/tests/Formulas/InfoTest.ts
208@@ -4,7 +4,8 @@ import {
209 ISLOGICAL,
210 ISNUMBER,
211 ISNONTEXT,
212- ISEMAIL
213+ ISEMAIL,
214+ ISURL
215 } from "../../src/Formulas/Info";
216 import * as ERRORS from "../../src/Errors";
217 import {
218@@ -71,3 +72,26 @@ test("ISEMAIL", function(){
219 ISEMAIL.apply(this, []);
220 }, ERRORS.NA_ERROR);
221 });
222+
223+test("ISURL", function(){
224+ assertEquals(ISURL("http://google.com"), true);
225+ assertEquals(ISURL("google.com"), true);
226+ assertEquals(ISURL("www.google.com"), true);
227+ assertEquals(ISURL("http://localhost"), true);
228+ assertEquals(ISURL("http://localhost/"), true);
229+ assertEquals(ISURL("https://10.1.1.255:8080"), true);
230+ assertEquals(ISURL("http://example.w3.org/path%20with%20spaces.html"), true);
231+ assertEquals(ISURL("http://example.w3.org/%20"), true);
232+ assertEquals(ISURL("ftp://ftp.is.co.za/rfc/rfc1808.txt"), true);
233+ assertEquals(ISURL("ftp://ftp.is.co.za/../../../rfc/rfc1808.txt"), true);
234+ assertEquals(ISURL("http://www.ietf.org/rfc/rfc2396.txt"), true);
235+ assertEquals(ISURL("ldap://[2001:db8::7]/c=GB?objectClass?one"), true);
236+ assertEquals(ISURL("mailto:[email protected]"), true);
237+ assertEquals(ISURL("news:comp.infosystems.www.servers.unix"), true);
238+ assertEquals(ISURL("tel:+1-816-555-1212"), true);
239+ assertEquals(ISURL("telnet://192.0.2.16:80/"), true);
240+ assertEquals(ISURL("urn:oasis:names:specification:docbook:dtd:xml:4.1.2"), true);
241+ catchAndAssertEquals(function() {
242+ ISURL.apply(this, []);
243+ }, ERRORS.NA_ERROR);
244+});
245diff --git a/tests/SheetFormulaTest.ts b/tests/SheetFormulaTest.ts
246index c1d2efa..2336543 100644
247--- a/tests/SheetFormulaTest.ts
248+++ b/tests/SheetFormulaTest.ts
249@@ -755,6 +755,14 @@ test("Sheet FV", function(){
250 assertFormulaEquals('=FV(0.05, 1, 66, 25000)', -26316);
251 });
252
253+test("Sheet ISEMAIL", function(){
254+ assertFormulaEquals('=ISEMAIL("[email protected]")', true);
255+});
256+
257+test("Sheet ISURL", function(){
258+ assertFormulaEquals('=ISURL("example.com")', true);
259+});
260+
261 test("Sheet *", function(){
262 assertFormulaEquals('= 10 * 10', 100);
263 assertFormulaEquals('= 10 * 0', 0);