mon-entreprise/selectors/usedVariables.js

149 lines
4.0 KiB
JavaScript
Raw Normal View History

import R from 'ramda'
import removeDiacritics from '../utils/remove-diacritics'
import { createSelector } from 'reselect'
import {variablesSelector} from './selectors'
import traversalGuide from './traversalGuide'
/* AIM : Parse all the variables and extract their references to other variables.
Rank the results by count. */
// Use http://regexr.com/ to understand and write regexps !!
// Returns a list of used variables
let findUsedVariables = (schema, toAnalyse, variables) =>
R.cond([
[R.is(Function), extractor =>
R.pipe(
extractor,
R.unless(R.isArrayLike, R.of),
R.map(R.cond([
[R.is(String), name => findVariables(variables, name)],
[R.is(Object), tags => findVariables(variables, null, tags)]
])),
R.unnest,
R.map(R.unless(R.is(String), found => findUsedVariables(traversalGuide, found, variables)))
)(toAnalyse)
],
[R.is(Object), traversalObject =>
R.toPairs(traversalObject).reduce(
(res, [key, value]) => {
return toAnalyse[key] != null ?
[...res, ...findUsedVariables(value, toAnalyse[key], variables)] :
res
}, []
)],
[R.T, yo => []]
])(schema)
// R.cond([
// [R.isArrayLike, R.map(name => {
// let found = findVariables(variables, name)
// return typeof found == 'object' ?
// findUsedVariables(traversalGuide, found, variables)
// : found
// })],
// [R.is(Object), tags => {
// let found = findVariables(variables, null, tags)
// return typeof found == 'object' ?
// findUsedVariables(traversalGuide, found, variables)
// : found
// }]
// ])(schema(toAnalyse))
let calculableVariables = createSelector(
[variablesSelector],
R.pipe(R.pluck('calculable'), R.unnest)
)
// let data = require('../sertarien.yaml')
// let getAllUsedVariables = R.pipe(
// R.map(findUsedVariables(traversalGuide)),
// R.flatten,
// R.countBy(R.identity),
// R.toPairs,
// R.sortBy(R.last),
// R.reverse,
// R.map(R.join(': '))
// )
let findVariablesByName = name =>
R.filter(variable => removeDiacritics(variable.variable) == name)
let findVariablesByTags = tags =>
R.filter(R.pipe(
R.prop('tags'),
R.whereEq(tags)
))
//
// let findVariables = (variables, name, tags) => {
// // Raise error if searching on both name and tags provided gives multiple results
// let results = variables
// if (R.is(String, name)) {
// results = findVariablesByName(name)(variables)
// if (!results.length)
// return `Final variable ${name}`
// }
// if (tags != null) {
// results = findVariablesByTags(tags)(variables)
// }
// if (results.length == 0)
// return `Final variable ${name}`
// if (name != null && results.length > 1)
// return `More than one variable corresponds to this name, tags tuple : ${name}, ${tags}`
//
// return results
// }
let findVariables = (variables, name, tags) =>
R.pipe(
variables => R.is(String, name)
? findVariablesByName(name)(variables)
: variables,
variables => R.is(Object, tags)
? findVariablesByTags(tags)(variables)
: variables,
R.cond([
[ R.isEmpty, () => variableNotFound(name)],
[ (variables) => R.is(String, name) && variables.length > 1,
() => variableNameCollision(name, tags)],
[ R.T,
R.identity]
]),
)(variables)
let variableNotFound = name =>
`Final variable ${name}`
// Should do a query to openfisca web api
// - input var -> end with an input var object
// - var calling other vars -> recursively call
let variableNameCollision = (name, tags) =>
`More than one variable corresponds to this name, tags tuple : ${name}, ${tags}`
export let usedVariables = createSelector(
[state => state.rootVariables, calculableVariables],
(roots, variables) => {
// get all variables from these roots, rec !
return R.compose(
R.uniq,
R.flatten,
R.map(rootObject => findUsedVariables(traversalGuide, rootObject, variables)),
R.map(root => findVariables(variables, removeDiacritics(root))[0])
)(roots)
}
)
// export let usedVariables = createSelector(
// [calculableVariables],
// getAllUsedVariables
// )