数组中用于匹配表达式的字符串之一

One of strings in array to match an expression

问题:

我有一个承诺数组,它被解析为一个字符串数组。现在,如果至少有一个字符串与正则表达式匹配,则测试应该通过。

目前,我使用简单的字符串连接解决了这个问题:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(values[0] + values[1] + values[2]).toMatch(/expression/);
});

显然,扩展性不佳,可读性也不是特别好。

问题:

是否可以使用 自定义 jasmine 匹配器jasmine.any() or custom asymmetric equality tester 来解决它?

正如评论中所说,虽然我最初使用 map,但 reduce 可以让你做你需要的,至少在这个种姓中更有意义:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(
        values.reduce(function(p, v) {
            return v.match(/expression/) || p;
        }, false)
    ).toBe(true);
});

或者写同样的东西,但是使用 ES6 箭头函数:

protractor.promise.all([text1, text2, text3]).then(function(values) {
    exptect(
        values.reduce( (p, v) => v.match(/expression/) || p, false )
    ).toBe(true);
});

两者做同样的事情,reduce 回调将默认为 false,直到 v.match 表达式计算为 true。
我假设这对大多数人来说是显而易见的,但我想我会提供语法和一些解释以供将来参考


也许可以进一步优化此解决方案,以便在找到单个匹配项后停止匹配模式:

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(
        values.reduce(function(p, v) {
            return p || !!v.match(/expression/);
        }, false)
    ).toBe(true);
});

我所做的只是将当前的 reduce 值用作默认值(一旦设置为 true,就没有必要测试任何其他字符串值)。为了确保 v.match 计算为布尔值而不是数组,我只使用了 !!v.match()。不过那部分是可选的。在 ES6 中,同样的事情看起来像这样:

protractor.promise.all([text1, text2, text3]).then(function(values) {
    exptect(
        values.reduce( (p, v) => p || !!v.match(/expression/), false )
    ).toBe(true);
});

这对于大数据集可能表现更好(考虑到 match 调用在找到第一个匹配项后停止,而不是每次都调用 v.match)。

如果可行,

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(values[0] + values[1] + values[2]).toMatch(/expression/);
});

我觉得你可以这样写;

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(values.join('')).toMatch(/expression/);
});

而且它是可扩展的。 :)

如果那些 [text1, text2, text3] 是来自 ElementFinder .getText() 的文本,那么您也可以尝试使用 Expected Conditions(您知道我是 EC 的超级粉丝,对吧?:))。

describe('test', function () {

    it('test', function () {
        var EC = protractor.ExpectedConditions;
        browser.get('http://www.protractortest.org/testapp/ng1/#/form');

        var textToContain = 'Check'; //Notice, that this is not 'equals', this is 'contains'
        var elementTextToCheck1 = EC.textToBePresentInElement($('#checkboxes h4'), textToContain); // Here it will be true : Checkboxes
        var elementTextToCheck2 = EC.textToBePresentInElement($('#animals h4'), textToContain); //false
        var elementTextToCheck3 = EC.textToBePresentInElement($('#transformedtext h4'), textToContain); //false

        var oneElementShouldContainText = EC.or(elementTextToCheck1, elementTextToCheck2, elementTextToCheck3);

        expect(oneElementShouldContainText()).toBeTruthy(`At least one element should contain "${textToContain}"`);
    })
});

对于简单元素: http://www.protractortest.org/#/api?view=ExpectedConditions.prototype.textToBePresentInElement

对于文本区域,输入: http://www.protractortest.org/#/api?view=ExpectedConditions.prototype.textToBePresentInElementValue

请注意,不幸的是 .textToBePresentInElement 仅适用于单个 ElementFinder,不支持 ArrayElementFinder。但在那种情况下,你可以用 .filter() 做一些事情并断言返回的列表是空的。

Array.prototype.some() 看起来像您真正要找的东西。

protractor.promise.all([text1, text2, text3]).then(function (values) {
    expect(values.some(v => v.match(/expression/)).toBe(true);
});

更多信息https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some

您可以简单地使用 map 来获取 boolean 的列表,然后使用 toContain(true):

断言结果
var all = protractor.promise.all;
var map = protractor.promise.map;

expect(map(all([text1, text2, text3]), RegExp.prototype.test, /expression/)).toContain(true);

您也可以使用自定义匹配器:

expect(all([text1, text2, text3])).toContainPattern(/expression/);

以及在 beforeEach 中声明的自定义匹配器:

beforeEach(function() {
  jasmine.addMatchers({
    toContainPattern: function() {
      return {
        compare: function(actual, regex) {
          return {
            pass: actual.some(RegExp.prototype.test, regex), 
            message: "Expected [" + actual + "] to have one or more match with " + regex
          };
        }
      };
    }
  });
});