Created
July 2, 2018 08:50
-
-
Save trsdln/3a4adc612583258abbd82a20964739df to your computer and use it in GitHub Desktop.
HM-DEF Usage
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
import R from 'ramda'; | |
import HMD from 'hm-def'; | |
import $ from 'sanctuary-def'; | |
import F from 'fluture'; | |
import { env, create as createS } from 'sanctuary'; | |
import { env as flutureEnv } from 'fluture-sanctuary-types'; | |
const funcName = R.concat ('func-sandbox/'); | |
const docsLink = R.concat ('http://trsdln.com/func-sandbox#'); | |
const Model = modelName => (typesStrMap) => { | |
const modelRecord = $.RecordType (typesStrMap); | |
return $.NullaryType ( | |
funcName (modelName), | |
docsLink (modelName), | |
$.test ([]) (modelRecord), | |
); | |
}; | |
// stringTest :: Any -> Boolean | |
const stringTest = $.test ([]) ($.String); | |
// naiveEmailStrTest :: String -> Boolean | |
const naiveEmailStrTest = R.test (/^[a-z0-9_.]+@[a-z0-9_.]+$/i); | |
// idStrTest :: String -> Boolean | |
const idStrTest = R.test (/^[a-z0-9_]+$/i); | |
// custom types | |
const Email = $.NullaryType ( | |
funcName ('Email'), | |
docsLink ('Email'), | |
R.both (stringTest) (naiveEmailStrTest), | |
); | |
const ID = $.NullaryType ( | |
funcName ('ID'), | |
docsLink ('ID'), | |
R.both (stringTest) (idStrTest), | |
); | |
const EmailEntry = Model ('EmailEntry') ({ | |
address: Email, | |
verified: $.Boolean, | |
}); | |
const User = Model ('User') ({ | |
_id: ID, | |
emails: $.Array (EmailEntry), | |
}); | |
const customTypes = [Email, User, ID]; | |
const CHECK_TYPES_FLAG = true; | |
const fullEnv = [...env, ...flutureEnv, ...customTypes]; | |
const S = createS ({ | |
checkTypes: CHECK_TYPES_FLAG, | |
env: fullEnv, | |
}); | |
const def = HMD.create ({ | |
checkTypes: CHECK_TYPES_FLAG, | |
env: fullEnv, | |
}); | |
const getMaybeEmailByUser = def ( | |
'getEmailByUser :: User -> Maybe Email', | |
S.gets (R.is (String)) (['emails', '0', 'address']), | |
); | |
describe ('hm def with custom types', () => { | |
it ('should allow to define custom type', () => { | |
const expectedEmail = '[email protected]'; | |
const fakeUser = { | |
_id: 'fake_user_id', | |
emails: [{ address: expectedEmail, verified: false }], | |
}; | |
const maybeEmail = getMaybeEmailByUser (fakeUser); | |
expect (S.fromMaybe ('na', maybeEmail)).toEqual (expectedEmail); | |
}); | |
it ('should not fail with missing email', () => { | |
const expectedEmail = 'na'; | |
const fakeUser = { _id: 'fake_user_id', emails: [] }; | |
const maybeEmail = getMaybeEmailByUser (fakeUser); | |
expect (S.fromMaybe (expectedEmail, maybeEmail)).toEqual (expectedEmail); | |
}); | |
it ('should fail when returned type is incorrect', () => { | |
const fakeUser = { _id: 'fake_user_id', emails: [] }; | |
const getOnlyEmailByUser = def ( | |
'getOnlyEmailByUser :: User -> Email', | |
R.compose ( | |
S.fromMaybe ('n/a'), | |
getMaybeEmailByUser, | |
), | |
); | |
expect (() => { | |
getOnlyEmailByUser (fakeUser); | |
}).toThrow (); | |
}); | |
it ('should work for some simple calculate', () => { | |
const calcInRange = def ( | |
'calcInRange :: Number -> Number', | |
S.pipe ([ | |
S.range (0), | |
S.map (S.add (1)), | |
S.map (R.multiply (2)), | |
S.reduce (S.add, 0), | |
]), | |
); | |
const testRange = S.pipe ([S.range (0), S.map (R.multiply (10))]) (10); | |
const testResults = S.map (calcInRange) (testRange); | |
const zippedList = R.zip (testRange) (testResults); | |
expect (zippedList).toMatchSnapshot (); | |
}); | |
it ('should support fluture', async () => { | |
const futureIncrement = def ( | |
'futureIncrement :: Number -> Future String Number', | |
S.pipe ([S.add (1), F.of]), | |
); | |
await expect (futureIncrement (5).promise ()).resolves.toEqual (6); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment