Не удалось преобразовать условие IF / Else в Ramda Cond - PullRequest
0 голосов
/ 12 ноября 2018

Работа на E2E с использованием Ramda. Я не понимаю, как преобразовать простое условие IF, используя Ramda Cond.

Код с использованием If:

if (constraint == 'required') {
  // then only do something
  await waitForElementToBeClickable(constraintElement);
  await constraint.click();
}

Мне не нужно другое, потому что я хочу, чтобы действие происходило только при наличии ограничения.

Я сделал это до сих пор, используя ограничение, но оно не работает:

await waitForElementToBeClickable(cond([
  [equals('required'), always(constraintElement)],
])(constraint), this.browser);

const constraintCheck = cond([
  [equals('required'), () => constraintElement.click()],
]);
await constraintCheck(constraint);

В некоторых случаях я не хочу проходить ограничение. Тогда Условие не должно выполняться вообще. Но он всегда выполняется и выдает ошибку: Не удается прочитать свойство 'isPresent' из Undefined.

Ответы [ 2 ]

0 голосов
/ 12 ноября 2018

Я думаю, возможно, здесь есть некоторая путаница (помимо того, что таможенный командир справедливо указывает на тип constraint.)

Одна из возможностей, которую Ramda пытается предложить, - это позволить нам программировать с выражениями вместо выражений . Особенно это касается операторов управления потоком. Но утверждение, которое выглядит так:

let foo
if (condition) {
  foo = 'bar'
} else {
  foo = 'baz'
}

уже имеет стандартную форму выражения:

const foo = condition ? 'bar' : 'baz'

Рамда на самом деле не пытается предложить альтернативу этому. Но есть и другой способ, которым мы могли бы попытаться использовать if:

let foo
if (test(val)) {
  foo = bar(val)
} else {
  foo = baz(val)
}

Здесь при работе с функциями Рамда предлагает удобное сокращение:

const getFoo = ifElse(test, bar, baz)
// ... later
const foo = getFoo(val)

(И если вы просто хотите вернуть val в случае, если тест не пройден, вы можете использовать сокращение:

   const foo = when(test, bar)

Или, если вы хотите val, когда тест пройден успешно, вы можете сделать

   const foo = unless(test, baz)

)

Хотя может быть немного выразительнее превратить код в

const foo = ifElse(test, bar, baz)(val)

Это не главное. Обоснование для ifElse состоит в том, чтобы использовать его при создании функции многократного использования ifElse(test, bar, baz). (cond - то же самое, просто предлагая последовательность пар, зависящих от условия, вместо одной if и одной else.)

Обратите внимание на одну важную особенность: функция тестирования, функция, которая запускается, если она истинна, и функция, которая запускается, если она ложна, все имеют одинаковую подпись. Если один из них принимает три параметра, то все они должны принимать три параметра. И хотя тест должен возвращать логическое значение, два других могут иметь любой тип возвращаемого значения, но каждый из них должен иметь тот же тип возвращаемого значения, что и другой.

Таким образом, можно использовать thunk, как вы пытаетесь с помощью () => constraintElement.click(), это в основном неправильное использование функции Ramda. Это, вероятно, ничего не дает в вашем коде.


До сих пор неясно, что вы пытаетесь сделать с преобразованием оператора if в ifElse или cond. Не стесняйтесь добавлять в свой вопрос обновление, объясняющее более подробно, что вы пытаетесь сделать, и какую проблему вы пытаетесь решить с помощью этого преобразования, кто-то, вероятно, сможет предложить некоторую помощь. Но не забудьте уточнить, что такое constraint и constraintElement и к чему waitForElementToBeClickable разрешается. Сейчас это довольно запутанно.

0 голосов
/ 12 ноября 2018

Рассматривая ваш пример, кажется, что вы используете constraint как строку и объект, что может вызвать ненужную путаницу. Я знаю, что вы можете реализовать метод toString() на объекте, но я не уверен, что он всегда хорошо работает при интеграции с внешними библиотеками

const obj = {
  toString: () => 'burrito',
  order: () => '?'
};

obj + '' === 'burrito' // true
obj === 'burrito' // false

equals('burrito', obj + '') // true
equals('burrito', obj) // false

Я бы посоветовал вам преобразовать ваш объект в строку перед проверкой:

const check = pipe(
  toString,
  equals('burrito')
);

check(obj); // true

Тогда, если вам не нужна ветка "else", вы можете использовать , когда .

const execute = when(check, invoker(0, 'order'))
execute(obj); // "?"
execute({}); // {}
...