├── .gitignore ├── src ├── index.js ├── debounce.js ├── elite-form.js ├── elite-form-rules.js └── elite-input.js ├── package.json ├── README.md └── __tests__ └── unitTests.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import { EliteInput } from 'elite-forms/src/elite-input'; 2 | import { EliteForm } from 'elite-forms/src/elite-form'; 3 | 4 | export { EliteForm, EliteInput } 5 | 6 | -------------------------------------------------------------------------------- /src/debounce.js: -------------------------------------------------------------------------------- 1 | function debounce(func, wait) { 2 | let timeout 3 | return function(...args) { 4 | const context = this 5 | clearTimeout(timeout) 6 | timeout = setTimeout(() => func.apply(context, args), wait) 7 | } 8 | } 9 | 10 | export default debounce -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elite-forms", 3 | "version": "0.0.1", 4 | "description": "\"Provides customizable web component for forms/input fields with built in validation using LitElements\"", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/oslabs-beta/EliteForms.git" 12 | }, 13 | "author": "Ammar Doo, Esther Cho, Patrick Mojica, Shinhae Na", 14 | "license": "ISC", 15 | "bugs": { 16 | "url": "https://github.com/oslabs-beta/EliteForms/issues" 17 | }, 18 | "homepage": "https://github.com/oslabs-beta/EliteForms#readme", 19 | "dependencies": { 20 | "lit": "^2.2.2" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/elite-form.js: -------------------------------------------------------------------------------- 1 | import {LitElement, html, css} from 'lit'; 2 | import {styleMap} from 'lit/directives/style-map.js'; 3 | 4 | export class EliteForm extends LitElement { 5 | static styles = css` 6 | 7 | .button-container { 8 | display: flex; 9 | flex-direction: column; 10 | justify-content: center; 11 | align-items: center; 12 | } 13 | .submitBtn { 14 | font-family: 'Roboto', sans-serif; 15 | align-items: center; 16 | background-color: #ffffff; 17 | border: 1px solid rgba(39, 48, 152, 0.5); 18 | border-radius: .25rem; 19 | box-shadow: rgba(39, 48, 152, 0.1) 0 1px 3px 0; 20 | box-sizing: border-box; 21 | color: rgba(39, 48, 152, 0.85); 22 | cursor: pointer; 23 | display: inline-flex; 24 | font-size: 20px; 25 | font-weight: 600; 26 | letter-spacing: 0.1em; 27 | justify-content: center; 28 | line-height: 1.25; 29 | margin: 0; 30 | min-height: 3rem; 31 | padding: calc(.875rem - 1px) calc(1.5rem - 1px); 32 | position: relative; 33 | text-decoration: none; 34 | transition: all 250ms; 35 | user-select: none; 36 | -webkit-user-select: none; 37 | touch-action: manipulation; 38 | vertical-align: baseline; 39 | width: auto; 40 | } 41 | .submitBtn:hover, 42 | .submitBtn:focus { 43 | border-color: 1px solid rgba(39, 48, 152, 0.5); 44 | box-shadow: rgba(13, 242, 253, 0.3) 0 4px 12px; 45 | color: rgba(49, 78, 255, 0.85); 46 | } 47 | .submitBtn:hover { 48 | transform: translateY(-1px); 49 | } 50 | .submitBtn:active { 51 | background-color: #7a8fff; 52 | border-color: rgba(0, 0, 0, 0.15); 53 | box-shadow: rgba(0, 0, 0, 0.06) 0 2px 4px; 54 | color: rgba(39, 48, 152, 0.85); 55 | transform: translateY(0); 56 | } 57 | `; 58 | 59 | static properties = { 60 | onSubmit: {}, 61 | arr: {}, 62 | error: {}, 63 | buttonName: {}, 64 | badFormMessage: {}, 65 | } 66 | 67 | constructor() { 68 | super(); 69 | this.error = true 70 | this.buttonName = 'Submit' 71 | this.badFormMessage = '!! Missing Fields !!' 72 | this.buttonStyles = ''; 73 | this.badFormMessageStyles = ''; 74 | this.buttonContainerStyles = ''; 75 | } 76 | 77 | render() { 78 | return html` 79 |
82 | 83 | 89 |
94 | ${this.badFormMessage} 95 |
96 |
97 | `; 98 | } 99 | 100 | validateForm(callback, arr) { 101 | const fields = this.querySelectorAll('.elite-input') 102 | let fieldsCheck = true 103 | const cache = {} 104 | 105 | for (let singleElement in fields) { 106 | const currentElement = fields[singleElement] 107 | if (!isNaN(Number(singleElement))) { 108 | if (Array.isArray(arr)) { 109 | if (currentElement.eliteForm && arr.includes(currentElement.id)) { 110 | if (!currentElement.value) { 111 | currentElement.handleValidation() 112 | } 113 | cache[currentElement.id] = currentElement.value 114 | if (Object.keys(currentElement.error).length > 0) fieldsCheck = false 115 | }else if (arr.includes(currentElement.id)) { 116 | const { id, value } = fields[singleElement] 117 | cache[id] = value 118 | } 119 | } else if (currentElement.eliteForm) { 120 | if (!currentElement.value) { 121 | currentElement.handleValidation() 122 | } 123 | cache[currentElement.id] = currentElement.value 124 | if (Object.keys(currentElement.error).length > 0) fieldsCheck = false 125 | } else { 126 | const { id, value } = fields[singleElement] 127 | cache[id] = value 128 | } 129 | } 130 | } 131 | if (fieldsCheck) { 132 | this.error = true 133 | callback(cache) 134 | } else { 135 | this.error = false 136 | } 137 | } 138 | } 139 | 140 | window.customElements.define('elite-form', EliteForm); 141 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EliteForms 2 | 3 | A robust form library for Lit that enriches input components with easy-to-use data validation features. 4 | 5 | ## Installation 6 | 7 | 1) ```npm install elite-forms``` 8 | 2) ```import 'elite-forms'``` into your project file 9 | 10 | ## Usage 11 | For full documentation, please visit our website 12 | ### Using the elite-form tag ### 13 | 14 | Our custom element allows you to validate the entire form before a submit event and comes equipped with a Submit button. 15 | 16 | ### Using the elite-input tag: ### 17 | 18 | Use our custom tag with your desired type attribute to create any input field. 19 | Types supported include: 20 | * Text 21 | * Email 22 | * Password 23 | * Date 24 | * Radio 25 | * Checkbox 26 | * Select 27 | * Range 28 | * Textarea 29 | 30 | #### Example of text input: #### 31 | ```javascript 32 | 44 | ``` 45 | 46 | #### Example of checkbox input: #### 47 | ```javascript 48 | 63 | ``` 64 | 65 | ### Field Validation: ### 66 | 67 | Include the validationRules attribute in your element with the rules you’d like applied to the form field. 68 | 69 | #### Example of alphanumeric rule: #### 70 | ```javascript 71 | 82 | ``` 83 | #### Example of reqUpper, reqLower, reqSpecialChar rules: #### 84 | ```javascript 85 | 97 | ``` 98 | 99 | ### Form Validation: ### 100 | 101 | The submit event will not fire successfully unless all fields have passed its validation rules. Our form validator confirms the final state of each element before completing. 102 | 103 | ### Conditional Fields: ### 104 | 105 | To create conditional fields, you must nest your conditional field within the dependent field. 106 | ```javascript 107 | 122 | 136 | 137 | ``` 138 | 139 | ![dessert_conditional](https://user-images.githubusercontent.com/97770491/165827826-21db2ffc-02de-4d8b-825a-a0e302109470.gif) 140 | 141 | 142 | ## Contributing 143 | 144 | We welcome all contributors! 145 | Features + improvements we’ve started or would like to see implemented: 146 | - Model binding 147 | - Typescript support 148 | - Ability to create custom validation rule 149 | - Custom validation error messages 150 | 151 | Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change. 152 | Please make sure to update tests as appropriate. 153 | 154 | https://github.com/oslabs-beta/EliteForms 155 | 156 | ## License 157 | [MIT](https://choosealicense.com/licenses/mit/) 158 | -------------------------------------------------------------------------------- /src/elite-form-rules.js: -------------------------------------------------------------------------------- 1 | const internalValMethods = { 2 | 3 | email: function(node) { // node = the 'this' keyword. we need access to state 4 | let error = true 5 | const name = node.validationName || node.name || node.type 6 | const validEmail = /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/ 7 | 8 | error = !validEmail.test(node.value) 9 | 10 | const err = { 11 | message: error ? `Please enter a valid ${name} address.` : null, 12 | error: error 13 | } 14 | return err // ***** switched this to return the object in order to collate all the errors 15 | }, 16 | 17 | //NOTE***developer needs to use escape variable when writing their custom strings*** 18 | endsWith: function(node, devInput) { // node = the 'this' keyword. we need access to state, devInput = array of strings, represents list of strings that are allowed endings 19 | let error = true 20 | for (let i = 0; i < devInput.length; i++) { 21 | const validEnding = RegExp(String.raw`.*${devInput[i]}$`) 22 | if (validEnding.test(node.value)) { 23 | error = false 24 | i = devInput.length 25 | } 26 | } 27 | const err = { 28 | message: error ? 'This field doesn\'t end with a valid value.' : null, 29 | error: error 30 | } 31 | return err // ***** switched this to return the object in order to collate all the errors 32 | }, 33 | 34 | matches: function(node, devInput) { // node = the 'this' keyword. we need access to state, devInput = array of strings, represents list of strings that are allowed endings 35 | let error 36 | //handle case if developer chooses to pass regex 37 | if (devInput.regex) { 38 | error = !devInput.regex.test(node.value) ? true : false 39 | } 40 | //handle case if developer chooses to pass only strings 41 | if (devInput.type === 'string') { 42 | const validArr = devInput.values 43 | error = true 44 | for (let i = 0; i < validArr.length; i++) { 45 | if (validArr[i] === node.value) { 46 | error = false 47 | i = validArr.length 48 | } 49 | } 50 | } 51 | const err = { 52 | message: error ? `${node.value} is not an allowed value.` : null, 53 | error: error 54 | } 55 | return err // ***** switched this to return the object in order to collate all the errors 56 | }, 57 | 58 | not: function(node, devInput) { // node = the 'this' keyword. we need access to state, devInput = array of strings, represents list of strings that are allowed endings 59 | let error 60 | const name = node.validationName || node.name || node.type 61 | //handle case if developer chooses to pass regex 62 | if (devInput.regex) { 63 | error = devInput.regex.test(node.value) ? true : false 64 | } 65 | //handle case if developer chooses to pass only strings 66 | if (devInput.type === 'string') { 67 | const validArr = devInput.values 68 | error = false 69 | for (let i = 0; i < validArr.length; i++) { 70 | if (validArr[i] === node.value) { 71 | error = true 72 | i = validArr.length 73 | } 74 | } 75 | } 76 | const err = { 77 | message: error ? `${node.value} is not an allowed ${name}.` : null, 78 | error: error 79 | } 80 | return err // ***** switched this to return the object in order to collate all the errors 81 | }, 82 | 83 | required: function(node) { // node = the 'this' keyword. we need access to state 84 | const name = node.validationName || node.name || node.type 85 | const err = { 86 | message: !node.value || (Array.isArray(node.value) && !node.value.length) ? `${name} is required.` : null, 87 | error: !node.value || (Array.isArray(node.value) && !node.value.length) ? true : false 88 | } 89 | return err // ***** switched this to return the object in order to collate all the errors 90 | }, 91 | 92 | alphanumeric: function(node) { 93 | const alphanumericRegex = /[^a-zA-Z0-9]+/g 94 | const name = node.validationName || node.name || node.type 95 | const error = alphanumericRegex.test(node.value) 96 | const err = { 97 | message: error ? `${name} can only contain letters and numbers` : null, 98 | error: error 99 | } 100 | // console.log(err) 101 | return err 102 | }, 103 | 104 | alpha: function(node) { 105 | const name = node.validationName || node.name || node.type 106 | const alphaRegex = /[^a-zA-Z]+/g 107 | const error = alphaRegex.test(node.value) 108 | const err = { 109 | message: error ? `${name} can only contain alphabetical characters` : null, 110 | error: error 111 | } 112 | return err 113 | }, 114 | 115 | number: function(node) { 116 | const name = node.validationName || node.name || node.type 117 | const numberRegex = /[^0-9]+/g 118 | const error = numberRegex.test(node.value) 119 | const err = { 120 | message: error ? `${name} must be a number` : null, 121 | error: error 122 | } 123 | return err 124 | }, 125 | password: function(node) { 126 | const name = node.validationName || node.name || node.type 127 | const passwordRegex = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&*]).{8,}$/; 128 | const error = !passwordRegex.test(node.value) 129 | const err = { 130 | message: error ? `${name} must be 8 characters long and contain at least: 1 number,\n1 uppercase character,\n1 lowercase character,\n1 special character (!,@,#,$,%,^,&,*)` : null, 131 | error: error 132 | } 133 | return err 134 | }, 135 | 136 | min: function(node, devInput) { 137 | let error = true; 138 | const name = node.validationName || node.name || node.type 139 | let message 140 | 141 | if (node.type === 'range') { 142 | const value = Number(node.value) 143 | message = `${name} must be greater than ${devInput}` 144 | if (value >= devInput) error = false 145 | } else { 146 | message = typeof(node.value) === 'string' ? `${name} must be at least ${devInput} characters long` : `You must select at least ${devInput} ${name} ` 147 | if (node.value && node.value.length >= devInput){ 148 | error = false; 149 | } 150 | } 151 | const err = { 152 | message: error ? message : null, 153 | error: error 154 | } 155 | return err; 156 | }, 157 | 158 | max: function(node, devInput) { 159 | let error = false; 160 | const name = node.validationName || node.name || node.type; 161 | let message 162 | 163 | if (node.type === 'range') { 164 | const value = Number(node.value) 165 | message = `${name} must be less than ${devInput}` 166 | if (value > devInput) error = true 167 | } else { 168 | message = typeof(node.value) === 'string' ? `The maximun number of characters of ${name} is ${devInput} characters long` : `You may only select ${devInput} ${name}` 169 | if (node.value && node.value.length > devInput){ 170 | error = true; 171 | } 172 | } 173 | const err = { 174 | message: error ? message : null, 175 | error: error 176 | } 177 | return err; 178 | }, 179 | 180 | minWords: function(node, devInput) { 181 | const regex = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g; 182 | const wordArr = node.value.replace(regex, '').split(' ').filter(elem => elem); 183 | let error = false; 184 | const name = node.validationName || node.name || node.type; 185 | const message = typeof(node.value) === 'string' ? `The minimun number of words of ${name} is ${devInput} words` : `You may only select ${devInput} ${name}` 186 | if (wordArr.length < devInput){ 187 | error = true; 188 | } 189 | const err = { 190 | message: error ? message : null, 191 | error: error 192 | } 193 | return err; 194 | }, 195 | 196 | maxWords: function(node, devInput) { 197 | const regex = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g; 198 | const wordArr = node.value.replace(regex, '').split(' ').filter(elem => elem); 199 | let error = false; 200 | const name = node.validationName || node.name || node.type; 201 | const message = typeof(node.value) === 'string' ? `The maximun number of words of ${name} is ${devInput} words` : `You may only select ${devInput} ${name}` 202 | if (wordArr.length > devInput){ 203 | error = true; 204 | } 205 | const err = { 206 | message: error ? message : null, 207 | error: error 208 | } 209 | return err; 210 | }, 211 | 212 | between: function(node, devInput) { // devInput is an array of [min, max] 213 | let error = true; 214 | const name = node.validationName || node.name || node.type; 215 | let message 216 | 217 | if (node.type === 'range') { 218 | const value = Number(node.value) 219 | message = `${name} must be between ${devInput[0]} and ${devInput[1]}` 220 | if (value >= devInput[0] && value <= devInput[1]) error = false 221 | } else { 222 | message = `${name} must be in between ${devInput[0]} and ${devInput[1]} characters long` 223 | if (node.value && node.value.length >= devInput[0] && node.value.length <= devInput[1]) { 224 | error = false; 225 | } 226 | } 227 | const err = { 228 | message: error ? message : null, 229 | error: error 230 | } 231 | return err; 232 | }, 233 | 234 | checkExisting: async function(node, devInput) { 235 | let error = false 236 | // console.log('validation node value: ', node.value) 237 | // console.log('fetch func results: ', devInput(node.value)) 238 | const result = await devInput(node.value) 239 | if (node.name === 'username' && result === true) { 240 | error = true 241 | const err = { 242 | message: error ? `Sorry, '${node.value}' is already taken.` : null, 243 | error: error 244 | } 245 | // console.log(`${node.value} error: `, err) 246 | return err; 247 | } else if (node.name === 'email' && result === true) { 248 | error = true 249 | const err = { 250 | message: error ? `${node.value} belongs to an existing account. Please sign in.` : null, 251 | error: error 252 | } 253 | // console.log(err) 254 | return err 255 | } 256 | return { 257 | message: null, 258 | error: false 259 | } 260 | }, 261 | 262 | reqNumber: function(node) { 263 | let error = true 264 | const name = node.validationName || node.name || node.type 265 | const validEmail = /.*[0-9].*/ 266 | 267 | error = !validEmail.test(node.value) 268 | 269 | const err = { 270 | message: error ? `${name} must contain at least one number` : null, 271 | error: error 272 | } 273 | return err // ***** switched this to return the object in order to collate all the errors 274 | }, 275 | 276 | reqUpper: function(node) { 277 | let error = true 278 | const name = node.validationName || node.name || node.type 279 | const validEmail = /.*[A-Z].*/ 280 | 281 | error = !validEmail.test(node.value) 282 | 283 | const err = { 284 | message: error ? `${name} must contain at least one uppercase letter` : null, 285 | error: error 286 | } 287 | return err // ***** switched this to return the object in order to collate all the errors 288 | }, 289 | 290 | reqLower: function(node) { 291 | let error = true 292 | const name = node.validationName || node.name || node.type 293 | const validEmail = /.*[a-z].*/ 294 | 295 | error = !validEmail.test(node.value) 296 | 297 | const err = { 298 | message: error ? `${name} must contain at least one lowercase letter` : null, 299 | error: error 300 | } 301 | return err // ***** switched this to return the object in order to collate all the errors 302 | }, 303 | 304 | reqSpecialChar: function(node) { 305 | let error = true 306 | const name = node.validationName || node.name || node.type 307 | const validEmail = /.*[!@#$%^&*?].*/ 308 | 309 | error = !validEmail.test(node.value) 310 | 311 | const err = { 312 | message: error ? `${name} must contain at least one special character (! @ # $ % ^ & * ?)` : null, 313 | error: error 314 | } 315 | return err // ***** switched this to return the object in order to collate all the errors 316 | }, 317 | 318 | before: function(node, devInput) { 319 | let error = true; 320 | const name = node.validationName || node.name || node.type 321 | let message 322 | 323 | //convert input date to year month day 324 | const { value } = node 325 | console.log(value) 326 | let year = '' 327 | let month = '' 328 | let day = '' 329 | let dashCount = 0 330 | for (let i = 0; i < value.length; i++) { 331 | if (value[i] === '-') dashCount += 1 332 | else if (dashCount === 0) year += value[i] 333 | else if (dashCount === 1) month += value[i] 334 | else day += value[i] 335 | } 336 | year = Number(year) 337 | month = Number(month) 338 | day = Number(day) 339 | 340 | if (year < devInput[0] || (year === devInput[0] && month < devInput[1]) || (year === devInput[0] && month === devInput[1] && day <= devInput[2])) error = false 341 | let dat = devInput[0].toString() 342 | if (devInput[1]) dat = devInput[1].toString() + '/' + dat 343 | if (devInput[2]) dat = devInput[1].toString() + '/' + devInput[2].toString() + '/' + devInput[0].toString() 344 | message = `${name} must be before ${dat}` 345 | 346 | const err = { 347 | message: error ? message : null, 348 | error: error 349 | } 350 | return err; 351 | }, 352 | 353 | after: function(node, devInput) { 354 | let error = true; 355 | const name = node.validationName || node.name || node.type 356 | let message 357 | 358 | //convert input date to year month day 359 | const { value } = node 360 | let year = '' 361 | let month = '' 362 | let day = '' 363 | let dashCount = 0 364 | for (let i = 0; i < value.length; i++) { 365 | if (value[i] === '-') dashCount += 1 366 | else if (dashCount === 0) year += value[i] 367 | else if (dashCount === 1) month += value[i] 368 | else day += value[i] 369 | } 370 | year = Number(year) 371 | month = Number(month) 372 | day = Number(day) 373 | 374 | if (year > devInput[0] || (year === devInput[0] && month > devInput[1]) || (year === devInput[0] && month === devInput[1] && day >= devInput[2])) error = false 375 | let dat = devInput[0].toString() 376 | if (devInput[1]) dat = devInput[1].toString() + '/' + dat 377 | if (devInput[2]) dat = devInput[1].toString() + '/' + devInput[2].toString() + '/' + devInput[0].toString() 378 | message = `${name} must be after ${dat}` 379 | 380 | const err = { 381 | message: error ? message : null, 382 | error: error 383 | } 384 | return err; 385 | }, 386 | } 387 | 388 | export default internalValMethods; -------------------------------------------------------------------------------- /src/elite-input.js: -------------------------------------------------------------------------------- 1 | import {LitElement, html, css} from 'lit'; 2 | import {styleMap} from 'lit/directives/style-map.js'; 3 | import internalValMethods from 'elite-forms/src/elite-form-rules' 4 | import debounce from 'elite-forms/src/debounce' 5 | 6 | export class EliteInput extends LitElement { 7 | static styles = css` 8 | 9 | :host { 10 | font-family: 'Roboto', sans-serif; 11 | color: #595b5e; 12 | } 13 | .elite-input-container { 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: space-between; 17 | padding: 10px; 18 | width: 400pt; 19 | } 20 | label { 21 | font-size: 1.3em; 22 | font-weight: bold; 23 | letter-spacing: 0.1em; 24 | padding-bottom: 0.3em; 25 | } 26 | .text-input, .radio-checkbox-container, textarea, select { 27 | font-family: 'Roboto', sans-serif; 28 | background-color: #ffffff; 29 | border: 1px solid rgba(39, 48, 152, 0.3); 30 | border-radius: .25rem; 31 | box-shadow: rgba(39, 48, 152, 0.1) 0 1px 3px 0; 32 | box-sizing: border-box; 33 | color: #595b5e; 34 | font-size: 16px; 35 | line-height: 1.25; 36 | margin: 0; 37 | min-height: 3rem; 38 | padding: calc(.875rem - 1px) calc(1.5rem - 1px); 39 | } 40 | .text-input:focus, textarea:focus, select:focus { 41 | outline: 1px solid rgba(13, 242, 253, 0.8); 42 | } 43 | .note, .show-word-count, .error { 44 | padding-top: 10px; 45 | } 46 | .note, .show-word-count { 47 | color: rgba(39, 48, 152, 0.85); 48 | } 49 | ul.error { 50 | color: rgb(49, 78, 255); 51 | padding: 10pt, 0, 0, 10pt; 52 | list-style-type: "✕ "; 53 | } 54 | .range-minmax-indexbox { 55 | display: flex; 56 | justify-content: space-between; 57 | font-weight: 600; 58 | margin-bottom: 1em; 59 | span:first-child{ 60 | margin-left: 10px; 61 | } 62 | } 63 | .range-valuebox { 64 | font-size: 1.5em; 65 | color: rgb(39, 48, 152); 66 | font-weight: 600; 67 | display: flex; 68 | justify-content: center; 69 | margin-top: 1em; 70 | } 71 | .range-input { 72 | -webkit-appearance: none; 73 | background-color: rgba(39, 48, 152, 0.5); 74 | height: 2px; 75 | border-radius: 5px; 76 | outline: 0; 77 | } 78 | .range-input::-webkit-slider-thumb { 79 | -webkit-appearance: none; 80 | background-color: rgba(49, 78, 255, 0.8); 81 | border: 1px solid rgba(13, 242, 253, 0.8); 82 | width: 12px; 83 | height: 20px; 84 | border-radius: 20%; 85 | cursor: pointer; 86 | transition: .3s ease-in-out; 87 | } 88 | 89 | input[type='checkbox'] { 90 | height: 15px; 91 | width: 15px; 92 | -webkit-appearance: none; 93 | -moz-appearance: none; 94 | -o-appearance: none; 95 | appearance: none; 96 | border: 1px solid rgba(39, 48, 152, 0.5); 97 | outline: none; 98 | transition-duration: 0.3s; 99 | cursor: pointer; 100 | margin-right: 0.5em; 101 | } 102 | input[type='checkbox']:checked { 103 | border: 1px solid #0df2fd; 104 | background-color: rgba(49, 78, 255, 0.8); 105 | } 106 | input[type='radio'] { 107 | height: 15px; 108 | width: 15px; 109 | border-radius: 100%; 110 | -webkit-appearance: none; 111 | -moz-appearance: none; 112 | -o-appearance: none; 113 | appearance: none; 114 | border: 1px solid rgba(39, 48, 152, 0.5); 115 | outline: none; 116 | transition-duration: 0.3s; 117 | cursor: pointer; 118 | margin-right: 0.5em; 119 | } 120 | input[type='radio']:checked { 121 | border: 1px solid #0df2fd; 122 | background-color: rgba(49, 78, 255, 0.8); 123 | } 124 | .options { 125 | margin-bottom: 0.2em; 126 | display: flex; 127 | justify-items: center; 128 | } 129 | `; 130 | 131 | static properties = { 132 | id: {}, 133 | name: {}, 134 | class: {}, 135 | label: {}, 136 | name: {}, 137 | placeholder: {}, 138 | type: {}, 139 | note: {}, 140 | validationRules: {}, 141 | errorBehavior: {}, 142 | validationName: {}, 143 | options: {}, 144 | optionGroup: {}, 145 | defaultHidden: {}, 146 | min: {}, 147 | max: {}, 148 | showIndex: {}, 149 | showVal: {}, 150 | row: {}, 151 | cols: {}, 152 | showWordCount: {}, 153 | conditional: {} 154 | } 155 | 156 | static state = { 157 | internalValMethods: internalValMethods, 158 | debounce: debounce 159 | } 160 | 161 | constructor() { 162 | super(); 163 | this.id = ''; 164 | this.class = ''; 165 | this.label = ''; 166 | this.name = ''; 167 | this.placeholder = ''; 168 | this.type = 'text'; 169 | this.note = ''; 170 | this.showIndex = false; 171 | this.showVal = false; 172 | this.defaultHidden = ' select one option' 173 | this.row = '4'; 174 | this.cols = '50'; 175 | this.showWordCount = true; 176 | this.error = {}; 177 | this.styles = ''; 178 | this.labelStyles = ''; 179 | this.inputStyles = ''; 180 | this.noteStyles = ''; 181 | this.errorStyles = ''; 182 | this.showWordCountStyles = ''; 183 | this.conditionalBool = true; 184 | this.eliteInputContainerStyles = ''; 185 | this.radioCheckboxContainerStyles = ''; 186 | this.optionsStyles = ''; 187 | this.rangeMinmaxIndexboxStyles = ''; 188 | this.rangeValueboxStyles = ''; 189 | } 190 | 191 | render() { 192 | 193 | const errorsArr = [] 194 | for (let err in this.error) { 195 | errorsArr.push(html`
  • ${this.error[err]}
  • `) 196 | } 197 | const error = html` 198 |
      201 | ${errorsArr} 202 |
    203 | ` 204 | const label = html` 205 | ` 210 | 211 | const note = html` 212 |
    216 | ${this.note} 217 |
    ` 218 | 219 | if (this.type === 'radio' || this.type === 'checkbox') { 220 | return html` 221 |
    222 | ${label} 223 |
    229 | ${this.options.map((option) => html ` 230 |
    233 | ${option.option}
    240 |
    241 | ` 242 | )} 243 |
    244 | ${note} 245 | ${error} 246 |
    247 |
    248 | 249 | 250 |
    251 | `; 252 | } 253 | else if (this.type === 'select') { 254 | if (this.optionGroup) { 255 | const optionGroups = Object.entries(this.optionGroup) 256 | return html ` 257 |
    258 | ${label} 259 | 280 | ${note} 281 | ${error} 282 |
    283 | ` 284 | } else { 285 | return html ` 286 |
    287 | ${label} 288 | 299 | ${note} 300 | ${error} 301 |
    302 | ` 303 | } 304 | } 305 | else if (this.type === 'textarea') { 306 | return html ` 307 |
    308 | ${label} 309 | 319 |
    323 | Current word count: ${this.countWords()} 324 |
    325 | ${note} 326 | ${error} 327 |
    328 | ` 329 | } 330 | else if (this.type === 'range'){ 331 | return html` 332 |
    333 | ${label} 334 |
    338 | ${this.min}${this.max} 339 |
    340 | 350 | 355 | ${this.value ? this.value : "slide it"} 356 | 357 | ${note} 358 | ${error} 359 |
    360 | `; 361 | } 362 | else { 363 | return html` 364 |
    365 | ${label} 366 | 376 | ${note} 377 | ${error} 378 |
    379 |
    380 | 381 |
    382 | `; 383 | } 384 | } 385 | 386 | handleConditional() { 387 | if (this.value == this.conditional[0]) { 388 | this.conditionalBool = false 389 | } else { 390 | this.conditionalBool = true 391 | } 392 | } 393 | 394 | countWords() { 395 | if (!this.value) { 396 | return 0; 397 | } 398 | else { 399 | const regex = /[!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g; 400 | const wordArr = this.value.replace(regex, '').split(' ').filter(elem => elem); 401 | return wordArr.length; 402 | } 403 | } 404 | 405 | handleBox(event) { 406 | const form = this.shadowRoot.querySelectorAll(`.${this.name}`) 407 | console.log('form: ', form) 408 | const response = [] 409 | for (let input in form) { 410 | if (!isNaN(Number(input))) { 411 | const { checked, value } = form[input] 412 | if (checked) response.push(value) 413 | else { 414 | response.slice(response.indexOf(value),1) 415 | } 416 | } 417 | } 418 | 419 | this.value = response 420 | console.log(this.value) 421 | if (this.conditional) { 422 | this.handleConditional() 423 | } 424 | this.handleValidation() 425 | } 426 | 427 | withDebounce = debounce(() => this.handleValidation(), 500) 428 | 429 | handleBlur(event) { 430 | if (this.errorBehavior === 'blur') { 431 | const { value } = event.target; 432 | this.value = value 433 | if (this.conditional) { 434 | this.handleConditional() 435 | } 436 | this.handleValidation() 437 | } 438 | } 439 | 440 | handleInput(event) { 441 | const { value } = event.target; 442 | this.value = value 443 | if (this.errorBehavior === 'debounce') { 444 | if (this.conditional) { 445 | this.handleConditional() 446 | } 447 | this.withDebounce() 448 | } else { 449 | if (this.errorBehavior !== 'blur') { 450 | if (this.conditional) { 451 | this.handleConditional() 452 | } 453 | this.handleValidation() 454 | } 455 | } 456 | } 457 | 458 | handleValidation() { 459 | const error = {} 460 | for (let rule in this.validationRules) { 461 | if (rule === 'checkExisting') { 462 | this.handdleAsyncValidation() 463 | } 464 | const result = internalValMethods[rule](this, this.validationRules[rule]) 465 | if (result.error) { 466 | error[rule] = result.message 467 | } 468 | } 469 | this.error = error 470 | this.requestUpdate() 471 | } 472 | 473 | async handdleAsyncValidation() { 474 | const error = {} 475 | for (let rule in this.validationRules) { 476 | const result = await internalValMethods[rule](this, this.validationRules[rule]) 477 | if (result.error) { 478 | error[rule] = result.message 479 | } 480 | } 481 | this.error = error 482 | this.requestUpdate() 483 | } 484 | } 485 | 486 | window.customElements.define('elite-input', EliteInput) -------------------------------------------------------------------------------- /__tests__/unitTests.js: -------------------------------------------------------------------------------- 1 | // below are unit tests for methods inside internalValMethod object. import internalValMethod object 2 | // into this file, install jest, and add script for jest into package.json file to run 3 | 4 | describe('Validation Rules Unit Tests', () => { 5 | 6 | const noError = { 7 | message: null, 8 | error: false 9 | } 10 | 11 | let node 12 | 13 | beforeEach(() => { 14 | node = { 15 | name: 'test' 16 | } 17 | }) 18 | 19 | describe('email Method Unit Tests', () => { 20 | it('Valid emails return noError object', () => { 21 | node.value = 'test@test.com' 22 | const result = internalValMethods.email(node) 23 | expect(result).toEqual(noError) 24 | }) 25 | 26 | it('Invalid emails return error object', () => { 27 | node.value = 'abcdTEST' 28 | const result1 = internalValMethods.email(node) 29 | expect(typeof result1.message).toBe('string') 30 | expect(result1.error).toBe(true) 31 | 32 | node.value = 'abcdTEST@test' 33 | const result2 = internalValMethods.email(node) 34 | expect(typeof result2.message).toBe('string') 35 | expect(result2.error).toBe(true) 36 | 37 | node.value = 'abcdTEST.test' 38 | const result3 = internalValMethods.email(node) 39 | expect(typeof result3.message).toBe('string') 40 | expect(result3.error).toBe(true) 41 | }) 42 | 43 | it('Undefined email values return error object', () => { 44 | node.value = undefined 45 | const result = internalValMethods.email(node) 46 | expect(typeof result.message).toBe('string') 47 | expect(result.error).toBe(true) 48 | }) 49 | 50 | }) 51 | 52 | describe('endsWith Method Unit Tests', () => { 53 | 54 | const devInput = ['ending', 'something'] 55 | 56 | it('Valid strings return noError object', () => { 57 | node.value = 'testending' 58 | const result1 = internalValMethods.endsWith(node, devInput) 59 | expect(result1).toEqual(noError) 60 | 61 | node.value = 'testsomething' 62 | const result2 = internalValMethods.endsWith(node, devInput) 63 | expect(result2).toEqual(noError) 64 | }) 65 | 66 | it('Invalid strings return error object', () => { 67 | node.value = 'testend' 68 | const result1 = internalValMethods.endsWith(node, devInput) 69 | expect(typeof result1.message).toBe('string') 70 | 71 | node.value = 'testsome' 72 | const result2 = internalValMethods.endsWith(node, devInput) 73 | expect(result2.error).toBe(true) 74 | }) 75 | 76 | it('Undefined string values return error object', () => { 77 | node.value = undefined 78 | const result = internalValMethods.endsWith(node, devInput) 79 | expect(typeof result.message).toBe('string') 80 | expect(result.error).toBe(true) 81 | }) 82 | 83 | }) 84 | 85 | describe('matches Method Unit Tests', () => { 86 | 87 | const devInput1 = { 88 | type: 'string', 89 | values: ['foo', 'test'] 90 | } 91 | 92 | it('Valid string matches return noError object', () => { 93 | node.value = 'foo' 94 | const result1 = internalValMethods.matches(node, devInput1) 95 | expect(result1).toEqual(noError) 96 | 97 | node.value = 'test' 98 | const result2 = internalValMethods.matches(node, devInput1) 99 | expect(result2).toEqual(noError) 100 | }) 101 | 102 | it('Invalid string matches return error object', () => { 103 | node.value = 'food' 104 | const result1 = internalValMethods.matches(node, devInput1) 105 | expect(typeof result1.message).toBe('string') 106 | 107 | node.value = 'Test' 108 | const result2 = internalValMethods.matches(node, devInput1) 109 | expect(result2.error).toBe(true) 110 | }) 111 | 112 | it('Undefined string value for string matches return error object', () => { 113 | node.value = undefined 114 | const result = internalValMethods.matches(node, devInput1) 115 | expect(typeof result.message).toBe('string') 116 | expect(result.error).toBe(true) 117 | }) 118 | 119 | const devInput2 = { 120 | regex: /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/ 121 | } 122 | 123 | it('Valid regex matches return noError object', () => { 124 | node.value = 'test@gmail.com' 125 | const result1 = internalValMethods.matches(node, devInput2) 126 | expect(result1).toEqual(noError) 127 | 128 | 129 | node.value = 'foo@bing.com' 130 | const result2 = internalValMethods.matches(node, devInput2) 131 | expect(result2).toEqual(noError) 132 | }) 133 | 134 | it('Invalid regex matches return error object', () => { 135 | node.value = 'foo@test' 136 | const result1 = internalValMethods.matches(node, devInput2) 137 | expect(typeof result1.message).toBe('string') 138 | 139 | node.value = 'test.foo' 140 | const result2 = internalValMethods.matches(node, devInput2) 141 | expect(result2.error).toBe(true) 142 | }) 143 | 144 | it('Undefined string value for regex matches return error object', () => { 145 | node.value = undefined 146 | const result = internalValMethods.matches(node, devInput2) 147 | expect(typeof result.message).toBe('string') 148 | expect(result.error).toBe(true) 149 | }) 150 | }) 151 | 152 | describe('not Method Unit Tests', () => { 153 | 154 | const devInput1 = { 155 | type: 'string', 156 | values: ['foo', 'test'] 157 | } 158 | 159 | it('Valid string entries return noError object', () => { 160 | node.value = 'Test' 161 | const result1 = internalValMethods.not(node, devInput1) 162 | expect(result1).toEqual(noError) 163 | 164 | node.value = 'food' 165 | const result2 = internalValMethods.not(node, devInput1) 166 | expect(result2).toEqual(noError) 167 | }) 168 | 169 | it('Invalid string entries return error object', () => { 170 | node.value = 'foo' 171 | const result1 = internalValMethods.not(node, devInput1) 172 | expect(typeof result1.message).toBe('string') 173 | 174 | node.value = 'test' 175 | const result2 = internalValMethods.not(node, devInput1) 176 | expect(result2.error).toBe(true) 177 | }) 178 | 179 | it('Undefined string value for string entries return error object', () => { 180 | //this is a problem****************** 181 | node.value = undefined 182 | const result = internalValMethods.not(node, devInput1) 183 | expect(typeof result.message).toBe('string') 184 | expect(result.error).toBe(true) 185 | //this is a problem****************** 186 | }) 187 | 188 | const devInput2 = { 189 | regex: /^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/ 190 | } 191 | 192 | it('Valid regex entries return noError object', () => { 193 | node.value = 'test@gmail' 194 | const result1 = internalValMethods.not(node, devInput2) 195 | expect(result1).toEqual(noError) 196 | 197 | 198 | node.value = 'foo.com' 199 | const result2 = internalValMethods.not(node, devInput2) 200 | expect(result2).toEqual(noError) 201 | }) 202 | 203 | it('Invalid regex entries return error object', () => { 204 | node.value = 'testing@gmail.com' 205 | const result1 = internalValMethods.not(node, devInput2) 206 | expect(typeof result1.message).toBe('string') 207 | 208 | node.value = 'foofoo@bing.com' 209 | const result2 = internalValMethods.not(node, devInput2) 210 | expect(result2.error).toBe(true) 211 | }) 212 | 213 | it('Undefined string value for regex entries return error object', () => { 214 | //this is a problem****************** 215 | node.value = undefined 216 | const result = internalValMethods.not(node, devInput2) 217 | expect(typeof result.message).toBe('string') 218 | expect(result.error).toBe(true) 219 | //this is a problem****************** 220 | }) 221 | 222 | }) 223 | 224 | describe('required Method Unit Tests', () => { 225 | it('Valid values return noError object', () => { 226 | node.value = 'foo' 227 | const result1 = internalValMethods.required(node) 228 | expect(result1).toEqual(noError) 229 | 230 | node.value = 'test' 231 | const result2 = internalValMethods.required(node) 232 | expect(result2).toEqual(noError) 233 | }) 234 | 235 | it('Empty string value returns error object', () => { 236 | node.value = '' 237 | const result = internalValMethods.required(node) 238 | expect(typeof result.message).toBe('string') 239 | expect(result.error).toBe(true) 240 | }) 241 | 242 | it('Undefined value returns error object', () => { 243 | node.value = undefined 244 | const result = internalValMethods.required(node) 245 | expect(typeof result.message).toBe('string') 246 | expect(result.error).toBe(true) 247 | }) 248 | }) 249 | 250 | describe('alphanumeric Method Unit Tests', () => { 251 | it('Valid values return noError object', () => { 252 | node.value = 'foo123' 253 | const result1 = internalValMethods.alphanumeric(node) 254 | expect(result1).toEqual(noError) 255 | 256 | node.value = 'F1O2O3' 257 | const result2 = internalValMethods.alphanumeric(node) 258 | expect(result2).toEqual(noError) 259 | 260 | node.value = 'Foo123Test' 261 | const result3 = internalValMethods.alphanumeric(node) 262 | expect(result3).toEqual(noError) 263 | }) 264 | 265 | it('Invalid values return error object', () => { 266 | //this is a problem****************** 267 | node.value = '' 268 | const result1 = internalValMethods.alphanumeric(node) 269 | expect(typeof result1.message).toBe('string') 270 | expect(result1.error).toBe(true) 271 | //this is a problem****************** 272 | 273 | 274 | node.value = 'abcdT12EST@test' 275 | const result2 = internalValMethods.alphanumeric(node) 276 | expect(typeof result2.message).toBe('string') 277 | expect(result2.error).toBe(true) 278 | 279 | node.value = 'ab@34te!s?t' 280 | const result3 = internalValMethods.alphanumeric(node) 281 | expect(typeof result3.message).toBe('string') 282 | expect(result3.error).toBe(true) 283 | }) 284 | 285 | it('Undefined values return error object', () => { 286 | //this is a problem****************** 287 | node.value = undefined 288 | const result = internalValMethods.alphanumeric(node) 289 | expect(typeof result.message).toBe('string') 290 | expect(result.error).toBe(true) 291 | //this is a problem****************** 292 | }) 293 | 294 | }) 295 | 296 | describe('alpha Method Unit Tests', () => { 297 | it('Valid values return noError object', () => { 298 | node.value = 'abcd' 299 | const result1 = internalValMethods.alpha(node) 300 | expect(result1).toEqual(noError) 301 | 302 | node.value = 'foo' 303 | const result2 = internalValMethods.alpha(node) 304 | expect(result2).toEqual(noError) 305 | }) 306 | 307 | it('Invalid values return error object', () => { 308 | //this is a problem****************** 309 | node.value = '' 310 | const result1 = internalValMethods.alpha(node) 311 | expect(typeof result1.message).toBe('string') 312 | expect(result1.error).toBe(true) 313 | //this is a problem****************** 314 | 315 | 316 | node.value = 'abcdTEST@test' 317 | const result2 = internalValMethods.alpha(node) 318 | expect(typeof result2.message).toBe('string') 319 | expect(result2.error).toBe(true) 320 | 321 | node.value = 'ab@te!s?t' 322 | const result3 = internalValMethods.alpha(node) 323 | expect(typeof result3.message).toBe('string') 324 | expect(result3.error).toBe(true) 325 | }) 326 | 327 | it('Undefined values return error object', () => { 328 | //this is a problem****************** 329 | node.value = undefined 330 | const result = internalValMethods.alpha(node) 331 | expect(typeof result.message).toBe('string') 332 | expect(result.error).toBe(true) 333 | //this is a problem****************** 334 | }) 335 | 336 | }) 337 | 338 | describe('number Method Unit Tests', () => { 339 | it('Valid values return noError object', () => { 340 | node.value = '1234' 341 | const result1 = internalValMethods.number(node) 342 | expect(result1).toEqual(noError) 343 | 344 | node.value = '8' 345 | const result2 = internalValMethods.number(node) 346 | expect(result2).toEqual(noError) 347 | }) 348 | 349 | it('Invalid values return error object', () => { 350 | //this is a problem****************** 351 | node.value = '' 352 | const result1 = internalValMethods.number(node) 353 | expect(typeof result1.message).toBe('string') 354 | expect(result1.error).toBe(true) 355 | //this is a problem****************** 356 | 357 | 358 | node.value = 'abc12dTESTt89est' 359 | const result2 = internalValMethods.number(node) 360 | expect(typeof result2.message).toBe('string') 361 | expect(result2.error).toBe(true) 362 | 363 | node.value = 'ab@t234e!s?t' 364 | const result3 = internalValMethods.number(node) 365 | expect(typeof result3.message).toBe('string') 366 | expect(result3.error).toBe(true) 367 | }) 368 | 369 | it('Undefined values return error object', () => { 370 | node.value = undefined 371 | const result = internalValMethods.number(node) 372 | expect(typeof result.message).toBe('string') 373 | expect(result.error).toBe(true) 374 | }) 375 | 376 | }) 377 | 378 | describe('password Method Unit Tests', () => { 379 | it('Valid values return noError object', () => { 380 | node.value = 'aA1!bB2@' 381 | const result1 = internalValMethods.password(node) 382 | expect(result1).toEqual(noError) 383 | 384 | node.value = 'aaAA11!!abc' 385 | const result2 = internalValMethods.password(node) 386 | expect(result2).toEqual(noError) 387 | }) 388 | 389 | it('Invalid values return error object', () => { 390 | node.value = '' 391 | const result1 = internalValMethods.password(node) 392 | expect(typeof result1.message).toBe('string') 393 | expect(result1.error).toBe(true) 394 | 395 | 396 | node.value = 'aA1!' 397 | const result2 = internalValMethods.password(node) 398 | expect(typeof result2.message).toBe('string') 399 | expect(result2.error).toBe(true) 400 | 401 | node.value = 'aaAA11abcd' 402 | const result3 = internalValMethods.password(node) 403 | expect(typeof result3.message).toBe('string') 404 | expect(result3.error).toBe(true) 405 | }) 406 | 407 | it('Undefined values return error object', () => { 408 | node.value = undefined 409 | const result = internalValMethods.password(node) 410 | expect(typeof result.message).toBe('string') 411 | expect(result.error).toBe(true) 412 | }) 413 | 414 | }) 415 | 416 | describe('min Method Unit Tests', () => { 417 | 418 | describe('Testing text type inputs', () => { 419 | 420 | const devInput1 = 5 421 | const devInput2 = 10 422 | 423 | it('Valid strings return noError object', () => { 424 | node.value = 'te$tfoo' 425 | const result1 = internalValMethods.min(node, devInput1) 426 | expect(result1).toEqual(noError) 427 | 428 | node.value = 'te$ts0mething' 429 | const result2 = internalValMethods.min(node, devInput2) 430 | expect(result2).toEqual(noError) 431 | }) 432 | 433 | it('Invalid strings return error object', () => { 434 | node.value = 'te$t' 435 | const result1 = internalValMethods.min(node, devInput1) 436 | expect(typeof result1.message).toBe('string') 437 | 438 | node.value = 'te$ts0me' 439 | const result2 = internalValMethods.min(node, devInput2) 440 | expect(result2.error).toBe(true) 441 | }) 442 | 443 | it('Undefined string values return error object', () => { 444 | node.value = undefined 445 | const result1 = internalValMethods.min(node, devInput1) 446 | expect(typeof result1.message).toBe('string') 447 | expect(result1.error).toBe(true) 448 | 449 | node.value = undefined 450 | const result2 = internalValMethods.min(node, devInput2) 451 | expect(typeof result2.message).toBe('string') 452 | expect(result2.error).toBe(true) 453 | }) 454 | 455 | }) 456 | 457 | describe('Testing range type inputs', () => { 458 | 459 | const devInput1 = 5 460 | const devInput2 = 10 461 | 462 | it('Valid range values return noError object', () => { 463 | node.value = '7' 464 | node.type = 'range' 465 | const result1 = internalValMethods.min(node, devInput1) 466 | expect(result1).toEqual(noError) 467 | 468 | node.value = '17' 469 | node.type = 'range' 470 | const result2 = internalValMethods.min(node, devInput2) 471 | expect(result2).toEqual(noError) 472 | }) 473 | 474 | it('Invalid range values return error object', () => { 475 | node.value = '4' 476 | node.type = 'range' 477 | const result1 = internalValMethods.min(node, devInput1) 478 | expect(typeof result1.message).toBe('string') 479 | 480 | node.value = '8' 481 | node.type = 'range' 482 | const result2 = internalValMethods.min(node, devInput2) 483 | expect(result2.error).toBe(true) 484 | }) 485 | 486 | it('Undefined range values return error object', () => { 487 | node.value = undefined 488 | node.type = 'range' 489 | const result1 = internalValMethods.min(node, devInput1) 490 | expect(typeof result1.message).toBe('string') 491 | expect(result1.error).toBe(true) 492 | 493 | node.value = undefined 494 | node.type = 'range' 495 | const result2 = internalValMethods.min(node, devInput2) 496 | expect(typeof result2.message).toBe('string') 497 | expect(result2.error).toBe(true) 498 | }) 499 | 500 | }) 501 | 502 | describe('Testing checkbox type inputs', () => { 503 | 504 | const devInput1 = 2 505 | const devInput2 = 5 506 | 507 | it('Valid number of selections return noError object', () => { 508 | node.value = ['foo1', 'foo2', 'foo3'] 509 | node.type = 'checkbox' 510 | const result1 = internalValMethods.min(node, devInput1) 511 | expect(result1).toEqual(noError) 512 | 513 | node.value = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5', 'foo6'] 514 | node.type = 'checkbox' 515 | const result2 = internalValMethods.min(node, devInput2) 516 | expect(result2).toEqual(noError) 517 | }) 518 | 519 | it('Invalid number of selections return error object', () => { 520 | node.value = [] 521 | node.type = 'checkbox' 522 | const result1 = internalValMethods.min(node, devInput1) 523 | expect(typeof result1.message).toBe('string') 524 | 525 | node.value = ['foo1', 'foo2', 'foo3'] 526 | node.type = 'checkbox' 527 | const result2 = internalValMethods.min(node, devInput2) 528 | expect(result2.error).toBe(true) 529 | }) 530 | 531 | it('Undefined value return error object', () => { 532 | node.value = undefined 533 | node.type = 'checkbox' 534 | const result1 = internalValMethods.min(node, devInput1) 535 | expect(typeof result1.message).toBe('string') 536 | expect(result1.error).toBe(true) 537 | 538 | node.value = undefined 539 | node.type = 'checkbox' 540 | const result2 = internalValMethods.min(node, devInput2) 541 | expect(typeof result2.message).toBe('string') 542 | expect(result2.error).toBe(true) 543 | }) 544 | 545 | }) 546 | 547 | }) 548 | 549 | describe('max Method Unit Tests', () => { 550 | 551 | describe('Testing text type inputs', () => { 552 | 553 | const devInput1 = 5 554 | const devInput2 = 10 555 | 556 | it('Valid strings return noError object', () => { 557 | node.value = 'te$t' 558 | const result1 = internalValMethods.max(node, devInput1) 559 | expect(result1).toEqual(noError) 560 | 561 | node.value = 'te$ts0me' 562 | const result2 = internalValMethods.max(node, devInput2) 563 | expect(result2).toEqual(noError) 564 | }) 565 | 566 | it('Invalid strings return error object', () => { 567 | node.value = 'te$tf00' 568 | const result1 = internalValMethods.max(node, devInput1) 569 | expect(typeof result1.message).toBe('string') 570 | 571 | node.value = 'te$ts0mething' 572 | const result2 = internalValMethods.max(node, devInput2) 573 | expect(result2.error).toBe(true) 574 | }) 575 | 576 | it('Undefined string values return error object', () => { 577 | //this is a problem****************** 578 | node.value = undefined 579 | const result1 = internalValMethods.max(node, devInput1) 580 | expect(typeof result1.message).toBe('string') 581 | expect(result1.error).toBe(true) 582 | 583 | node.value = undefined 584 | const result2 = internalValMethods.max(node, devInput2) 585 | expect(typeof result2.message).toBe('string') 586 | expect(result2.error).toBe(true) 587 | //this is a problem****************** 588 | }) 589 | 590 | }) 591 | 592 | describe('Testing range type inputs', () => { 593 | 594 | const devInput1 = 5 595 | const devInput2 = 10 596 | 597 | it('Valid range values return noError object', () => { 598 | node.value = '2' 599 | node.type = 'range' 600 | const result1 = internalValMethods.max(node, devInput1) 601 | expect(result1).toEqual(noError) 602 | 603 | node.value = '7' 604 | node.type = 'range' 605 | const result2 = internalValMethods.max(node, devInput2) 606 | expect(result2).toEqual(noError) 607 | }) 608 | 609 | it('Invalid range values return error object', () => { 610 | node.value = '9' 611 | node.type = 'range' 612 | const result1 = internalValMethods.max(node, devInput1) 613 | expect(typeof result1.message).toBe('string') 614 | 615 | node.value = '18' 616 | node.type = 'range' 617 | const result2 = internalValMethods.max(node, devInput2) 618 | expect(result2.error).toBe(true) 619 | }) 620 | 621 | it('Undefined range values return error object', () => { 622 | //this is a problem****************** 623 | node.value = undefined 624 | node.type = 'range' 625 | const result1 = internalValMethods.max(node, devInput1) 626 | expect(typeof result1.message).toBe('string') 627 | expect(result1.error).toBe(true) 628 | 629 | node.value = undefined 630 | node.type = 'range' 631 | const result2 = internalValMethods.max(node, devInput2) 632 | expect(typeof result2.message).toBe('string') 633 | expect(result2.error).toBe(true) 634 | //this is a problem****************** 635 | }) 636 | 637 | }) 638 | 639 | describe('Testing checkbox type inputs', () => { 640 | 641 | const devInput1 = 2 642 | const devInput2 = 5 643 | 644 | it('Valid number of selections return noError object', () => { 645 | node.value = ['foo1', 'foo2'] 646 | node.type = 'checkbox' 647 | const result1 = internalValMethods.max(node, devInput1) 648 | expect(result1).toEqual(noError) 649 | 650 | node.value = ['foo1', 'foo2'] 651 | node.type = 'checkbox' 652 | const result2 = internalValMethods.max(node, devInput2) 653 | expect(result2).toEqual(noError) 654 | }) 655 | 656 | it('Invalid number of selections return error object', () => { 657 | node.value = ['foo1', 'foo2', 'foo3'] 658 | node.type = 'checkbox' 659 | const result1 = internalValMethods.max(node, devInput1) 660 | expect(typeof result1.message).toBe('string') 661 | 662 | node.value = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5', 'foo6'] 663 | node.type = 'checkbox' 664 | const result2 = internalValMethods.max(node, devInput2) 665 | expect(result2.error).toBe(true) 666 | }) 667 | 668 | it('Undefined value return error object', () => { 669 | //this is a problem****************** 670 | node.value = undefined 671 | node.type = 'checkbox' 672 | const result1 = internalValMethods.max(node, devInput1) 673 | expect(typeof result1.message).toBe('string') 674 | expect(result1.error).toBe(true) 675 | 676 | node.value = undefined 677 | node.type = 'checkbox' 678 | const result2 = internalValMethods.max(node, devInput2) 679 | expect(typeof result2.message).toBe('string') 680 | expect(result2.error).toBe(true) 681 | //this is a problem****************** 682 | }) 683 | 684 | }) 685 | 686 | }) 687 | 688 | describe('minWords Method Unit Tests', () => { 689 | 690 | const devInput1 = 5 691 | const devInput2 = 10 692 | 693 | it('Valid strings return noError object', () => { 694 | node.value = 'the quick, brown fox! jumps over the lazy dog' 695 | const result1 = internalValMethods.minWords(node, devInput1) 696 | expect(result1).toEqual(noError) 697 | 698 | node.value = 'the quick, brown fox! jumps over the lazy dog. if the dog reacted, was it lazy?' 699 | const result2 = internalValMethods.minWords(node, devInput2) 700 | expect(result2).toEqual(noError) 701 | }) 702 | 703 | it('Invalid strings return error object', () => { 704 | node.value = 'the quick?' 705 | const result1 = internalValMethods.minWords(node, devInput1) 706 | expect(typeof result1.message).toBe('string') 707 | 708 | node.value = 'the quick brown fox? jumped!' 709 | const result2 = internalValMethods.minWords(node, devInput2) 710 | expect(result2.error).toBe(true) 711 | }) 712 | 713 | it('Undefined string values return error object', () => { 714 | //this is a problem****************** 715 | node.value = undefined 716 | const result = internalValMethods.minWords(node, devInput1) 717 | expect(typeof result.message).toBe('string') 718 | expect(result.error).toBe(true) 719 | //this is a problem****************** 720 | }) 721 | }) 722 | 723 | describe('maxWords Method Unit Tests', () => { 724 | 725 | const devInput1 = 5 726 | const devInput2 = 10 727 | 728 | it('Valid strings return noError object', () => { 729 | node.value = 'test sentance?' 730 | const result1 = internalValMethods.maxWords(node, devInput1) 731 | expect(result1).toEqual(noError) 732 | 733 | node.value = 'a longer. test? sentance! will this work?' 734 | const result2 = internalValMethods.maxWords(node, devInput2) 735 | expect(result2).toEqual(noError) 736 | }) 737 | 738 | it('Invalid strings return error object', () => { 739 | node.value = 'the quick, brown fox! jumps over the lazy dog?' 740 | const result1 = internalValMethods.maxWords(node, devInput1) 741 | expect(typeof result1.message).toBe('string') 742 | 743 | node.value = 'the quick, brown fox! jumps over the lazy dog? if the dog jumps... was it really lazy??' 744 | const result2 = internalValMethods.maxWords(node, devInput2) 745 | expect(result2.error).toBe(true) 746 | }) 747 | 748 | it('Undefined string values return error object', () => { 749 | //this is a problem****************** 750 | node.value = undefined 751 | const result = internalValMethods.maxWords(node, devInput1) 752 | expect(typeof result.message).toBe('string') 753 | expect(result.error).toBe(true) 754 | //this is a problem****************** 755 | }) 756 | }) 757 | 758 | describe('between Method Unit Tests', () => { 759 | 760 | describe('Testing text type inputs', () => { 761 | 762 | const devInput1 = [2,10] 763 | const devInput2 = [5,15] 764 | 765 | it('Valid strings return noError object', () => { 766 | node.value = 'te$t' 767 | const result1 = internalValMethods.between(node, devInput1) 768 | expect(result1).toEqual(noError) 769 | 770 | node.value = 'te$ts0me' 771 | const result2 = internalValMethods.between(node, devInput2) 772 | expect(result2).toEqual(noError) 773 | }) 774 | 775 | it('Invalid strings return error object', () => { 776 | node.value = '!' 777 | const result1 = internalValMethods.between(node, devInput1) 778 | expect(typeof result1.message).toBe('string') 779 | 780 | node.value = 'te$ts0mething12345!!abcd' 781 | const result2 = internalValMethods.between(node, devInput2) 782 | expect(result2.error).toBe(true) 783 | }) 784 | 785 | it('Undefined string values return error object', () => { 786 | //this is a problem****************** 787 | node.value = undefined 788 | const result1 = internalValMethods.between(node, devInput1) 789 | expect(typeof result1.message).toBe('string') 790 | expect(result1.error).toBe(true) 791 | 792 | node.value = undefined 793 | const result2 = internalValMethods.between(node, devInput2) 794 | expect(typeof result2.message).toBe('string') 795 | expect(result2.error).toBe(true) 796 | //this is a problem****************** 797 | }) 798 | 799 | }) 800 | 801 | describe('Testing range type inputs', () => { 802 | 803 | const devInput1 = [2,10] 804 | const devInput2 = [5,15] 805 | 806 | it('Valid range values return noError object', () => { 807 | node.value = '4' 808 | node.type = 'range' 809 | const result1 = internalValMethods.between(node, devInput1) 810 | expect(result1).toEqual(noError) 811 | 812 | node.value = '11' 813 | node.type = 'range' 814 | const result2 = internalValMethods.between(node, devInput2) 815 | expect(result2).toEqual(noError) 816 | }) 817 | 818 | it('Invalid range values return error object', () => { 819 | node.value = '100' 820 | node.type = 'range' 821 | const result1 = internalValMethods.between(node, devInput1) 822 | expect(typeof result1.message).toBe('string') 823 | 824 | node.value = '1' 825 | node.type = 'range' 826 | const result2 = internalValMethods.between(node, devInput2) 827 | expect(result2.error).toBe(true) 828 | }) 829 | 830 | it('Undefined range values return error object', () => { 831 | //this is a problem****************** 832 | node.value = undefined 833 | node.type = 'range' 834 | const result1 = internalValMethods.between(node, devInput1) 835 | expect(typeof result1.message).toBe('string') 836 | expect(result1.error).toBe(true) 837 | 838 | node.value = undefined 839 | node.type = 'range' 840 | const result2 = internalValMethods.between(node, devInput2) 841 | expect(typeof result2.message).toBe('string') 842 | expect(result2.error).toBe(true) 843 | //this is a problem****************** 844 | }) 845 | 846 | }) 847 | 848 | describe('Testing checkbox type inputs', () => { 849 | 850 | const devInput1 = [2,10] 851 | const devInput2 = [5,15] 852 | 853 | it('Valid number of selections return noError object', () => { 854 | node.value = ['foo1', 'foo2', 'foo3'] 855 | node.type = 'checkbox' 856 | const result1 = internalValMethods.between(node, devInput1) 857 | expect(result1).toEqual(noError) 858 | 859 | node.value = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5', 'foo6', 'foo7'] 860 | node.type = 'checkbox' 861 | const result2 = internalValMethods.between(node, devInput2) 862 | expect(result2).toEqual(noError) 863 | }) 864 | 865 | it('Invalid number of selections return error object', () => { 866 | node.value = ['foo1', 'foo2', 'foo3', 'foo4', 'foo5', 'foo6', 'foo7', 'foo8', 'foo9', 'foo10', 'foo11'] 867 | node.type = 'checkbox' 868 | const result1 = internalValMethods.between(node, devInput1) 869 | expect(typeof result1.message).toBe('string') 870 | 871 | node.value = ['foo1', 'foo2'] 872 | node.type = 'checkbox' 873 | const result2 = internalValMethods.between(node, devInput2) 874 | expect(result2.error).toBe(true) 875 | }) 876 | 877 | it('Undefined value return error object', () => { 878 | //this is a problem****************** 879 | node.value = undefined 880 | node.type = 'checkbox' 881 | const result1 = internalValMethods.between(node, devInput1) 882 | expect(typeof result1.message).toBe('string') 883 | expect(result1.error).toBe(true) 884 | 885 | node.value = undefined 886 | node.type = 'checkbox' 887 | const result2 = internalValMethods.between(node, devInput2) 888 | expect(typeof result2.message).toBe('string') 889 | expect(result2.error).toBe(true) 890 | //this is a problem****************** 891 | }) 892 | 893 | }) 894 | 895 | }) 896 | 897 | describe('reqNumber Method Unit Tests', () => { 898 | it('Valid strings return noError object', () => { 899 | node.value = '12345' 900 | const result1 = internalValMethods.reqNumber(node) 901 | expect(result1).toEqual(noError) 902 | 903 | node.value = 'ab!1A$@lkja' 904 | const result2 = internalValMethods.reqNumber(node) 905 | expect(result2).toEqual(noError) 906 | }) 907 | 908 | it('Invalid strings return error object', () => { 909 | node.value = 'abcdTEST' 910 | const result1 = internalValMethods.reqNumber(node) 911 | expect(typeof result1.message).toBe('string') 912 | expect(result1.error).toBe(true) 913 | 914 | node.value = 'ab!A$@lkja' 915 | const result2 = internalValMethods.reqNumber(node) 916 | expect(typeof result2.message).toBe('string') 917 | expect(result2.error).toBe(true) 918 | }) 919 | 920 | it('Undefined values return error object', () => { 921 | node.value = undefined 922 | const result = internalValMethods.reqNumber(node) 923 | expect(typeof result.message).toBe('string') 924 | expect(result.error).toBe(true) 925 | }) 926 | 927 | }) 928 | 929 | describe('reqUpper Method Unit Tests', () => { 930 | it('Valid strings return noError object', () => { 931 | node.value = 'ABCD' 932 | const result1 = internalValMethods.reqUpper(node) 933 | expect(result1).toEqual(noError) 934 | 935 | node.value = 'ab!1A$@lkja' 936 | const result2 = internalValMethods.reqUpper(node) 937 | expect(result2).toEqual(noError) 938 | }) 939 | 940 | it('Invalid strings return error object', () => { 941 | node.value = 'abcd1234' 942 | const result1 = internalValMethods.reqUpper(node) 943 | expect(typeof result1.message).toBe('string') 944 | expect(result1.error).toBe(true) 945 | 946 | node.value = 'ab!1$@lkja' 947 | const result2 = internalValMethods.reqUpper(node) 948 | expect(typeof result2.message).toBe('string') 949 | expect(result2.error).toBe(true) 950 | }) 951 | 952 | it('Undefined values return error object', () => { 953 | node.value = undefined 954 | const result = internalValMethods.reqUpper(node) 955 | expect(typeof result.message).toBe('string') 956 | expect(result.error).toBe(true) 957 | }) 958 | 959 | }) 960 | 961 | describe('reqLower Method Unit Tests', () => { 962 | it('Valid strings return noError object', () => { 963 | node.value = 'abcd' 964 | const result1 = internalValMethods.reqLower(node) 965 | expect(result1).toEqual(noError) 966 | 967 | node.value = 'BC!S$1a2AS32' 968 | const result2 = internalValMethods.reqLower(node) 969 | expect(result2).toEqual(noError) 970 | }) 971 | 972 | it('Invalid strings return error object', () => { 973 | node.value = 'ABCD1234' 974 | const result1 = internalValMethods.reqLower(node) 975 | expect(typeof result1.message).toBe('string') 976 | expect(result1.error).toBe(true) 977 | 978 | node.value = 'BC!S$12AS32' 979 | const result2 = internalValMethods.reqLower(node) 980 | expect(typeof result2.message).toBe('string') 981 | expect(result2.error).toBe(true) 982 | }) 983 | 984 | it('Undefined values return error object', () => { 985 | //this is a problem****************** 986 | node.value = undefined 987 | const result = internalValMethods.reqLower(node) 988 | expect(typeof result.message).toBe('string') 989 | expect(result.error).toBe(true) 990 | //this is a problem****************** 991 | }) 992 | 993 | }) 994 | 995 | describe('reqSpecialChar Method Unit Tests', () => { 996 | it('Valid strings return noError object', () => { 997 | node.value = '!@#$' 998 | const result1 = internalValMethods.reqSpecialChar(node) 999 | expect(result1).toEqual(noError) 1000 | 1001 | node.value = 'ab1A$lkja' 1002 | const result2 = internalValMethods.reqSpecialChar(node) 1003 | expect(result2).toEqual(noError) 1004 | }) 1005 | 1006 | it('Invalid strings return error object', () => { 1007 | node.value = 'abcd1234' 1008 | const result1 = internalValMethods.reqSpecialChar(node) 1009 | expect(typeof result1.message).toBe('string') 1010 | expect(result1.error).toBe(true) 1011 | 1012 | node.value = 'ab1lkja' 1013 | const result2 = internalValMethods.reqSpecialChar(node) 1014 | expect(typeof result2.message).toBe('string') 1015 | expect(result2.error).toBe(true) 1016 | }) 1017 | 1018 | it('Undefined values return error object', () => { 1019 | node.value = undefined 1020 | const result = internalValMethods.reqSpecialChar(node) 1021 | expect(typeof result.message).toBe('string') 1022 | expect(result.error).toBe(true) 1023 | }) 1024 | 1025 | }) 1026 | 1027 | describe('before Method Unit Tests', () => { 1028 | describe('If only YEAR is provided', () => { 1029 | 1030 | const devInput = [2020] 1031 | 1032 | it('Valid dates return noError object', () => { 1033 | node.value = '2000-02-25' 1034 | const result1 = internalValMethods.before(node, devInput) 1035 | expect(result1).toEqual(noError) 1036 | 1037 | node.value = '2019-12-31' 1038 | const result2 = internalValMethods.before(node, devInput) 1039 | expect(result2).toEqual(noError) 1040 | }) 1041 | 1042 | it('Invalid dates return error object', () => { 1043 | node.value = '2023-01-20' 1044 | const result1 = internalValMethods.before(node, devInput) 1045 | expect(typeof result1.message).toBe('string') 1046 | expect(result1.error).toBe(true) 1047 | 1048 | node.value = '2020-01-01' 1049 | const result2 = internalValMethods.before(node, devInput) 1050 | expect(typeof result2.message).toBe('string') 1051 | expect(result2.error).toBe(true) 1052 | }) 1053 | 1054 | it('Undefined date values return error object', () => { 1055 | //this HHHUUUGGGEEE is a problem****************** 1056 | node.value = undefined 1057 | const result = internalValMethods.before(node, devInput) 1058 | expect(typeof result.message).toBe('string') 1059 | expect(result.error).toBe(true) 1060 | //this HHHUUUGGGEEE is a problem****************** 1061 | }) 1062 | }) 1063 | 1064 | describe('If YEAR and MONTH are provided', () => { 1065 | 1066 | const devInput = [2020, 4] 1067 | 1068 | it('Valid dates return noError object', () => { 1069 | node.value = '2000-02-25' 1070 | const result1 = internalValMethods.before(node, devInput) 1071 | expect(result1).toEqual(noError) 1072 | 1073 | node.value = '2020-03-31' 1074 | const result2 = internalValMethods.before(node, devInput) 1075 | expect(result2).toEqual(noError) 1076 | }) 1077 | 1078 | it('Invalid dates return error object', () => { 1079 | node.value = '2023-01-20' 1080 | const result1 = internalValMethods.before(node, devInput) 1081 | expect(typeof result1.message).toBe('string') 1082 | expect(result1.error).toBe(true) 1083 | 1084 | node.value = '2020-04-01' 1085 | const result2 = internalValMethods.before(node, devInput) 1086 | expect(typeof result2.message).toBe('string') 1087 | expect(result2.error).toBe(true) 1088 | }) 1089 | 1090 | it('Undefined date values return error object', () => { 1091 | //this HHHUUUGGGEEE is a problem****************** 1092 | node.value = undefined 1093 | const result = internalValMethods.before(node, devInput) 1094 | expect(typeof result.message).toBe('string') 1095 | expect(result.error).toBe(true) 1096 | //this HHHUUUGGGEEE is a problem****************** 1097 | }) 1098 | }) 1099 | 1100 | describe('If YEAR, MONTH and DAY are provided', () => { 1101 | 1102 | const devInput = [2020, 4, 15] 1103 | 1104 | it('Valid dates return noError object', () => { 1105 | node.value = '2000-02-25' 1106 | const result1 = internalValMethods.before(node, devInput) 1107 | expect(result1).toEqual(noError) 1108 | 1109 | node.value = '2020-04-15' 1110 | const result2 = internalValMethods.before(node, devInput) 1111 | expect(result2).toEqual(noError) 1112 | }) 1113 | 1114 | it('Invalid dates return error object', () => { 1115 | node.value = '2023-01-20' 1116 | const result1 = internalValMethods.before(node, devInput) 1117 | expect(typeof result1.message).toBe('string') 1118 | expect(result1.error).toBe(true) 1119 | 1120 | node.value = '2020-04-16' 1121 | const result2 = internalValMethods.before(node, devInput) 1122 | expect(typeof result2.message).toBe('string') 1123 | expect(result2.error).toBe(true) 1124 | }) 1125 | 1126 | it('Undefined date values return error object', () => { 1127 | //this HHHUUUGGGEEE is a problem****************** 1128 | node.value = undefined 1129 | const result = internalValMethods.before(node, devInput) 1130 | expect(typeof result.message).toBe('string') 1131 | expect(result.error).toBe(true) 1132 | //this HHHUUUGGGEEE is a problem****************** 1133 | }) 1134 | }) 1135 | 1136 | }) 1137 | 1138 | describe('after Method Unit Tests', () => { 1139 | describe('If only YEAR is provided', () => { 1140 | 1141 | const devInput = [2020] 1142 | 1143 | it('Valid dates return noError object', () => { 1144 | node.value = '2040-09-17' 1145 | const result1 = internalValMethods.after(node, devInput) 1146 | expect(result1).toEqual(noError) 1147 | 1148 | node.value = '2021-01-01' 1149 | const result2 = internalValMethods.after(node, devInput) 1150 | expect(result2).toEqual(noError) 1151 | }) 1152 | 1153 | it('Invalid dates return error object', () => { 1154 | node.value = '2019-04-15' 1155 | const result1 = internalValMethods.after(node, devInput) 1156 | expect(typeof result1.message).toBe('string') 1157 | expect(result1.error).toBe(true) 1158 | 1159 | node.value = '2019-12-31' 1160 | const result2 = internalValMethods.after(node, devInput) 1161 | expect(typeof result2.message).toBe('string') 1162 | expect(result2.error).toBe(true) 1163 | }) 1164 | 1165 | it('Undefined date values return error object', () => { 1166 | //this HHHUUUGGGEEE is a problem****************** 1167 | node.value = undefined 1168 | const result = internalValMethods.after(node, devInput) 1169 | expect(typeof result.message).toBe('string') 1170 | expect(result.error).toBe(true) 1171 | //this HHHUUUGGGEEE is a problem****************** 1172 | }) 1173 | }) 1174 | 1175 | describe('If YEAR and MONTH are provided', () => { 1176 | 1177 | const devInput = [2020, 4] 1178 | 1179 | it('Valid dates return noError object', () => { 1180 | node.value = '2023-01-20' 1181 | const result1 = internalValMethods.after(node, devInput) 1182 | expect(result1).toEqual(noError) 1183 | 1184 | node.value = '2020-05-01' 1185 | const result2 = internalValMethods.after(node, devInput) 1186 | expect(result2).toEqual(noError) 1187 | }) 1188 | 1189 | it('Invalid dates return error object', () => { 1190 | node.value = '2000-02-25' 1191 | const result1 = internalValMethods.after(node, devInput) 1192 | expect(typeof result1.message).toBe('string') 1193 | expect(result1.error).toBe(true) 1194 | 1195 | node.value = '2020-04-31' 1196 | const result2 = internalValMethods.after(node, devInput) 1197 | expect(typeof result2.message).toBe('string') 1198 | expect(result2.error).toBe(true) 1199 | }) 1200 | 1201 | it('Undefined date values return error object', () => { 1202 | //this HHHUUUGGGEEE is a problem****************** 1203 | node.value = undefined 1204 | const result = internalValMethods.after(node, devInput) 1205 | expect(typeof result.message).toBe('string') 1206 | expect(result.error).toBe(true) 1207 | //this HHHUUUGGGEEE is a problem****************** 1208 | }) 1209 | }) 1210 | 1211 | describe('If YEAR, MONTH and DAY are provided', () => { 1212 | 1213 | const devInput = [2020, 4, 15] 1214 | 1215 | it('Valid dates return noError object', () => { 1216 | node.value = '2023-01-20' 1217 | const result1 = internalValMethods.after(node, devInput) 1218 | expect(result1).toEqual(noError) 1219 | 1220 | node.value = '2020-04-15' 1221 | const result2 = internalValMethods.after(node, devInput) 1222 | expect(result2).toEqual(noError) 1223 | }) 1224 | 1225 | it('Invalid dates return error object', () => { 1226 | node.value = '2000-02-25' 1227 | const result1 = internalValMethods.after(node, devInput) 1228 | expect(typeof result1.message).toBe('string') 1229 | expect(result1.error).toBe(true) 1230 | 1231 | node.value = '2020-04-14' 1232 | const result2 = internalValMethods.after(node, devInput) 1233 | expect(typeof result2.message).toBe('string') 1234 | expect(result2.error).toBe(true) 1235 | }) 1236 | 1237 | it('Undefined date values return error object', () => { 1238 | //this HHHUUUGGGEEE is a problem****************** 1239 | node.value = undefined 1240 | const result = internalValMethods.after(node, devInput) 1241 | expect(typeof result.message).toBe('string') 1242 | expect(result.error).toBe(true) 1243 | //this HHHUUUGGGEEE is a problem****************** 1244 | }) 1245 | }) 1246 | 1247 | }) 1248 | 1249 | }) 1250 | --------------------------------------------------------------------------------