Skip to content

Instantly share code, notes, and snippets.

@trsdln
Created July 2, 2018 08:50
Show Gist options
  • Save trsdln/3a4adc612583258abbd82a20964739df to your computer and use it in GitHub Desktop.
Save trsdln/3a4adc612583258abbd82a20964739df to your computer and use it in GitHub Desktop.
HM-DEF Usage
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 = 'test@test.com';
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