数组中用于匹配表达式的字符串之一
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
};
}
};
}
});
});
问题:
我有一个承诺数组,它被解析为一个字符串数组。现在,如果至少有一个字符串与正则表达式匹配,则测试应该通过。
目前,我使用简单的字符串连接解决了这个问题:
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
};
}
};
}
});
});