Skip to content

Commit

Permalink
Merge pull request #2 from A1c0/fluture-test
Browse files Browse the repository at this point in the history
Fluture test
  • Loading branch information
A1c0 authored Dec 2, 2021
2 parents 81f81f8 + d2ca2d0 commit 86a8ad6
Show file tree
Hide file tree
Showing 15 changed files with 1,070 additions and 738 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ sandbox
.idea
node_modules
*.log
/test/
/sanctuary-lourde.test.mjs
1 change: 0 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

yarn test
yarn sync-doc
git add README.md
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.husky
.script
.github
8 changes: 7 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,11 @@
"bracketSpacing": false,
"printWidth": 80,
"arrowParens": "avoid",

"importOrder": [
"^((assert)|(async_hooks)|(buffer)|(child_process)|(cluster)|(console)|(constants)|(crypto)|(dgram)|(diagnostics_channel)|(dns)|(domain)|(events)|(fs)|(http2)|(http)|(https)|(inspector)|(module)|(net)|(os)|(path)|(perf_hooks)|(process)|(punycode)|(querystring)|(readline)|(repl)|(stream)|(string_decoder)|(sys)|(timers)|(tls)|(trace_events)|(tty)|(url)|(util)|(v8)|(vm)|(wasi)|(worker_threads)|(zlib))$",
"^[^.](.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}
17 changes: 17 additions & 0 deletions .script/assets/prefix.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const log = l => x => `[${l}]: ${S.show(x)}`;

const isEither = S.is ($.Either ($.Unknown) ($.Unknown));
const isMaybe = S.is ($.Maybe ($.Unknown));
const showIfSanctuaryValue = S.unchecked.when (x => isEither (x) || isMaybe (x))
(S.show);
const forkLog = f => promise (f).then (log ('resolution')).catch (log ('rejection'));

const evalValue = S.pipe ([
s => `(${s})`,
S.encase (eval)
]);

const parseExpected = x => S.pipe ([
evalValue,
S.unchecked.fromEither (x)
]) (x);
2 changes: 2 additions & 0 deletions .script/assets/prefix_import.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import {promise} from 'fluture';
import test from 'oletus';
65 changes: 65 additions & 0 deletions .script/common.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import {S, Sl, readFile, replace} from './utils.mjs';

const appendOnDef = acc => value => {
const last = S.last (acc);
if (S.isNothing (last)) {
return S.append ([value]) (acc);
}
if (S.test (/::/) (value)) {
return S.append ([value]) (acc);
}
if (S.test (S.regex ('') ('#'.repeat (6))) (value)) {
const lastLine = S.fromMaybe ('') (S.chain (S.last) (last));
if (S.complement (S.test (/##/)) (lastLine)) {
return S.append ([value]) (acc);
}
}
const lastValue = S.fromMaybe ([]) (last);
const appFOrUpdate = S.fromMaybe ([]) (S.dropLast (1) (acc));
return S.append (S.append (value) (lastValue)) (appFOrUpdate);
};

export const createGroupOnDef = S.reduce (appendOnDef) ([]);

const bundleDef = lines => defLines =>
S.pipe ([
S.unchecked.flip ({
index: S.pipe ([
Sl.nth (0),
S.chain (S.flip (Sl.indexOf) (lines))
]),
title: S.pipe ([
Sl.nth (0),
S.map (replace (/ *\/\/ */) ('')),
S.chain (Sl.toMaybe (S.test (/[A-Za-z0-9]+ :: [A-Za-z0-9() ]+ (-> [A-Za-z0-9() ]+)*/))),
]),
meta: S.pipe ([
S.map (replace (/ *\/\/ */) ('')),
S.joinWith ('\n'),
S.splitOn ('\n\n'),
Sl.nth (1),
]),
examples: S.pipe ([
S.map (replace (/ *\/\/ */) ('')),
S.joinWith ('\n'),
S.splitOn ('\n\n'),
S.drop (2),
S.map (S.joinWith ('\n\n')),
]),
}),
S.unchecked.sequence (S.Maybe),
S.maybeToEither (defLines),
]) (defLines);

const bundleDefs = lines =>
S.pipe ([
S.filter (S.test (/ *\/\//)),
createGroupOnDef,
S.map (bundleDef (lines)),
]) (lines);

export const getApiDoc = S.pipe ([
readFile,
S.lines,
bundleDefs
]);
6 changes: 3 additions & 3 deletions .script/doctest.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
cp index.mjs index.test.mjs
echo 'create ({checkTypes: true});' >> index.test.mjs
(doctest --module esm index.test.mjs || (rm index.test.mjs && exit 1)) && rm index.test.mjs
CHECK_TYPES_SANCTUARY=false node .script/test-builder.mjs
oletus sanctuary-lourde.test.mjs
rm sanctuary-lourde.test.mjs
163 changes: 69 additions & 94 deletions .script/sync-doc.mjs
Original file line number Diff line number Diff line change
@@ -1,123 +1,98 @@
import {create} from '../index.mjs';
import {env as flutureEnv} from 'fluture-sanctuary-types';
import * as fs from 'fs';
import path from 'path';
import sanctuary from 'sanctuary';
import {fileURLToPath} from 'url';

const S = sanctuary.create ({
checkTypes: true,
env: sanctuary.env.concat (flutureEnv),
});

const Sl = create ({
checkTypes: true,
});

const __dirname = path.dirname (fileURLToPath (import.meta.url));
const APP_DIR = path.dirname (__dirname);

const readFile = x => S.pipe ([
fs.readFileSync,
S.show
]) (x);

const writeFile = S.curry2 (fs.writeFileSync);

const bob = acc => value => {
const last = S.last (acc);
if (S.isNothing (last)) {
return S.append ([value]) (acc);
}
if (S.test (/::/) (value)) {
return S.append ([value]) (acc);
}
const lastValue = S.fromMaybe ([]) (last);
const appFOrUpdate = S.fromMaybe ([]) (S.dropLast (1) (acc));
return S.append (S.append (value) (lastValue)) (appFOrUpdate);
};

const replace = a => b => s => s.replace (a, b);

const indexOf = elm => array => {
const index = array.indexOf (elm);
return index === -1 ? S.Nothing : S.Just (index);
};

import {getApiDoc} from './common.mjs';
import {APP_DIR, S, Sl, readFile, replace, writeFile} from './utils.mjs';

const buildUrl = index =>
`https://github.com/A1c0/sanctuary-lourdes/blob/main/index.mjs#L${S.add(1)(
index
)}`;

const buildExemples = e => ['```js', e, '```'].join ('\n');
const buildExamples = e => ['```js', e, '```'].join ('\n');

const defToString = ({index, title, meta, exemples}) =>
const defToString = ({index, title, meta, examples}) =>
[
`#### <a href="${buildUrl(index)}">\`${title}\`</a>`,
meta,
buildExemples (exemples),
buildExamples (examples),
].join ('\n\n');

const bundleDef = lines => defLines =>
S.pipe ([
S.unchecked.flip ({
index: S.pipe ([
Sl.nth (0),
S.chain (S.flip (indexOf) (lines))
]),
title: S.pipe ([
Sl.nth (0),
S.map (replace (/ *\/\/ */) (''))
]),
meta: S.pipe ([
S.map (replace (/ *\/\/ */) ('')),
S.joinWith ('\n'),
S.splitOn ('\n\n'),
Sl.nth (1),
]),
exemples: S.pipe ([
S.map (replace (/ *\/\/ */) ('')),
S.joinWith ('\n'),
S.splitOn ('\n\n'),
S.drop (2),
S.map (S.joinWith ('\n\n')),
]),
}),
S.unchecked.sequence (S.Maybe),
]) (defLines);

const bundleDefs = lines =>
S.pipe ([
S.filter (S.test (/ *\/\//)),
// debug ('file'),
S.reduce (bob) ([]),
S.map (bundleDef (lines)),
S.justs,
]) (lines);

const toTextFormat = S.pipe ([
S.map (defToString),
S.joinWith ('\n\n')
const toCapitalize = s => `${s[0].toUpperCase()}${s.slice(1).toLowerCase()}`;

const toTypeTitle = s => `### ${s}`;

const apiDoc = getApiDoc (path.resolve (APP_DIR, 'index.mjs'));

// removeCommentMarkerAndJoin :: Array String -> String
const removeCommentMarkerAndJoin = S.pipe ([
S.map (replace (/ *\/\/ */) ('')),
S.joinWith ('\n'),
]);

// getDocTitle :: Array String -> Maybe String
const getDocTitle = S.pipe ([
removeCommentMarkerAndJoin,
Sl.extractString (/#*\n#{5} {3}([A-Za-z]+) {3}#{5}\n#*/),
S.map (toCapitalize),
]);

// getFormattedTitle :: Array String -> Maybe String
const getFormattedTitle = S.pipe ([
getDocTitle,
S.map (toTypeTitle)
]);

// getFormattedDescription :: Array String -> Maybe String
const getFormattedDescription = S.pipe ([
removeCommentMarkerAndJoin,
Sl.extractString (/#*\n#{5} {3}[A-Za-z]+ {3}#{5}\n#*\n\n(.*(\n.*)*)/),
S.map (Sl.replace (/\n/g) (' ')),
]);

// getFormattedTitleAndDescription :: Array String -> Maybe String
const getFormattedTitleAndDescription = S.pipe ([
S.flip ([getFormattedTitle, getFormattedDescription]),
S.justs,
Sl.toMaybe (array => array.length !== 0),
S.map (S.joinWith ('\n\n')),
]);

// extractWantedDoc :: Array String -> Either Array String String
const extractWantedDoc = x =>
S.pipe ([
getFormattedTitleAndDescription,
S.maybeToEither (x)
]) (x);

const toSummaryFormat = s => `- [${s}](#${s})`;

// docSummary :: String
const docSummary = S.pipe ([
S.map (S.either (getDocTitle) (S.K (S.Nothing))),
S.justs,
S.map (toSummaryFormat),
S.unlines,
]) (apiDoc);

// apiString :: String
const apiString = S.pipe ([
readFile,
S.lines,
bundleDefs,
toTextFormat
]) (path.resolve (APP_DIR, 'index.mjs'));
S.map (S.either (extractWantedDoc) (x => S.Right (defToString (x)))),
S.rights,
S.joinWith ('\n\n'),
]) (apiDoc);

const readmePath = path.resolve (APP_DIR, 'README.md');

S.pipe ([
readFile,
S.lines,
lines => S.take (S.fromMaybe (0) (indexOf ('## API') (lines))) (lines),
lines => S.take (S.fromMaybe (0) (Sl.indexOf ('## API') (lines))) (lines),
S.fromMaybe ([]),
S.append ('## API'),
S.append (''),
S.append (apiString),
S.append (docSummary),
S.append (''),
S.append (apiString),
S.unlines,
writeFile (readmePath),
]) (readmePath);
Loading

0 comments on commit 86a8ad6

Please sign in to comment.