Created
March 9, 2017 12:29
-
-
Save MikeMKH/8cbf5785ac9dc6c79dfb383cf0e8014f to your computer and use it in GitHub Desktop.
Basic Validation example using folktale with mocha and expect.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Validation = require('data.validation') | |
| const Success = Validation.Success | |
| const Failure = Validation.Failure | |
| const expect = require('expect.js'); | |
| describe('truth', () => { | |
| it('will be true', () => { | |
| expect(true).to.equal(true); | |
| }) | |
| }); | |
| // example from http://robotlolita.me/2013/12/08/a-monad-in-practicality-first-class-failures.html#sometimes-you-fail-more-than-once | |
| describe('validation example', () => { | |
| describe('user name validation', () => { | |
| /* | |
| - Usernames should contain only numbers and letters. | |
| - Passwords should be at least 6 characters long. | |
| - Passwords must contain at least one special character. | |
| */ | |
| const isNameValid = name => | |
| /^[\w]+$/.test(name) ? Success(name) : Failure('Error: User name cannot be empty'); | |
| describe('isNameValid', () => { | |
| it('given empty name it must return failure', () => { | |
| expect(isNameValid('').isFailure).to.be.ok(); | |
| }), | |
| it('given name with a space it must return failure', () => { | |
| expect(isNameValid('this fails').isFailure).to.be.ok(); | |
| }), | |
| it('given name with digits it must return success', () => { | |
| const name = '123valid456'; | |
| expect(isNameValid(name)).to.eql(Success(name)); | |
| }); | |
| }); | |
| const isPasswordLongEnough = password => | |
| password && password.length > 6 ? Success(password) : Failure('Error: Password not long enough'); | |
| describe('isPasswordLongEnough', () => { | |
| it('given null password it must return failure', () => { | |
| expect(isPasswordLongEnough(null).isFailure).to.be.ok(); | |
| }), | |
| it('given empty password it must return failure', () => { | |
| expect(isPasswordLongEnough('').isFailure).to.be.ok(); | |
| }), | |
| it('given password of length 6 it must return failure', () => { | |
| expect(isPasswordLongEnough('123456').isFailure).to.be.ok(); | |
| }), | |
| it('given password of length 7 it must return success', () => { | |
| const password = '1234567'; | |
| expect(isPasswordLongEnough(password)).to.eql(Success(password)); | |
| }); | |
| }); | |
| const isPasswordStrongEnough = password => | |
| /\W/.test(password) ? Success(password) : Failure('Error: Password not strong enough'); | |
| describe('isPasswordStrongEnough' , () => { | |
| it('given empty password it must return failure', () => { | |
| expect(isPasswordStrongEnough('').isFailure).to.be.ok(); | |
| }), | |
| it('given password of just numbers it must return failure', () => { | |
| expect(isPasswordStrongEnough('1').isFailure).to.be.ok(); | |
| }), | |
| it('given password with a bang it must return success', () => { | |
| const password = '!'; | |
| expect(isPasswordStrongEnough(password)).to.eql(Success(password)); | |
| }); | |
| }); | |
| // taken from http://robotlolita.me/2013/12/08/a-monad-in-practicality-first-class-failures.html#sometimes-you-fail-more-than-once | |
| const curryN = (n, f) => | |
| function _curryN(as) { | |
| return function() { | |
| var args = as.concat([].slice.call(arguments)) | |
| return args.length < n ? _curryN(args) : f.apply(null, args)}}([]); | |
| const isPasswordValid = password => | |
| Success(curryN(2, () => password)) | |
| .ap(isPasswordLongEnough(password)) | |
| .ap(isPasswordStrongEnough(password)); | |
| describe('isPasswordValid', () => { | |
| it('given empty password it must return failure', () => { | |
| expect(isPasswordValid('').isFailure).to.be.ok(); | |
| }), | |
| it('given password without special character it must return failure', () => { | |
| expect(isPasswordValid('1234567').isFailure).to.be.ok(); | |
| }), | |
| it('given valid password it must return success', () => { | |
| const password = 'roses.are.red'; | |
| expect(isPasswordValid(password)).to.eql(Success(password)); | |
| }); | |
| }); | |
| const isAccountValid = (name, password) => | |
| Success(curryN(2, (n, p) => [n, p])) | |
| .ap(isNameValid(name)) | |
| .ap(isPasswordValid(password)); | |
| describe('isAccountValid', () => { | |
| const validAccount = '123valid456'; | |
| const invalidAccount = ''; | |
| const validPassword = 'roses.are.red'; | |
| const invalidPassword = ''; | |
| it('given invalid account it must return failure', () => { | |
| expect(isAccountValid(invalidAccount, validPassword).isFailure).to.be.ok(); | |
| }); | |
| it('given invalid password it must return failure', () => { | |
| expect(isAccountValid(validAccount, invalidPassword).isFailure).to.be.ok(); | |
| }); | |
| it('given invalid account and password it must return failure', () => { | |
| expect(isAccountValid(invalidAccount, invalidPassword).isFailure).to.be.ok(); | |
| }); | |
| it('given valid account and password it must return success', () => { | |
| expect(isAccountValid(validAccount, validPassword).isSuccess).to.be.ok(); | |
| }); | |
| }); | |
| }); | |
| }); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Examples are from http://robotlolita.me/2013/12/08/a-monad-in-practicality-first-class-failures.html#sometimes-you-fail-more-than-once