无法将IF / Else条件转换为Ramda Cond

时间:2018-11-12 10:39:46

标签: javascript e2e-testing ramda.js angularjs-e2e

使用Ramda进行E2E。我不知道如何使用Ramda Cond转换简单的IF条件。

使用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'。

2 个答案:

答案 0 :(得分:1)

我认为这里可能有些混乱(除了customcommander正确指出的constraint类型之外)。

Ramda试图提供的功能之一是允许我们使用表达式而不是声明进行编程。特别值得关注的是控制流语句。但是,一条语句看起来像这样:

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

已经具有标准的表达形式:

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

Ramda并未真正尝试提供替代方法。但是,我们可以尝试使用另一种方法来使用if

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

在这里,使用函数时,Ramda提供了一个便捷的速记:

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。)

请注意一个重要的功能:测试功能,为真时运行的功能和为假时要运行的功能都具有相同的签名。如果其中之一采用三个参数,则它们都应接受三个参数。尽管测试应该返回布尔值,但是其他两个可以具有任何返回类型,但是每个都应该具有与另一个相同的返回类型。

因此,当您尝试使用() => constraintElement.click()时,可以使用thunk,这主要是滥用Ramda功能。它可能不会给您带来任何好处。


目前尚不清楚您要如何处理从ififElsecond的转换。请随时在您的问题中添加更新,以更全面地说明您要执行的操作以及此转换要解决的问题,有人可能会提供帮助。但是请确保您弄清constraintconstraintElement是什么以及waitForElementToBeClickable会解决什么。现在,这非常令人困惑。

答案 1 :(得分:0)

通过查看示例,您似乎同时将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”分支,则可以考虑使用when

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