Skip to content

Commit

Permalink
refactor(xod-project): make normalizePinLabels only change empty pin …
Browse files Browse the repository at this point in the history
…labels, rename to normalizeEmptyPinLabels
  • Loading branch information
evgenykochetkov committed Jul 13, 2018
1 parent 913b1c1 commit 4966ff7
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 99 deletions.
6 changes: 3 additions & 3 deletions packages/xod-arduino/src/transpiler.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ const convertPatchToTPatch = def(
),
})
),
XP.normalizePinLabels,
XP.normalizeEmptyPinLabels,
XP.listOutputPins
)(patch);

Expand All @@ -133,7 +133,7 @@ const convertPatchToTPatch = def(
isDirtyable,
})
),
XP.normalizePinLabels,
XP.normalizeEmptyPinLabels,
XP.listInputPins
)(patch);

Expand Down Expand Up @@ -266,7 +266,7 @@ const getNodePinsUnsafe = def(

const getNodePinLabels = def(
'getNodePinLabels :: Node -> Project -> Map PinKey PinLabel',
R.compose(getPinLabelsMap, XP.normalizePinLabels, getNodePinsUnsafe)
R.compose(getPinLabelsMap, XP.normalizeEmptyPinLabels, getNodePinsUnsafe)
);

// TODO: Remove it when `Project.getBoundValue` will return default values
Expand Down
2 changes: 1 addition & 1 deletion packages/xod-client/src/editor/components/PatchDocs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const PatchDocs = ({ patch, minimal }) => {

const [inputPins, outputPins] = R.compose(
R.partition(XP.isInputPin),
XP.normalizePinLabels,
XP.normalizeEmptyPinLabels,
R.map(pin =>
R.assoc('isVariadic', R.contains(XP.getPinKey(pin), variadicPinKeys), pin)
),
Expand Down
88 changes: 45 additions & 43 deletions packages/xod-client/src/project/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,49 +82,51 @@ export const getInitialPatchOffset = R.compose(
);

// extract information from Patch that is required to render it with Node component
export const patchToNodeProps = R.curry((shouldNormalizePinLabels, patch) => {
const pins = XP.listPins(patch);
const size = calcutaleNodeSizeFromPins(pins);
const type = XP.getPatchPath(patch);
const isVariadic = XP.isVariadicPatch(patch);
const arityStep = foldMaybe(0, R.identity, XP.getArityStepFromPatch(patch));

return {
id: type,
type,
label: '',
position: { x: 0, y: 0 },
size,
isVariadic,
pins: R.compose(
R.when(
() => isVariadic,
renderablePins =>
R.compose(
R.merge(renderablePins),
R.indexBy(R.prop('keyName')),
R.map(R.assoc('isLastVariadicGroup', true)),
R.takeLast(arityStep),
R.sortBy(XP.getPinOrder),
R.filter(XP.isInputPin),
R.values
)(renderablePins)
),
R.indexBy(R.prop('keyName')),
R.map(
R.applySpec({
key: XP.getPinKey,
keyName: XP.getPinKey,
type: XP.getPinType,
direction: XP.getPinDirection,
label: XP.getPinLabel,
position: calculatePinPosition(size),
})
),
shouldNormalizePinLabels ? XP.normalizePinLabels : R.identity
)(pins),
};
});
export const patchToNodeProps = R.curry(
(shouldnormalizeEmptyPinLabels, patch) => {
const pins = XP.listPins(patch);
const size = calcutaleNodeSizeFromPins(pins);
const type = XP.getPatchPath(patch);
const isVariadic = XP.isVariadicPatch(patch);
const arityStep = foldMaybe(0, R.identity, XP.getArityStepFromPatch(patch));

return {
id: type,
type,
label: '',
position: { x: 0, y: 0 },
size,
isVariadic,
pins: R.compose(
R.when(
() => isVariadic,
renderablePins =>
R.compose(
R.merge(renderablePins),
R.indexBy(R.prop('keyName')),
R.map(R.assoc('isLastVariadicGroup', true)),
R.takeLast(arityStep),
R.sortBy(XP.getPinOrder),
R.filter(XP.isInputPin),
R.values
)(renderablePins)
),
R.indexBy(R.prop('keyName')),
R.map(
R.applySpec({
key: XP.getPinKey,
keyName: XP.getPinKey,
type: XP.getPinType,
direction: XP.getPinDirection,
label: XP.getPinLabel,
position: calculatePinPosition(size),
})
),
shouldnormalizeEmptyPinLabels ? XP.normalizeEmptyPinLabels : R.identity
)(pins),
};
}
);

export const isPatchDeadTerminal = R.compose(
R.ifElse(
Expand Down
2 changes: 1 addition & 1 deletion packages/xod-project/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export {
isInputPin,
isOutputPin,
isTerminalPin,
normalizePinLabels,
normalizeEmptyPinLabels,
isPinBindable,
isPulsePin,
} from './pin';
Expand Down
4 changes: 2 additions & 2 deletions packages/xod-project/src/patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ export const validatePinLabels = def(
),
R.filter(groupedPins => groupedPins.length > 1),
R.groupBy(Pin.getPinLabel),
Pin.normalizePinLabels,
Pin.normalizeEmptyPinLabels,
listPins
)(patch)
);
Expand Down Expand Up @@ -974,7 +974,7 @@ export const getNondeadNodePins = def(
R.mergeWith(R.merge, R.__, patchPins),
R.map(R.compose(R.objOf('normalizedLabel'), Pin.getPinLabel)),
R.indexBy(Pin.getPinKey),
Pin.normalizePinLabels,
Pin.normalizeEmptyPinLabels,
R.values
)(patchPins),
R.indexBy(Pin.getPinKey),
Expand Down
51 changes: 20 additions & 31 deletions packages/xod-project/src/pin.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,45 +241,34 @@ const getPinLabelByDirection = def(
);

/**
* Returns a list of Pins with unique Pin Labels.
* For each non-unique pin label it adds an incrementing one-based integer
* suffix.
* Also, if Pin has an empty label it became "IN" or "OUT" depending on its
* direction.
* E.G., Pin labels will be converted into:
* - "A" -> "A1"
* - "A" -> "A2"
* - "B" -> "B1"
* - "B" -> "B2"
* - "C" -> "C"
* Gives pins with empty labels unique names
* E.G.,
* - "" (input) -> "IN1"
* - "" (input) -> "IN2"
* - "" (output) -> "OUT"
*
* This function is useful for transpilers, that want to use
* normalized pin labels instead of shortIds (real pinKeys,
* that refers to NodeIds) and in the clients to show which
* pinKeys user can use in the native implementations.
*/
export const normalizePinLabels = def(
'normalizePinLabels :: [Pin] -> [Pin]',
export const normalizeEmptyPinLabels = def(
'normalizeEmptyPinLabels :: [Pin] -> [Pin]',
R.compose(
R.unnest,
R.values,
R.map(
R.when(
R.compose(R.gt(R.__, 1), R.length),
R.addIndex(R.map)((pin, idx) =>
setPinLabel(`${getPinLabel(pin)}${idx + 1}`, pin)
)
R.over(
R.lensIndex(0),
R.compose(
R.unnest,
R.values,
R.map(
R.when(
R.compose(R.gt(R.__, 1), R.length),
R.addIndex(R.map)((pin, idx) =>
setPinLabel(`${getPinLabel(pin)}${idx + 1}`, pin)
)
)
),
R.groupBy(getPinLabel),
R.map(pin => setPinLabel(getPinLabelByDirection(pin), pin))
)
),
R.groupBy(getPinLabel),
R.map(
R.when(isPinLabelEmpty, pin =>
setPinLabel(getPinLabelByDirection(pin), pin)
)
)
R.partition(isPinLabelEmpty)
)
);

Expand Down
55 changes: 38 additions & 17 deletions packages/xod-project/test/pin.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,28 +90,49 @@ describe('Pin', () => {
assert.isTrue(Pin.isPulsePin(pin));
});
});
describe('normalizePinLabels', () => {
it('should return list of pins with unique labels', () => {
describe('normalizeEmptyPinLabels', () => {
const { INPUT, OUTPUT } = CONST.PIN_DIRECTION;

it('should leave pins with labels untouched', () => {
const pins = [
{ label: 'A', direction: INPUT },
{ label: 'A', direction: INPUT },
{ label: 'A', direction: OUTPUT },
].map(Helper.defaultizePin);

assert.deepEqual(Pin.normalizeEmptyPinLabels(pins), pins);
});

it('should generate unique labels for pins with empty labels', () => {
const pins = [
{ label: '', direction: INPUT },
{ label: '', direction: INPUT },
{ label: '', direction: OUTPUT },
].map(Helper.defaultizePin);
const pinsExpected = [
{ label: 'IN1', direction: INPUT },
{ label: 'IN2', direction: INPUT },
{ label: 'OUT', direction: OUTPUT },
].map(Helper.defaultizePin);

assert.deepEqual(Pin.normalizeEmptyPinLabels(pins), pinsExpected);
});

it('should allow clashes of generated labels with existing labels', () => {
const pins = [
{ label: 'A' },
{ label: 'A' },
{ label: 'B' },
{ label: 'IN', direction: CONST.PIN_DIRECTION.INPUT },
{ label: '', direction: CONST.PIN_DIRECTION.INPUT },
{ label: '', direction: CONST.PIN_DIRECTION.INPUT },
{ label: '', direction: CONST.PIN_DIRECTION.OUTPUT },
{ label: '', direction: INPUT },
{ label: '', direction: OUTPUT },
{ label: '', direction: OUTPUT },
{ label: 'IN', direction: OUTPUT },
].map(Helper.defaultizePin);
const pinsExpected = [
{ label: 'A1' },
{ label: 'A2' },
{ label: 'B' },
{ label: 'IN1', direction: CONST.PIN_DIRECTION.INPUT },
{ label: 'IN2', direction: CONST.PIN_DIRECTION.INPUT },
{ label: 'IN3', direction: CONST.PIN_DIRECTION.INPUT },
{ label: 'OUT', direction: CONST.PIN_DIRECTION.OUTPUT },
{ label: 'IN', direction: INPUT },
{ label: 'OUT1', direction: OUTPUT },
{ label: 'OUT2', direction: OUTPUT },
{ label: 'IN', direction: OUTPUT },
].map(Helper.defaultizePin);

assert.deepEqual(Pin.normalizePinLabels(pins), pinsExpected);
assert.deepEqual(Pin.normalizeEmptyPinLabels(pins), pinsExpected);
});
});

Expand Down
2 changes: 1 addition & 1 deletion packages/xod-tabtest/src/XodProject/Pin.re
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let getDirection = (pin: t) : direction => {
};

[@bs.module "xod-project"]
external _normalizeLabels : array(t) => array(t) = "normalizePinLabels";
external _normalizeLabels : array(t) => array(t) = "normalizeEmptyPinLabels";

let normalizeLabels = pins =>
pins |. List.toArray |. _normalizeLabels |. List.fromArray;
Expand Down

0 comments on commit 4966ff7

Please sign in to comment.