arnapou / behat
v1.4
2024-08-29 18:47 UTC
Requires
- php: ~8.3.0
- arnapou/appcfg: ^1.7
- behat/behat: ^3.0
- psr/cache: ^2.0 || ^3.0
- psr/clock: ^1.0
- psr/simple-cache: ^2.0 || ^3.0
Requires (Dev)
- ext-yaml: *
- friendsofphp/php-cs-fixer: ^3.52
- phpstan/extension-installer: ^1.3
- phpstan/phpstan: ^1.10
- phpstan/phpstan-deprecation-rules: ^1.1
- phpstan/phpstan-phpunit: ^1.3
- phpstan/phpstan-strict-rules: ^1.5
- phpunit/php-code-coverage: ^11.0
- phpunit/phpunit: ^11.0
README
应用程序配置系统。
安装
composer require arnapou/behat
packagist 👉️ arnapou/behat
简介
该库主要提供了一个 BehatTool 对象,您可以在自己的环境中使用它来处理数据。
它利用 arnapou/appcfg 来“编译”带有上下文的数组。
这使得我们可以轻松使用 appcfg 语法来处理数据以进行测试匹配等...
语法 %<processor>(<label>:<expression>)%
- processor:解释标签 + 表达式(仅限于
a-zA-Z0-9_
字符)的方式 - label:对于处理器来说,意味着任何内容,可以包含任何字符(仅需要转义
:
,如\:
) - expression(可选):对于处理器来说,意味着任何内容,可以包含任何字符(仅需要转义
:
,如\:
)
有效表达式
%<processor>(<label>)%
:缺少表达式 + 冒号:
,表达式没有“值”。%<processor>(<label>:%<nested_processor>(<nested_label>:<nested_expression>)%)%
:可以有多个嵌套表达式的层次。
更多详情请参考 arnapou/appcfg 库。
Behat 糖
BehatTool 类包含一系列方法,可以帮助您使用 appcfg 操作 编译后的数组。
为了帮助 匹配测试,我们添加了一个接口 MatchingProcessor,您可以实现并通过 ProcessorsProvider 接口注入。
代码得到了适当的隔离。因此,您可以直接在 behat 环境中使用我们的 gherkin 辅助类。
- ArrayHelper:帮助折叠/展开数组 + 其他辅助工具。
- TableNodeWithLayout:behat
TableNode
的外观,以保持行为、格式和类型的一致性。
为了简化测试,库中包含了一些 PSR 的简单实现
- PSR-6 使用 RuntimeCacheItemPool
- PSR-16 使用 RuntimeSimpleCache
- PSR-20 使用 FixedClock
处理器
默认
%(array.context.path.value)%
%(array.context.path.value:<default>)%
环境变量
%env(VARIABLE)%
%env(VARIABLE:<default>)%
基本静态值转换(简短语法替代)
%int(<value>)%
或%int(:<value>)%
%float(<value>)%
或%float(:<value>)%
%bool(<value>)%
或%bool(:<value>)%
%null()%
过滤器:基本转换
%filter(int:<value>)%
或可空%filter(?int:<value>)%
%filter(float:<value>)%
或可空%filter(?float:<value>)%
%filter(bool:<value>)%
或可空%filter(?bool:<value>)%
%filter(string:<value>)%
或可空%filter(?string:<value>)%
过滤器:字符串函数
%filter(md5:<value>)%
%filter(sha1:<value>)%
%filter(capitalize:<value>)%
%filter(lower:<value>)%
%filter(upper:
)%
过滤器:字符串+数组函数
%filter(length:
)%
JSON操作
%json(decode:
)% %json(encode:
)%
日期操作
%date(
: )% %date(Y-m-d\TH\:i\:sP:
(格式中的转义冒号))% %date(Y-m-d:10 june next year)%
%date(Y-m-d:1718990615)%
缓存操作
%save(
保存值: )% %cache(
获取值: )%
如果有效则传递值,否则 null
%regex(
:对于任何字符串,例如: )% %regex(/^\d+$/)%
%between(
:仅适用于数值,例如, : )% %between(10,20)%
匹配处理器
%regex(
:对于任何字符串,例如)% %regex(/^\d+$/)%
%between(
:仅适用于数值,例如, )% %between(10,20)%
%undefined(array-key)%
:仅适用于数组或对象属性,例如%undefined()%
examples.feature
这是一个示例,这意味着 FeatureContext 文件夹中的 feature
文件仅为此示例在 CI 上运行而存在。
您可以从其中复制代码或获取灵感,这取决于您。
Feature: Examples of what we can achieve
Background:
# For the example, this context is also interpreted and compiled.
# In a real scenario, for example, these context data would probably
# come from the last json response of a http query.
Given a common JSON used as context for all compilation examples
"""
{
"items": [1, 2, 3, 4, 5, 6, 7, 8, 9],
"text": "Hello World",
"date": "%int(:%date(U:2024-06-23T19:03:48+00:00)%)%",
"user": { "name": "John", "age": 20 }
}
"""
Scenario: "Rows" layout
# The compilation is done with the context of the background.
When we compile these "rows"
| column A | column B | column C |
| foo | %items.1% | %(date)% |
| %save(username:%(user.name)%)% | %(items.2)% | %filter(upper:%(text)%)% |
# Basic EQUAL comparison against the previous result
Then the last compiled is equal to these "rows"
| column A | column B | column C |
| foo | %int(2)% | %int(1719169428)% |
| John | %int(3)% | HELLO WORLD |
# Equivalent EQUAL comparison but with raw JSON (not compiled)
And the last compiled is equal to this JSON
"""
[{
"column A": "foo",
"column B": 2,
"column C": 1719169428
},{
"column A": "John",
"column B": 3,
"column C": "HELLO WORLD"
}]
"""
Scenario: "Columns" layout with only 1 column
# The compilation is done with the context of the background.
When we compile these "columns"
| row | foo |
| json | %json(encode:%(user)%)% |
| name | %cache(username)% |
| company | %cache(user.company:unknown)% |
# Basic EQUAL comparison against the previous result
Then the last compiled is equal to these "columns"
| row | foo |
| json | {"name":"John","age":20} |
| name | John |
| company | unknown |
# Equivalent EQUAL comparison but with raw JSON (not compiled)
And the last compiled is equal to this JSON
"""
{
"row": "foo",
"json": "{\"name\":\"John\",\"age\":20}",
"name": "John",
"company": "unknown"
}
"""
Scenario: "Columns" layout with multiple columns
# The compilation is done with the context of the background.
When we compile these "columns"
| name | John | Sue |
| age | %int(20)% | %int(23)% |
| company | Google | Microsoft |
# Equivalent EQUAL comparison but with raw JSON (not compiled)
And the last compiled is equal to this JSON
"""
[{
"name": "John",
"age": 20,
"company": "Google"
},{
"name": "Sue",
"age": 23,
"company": "Microsoft"
}]
"""
Scenario: Matching example
# The table is "unfolded" before compilation, that does the contrary
# of flatten, expanding the paths to keys and sub-keys, ...
When we unfold and compile these "columns"
| users.0.name | %cache(username)% |
| users.0.age | %(user.age)% |
| users.1.name | Sue |
| users.1.age | %int(21)% |
| items.values | %(items)% |
| items.count | %filter(length:%(items)%)% |
| date | %date(Y-m-d:%(date)%)% |
# MATCHING comparison which is OK if it does not trigger an exception.
# You may use either raw values, or matching processors like regex & between.
Then the last compiled is matching these "columns"
| users.0.age | %regex(/^\d+$/)% |
| users.1.age | %between(20,22)% |
| users.2 | %undefined(age)% |
| users | %undefined(2)% |
| date | 2024-06-23 |
| unknown | %undefined()% |
# EQUAL comparison with raw JSON (not compiled)
And the last compiled is equal to this JSON
"""
{
"users": [
{ "name": "John" , "age": 20 },
{ "name": "Sue" , "age": 21 }
],
"items": {
"values": [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ],
"count": 9
},
"date": "2024-06-23"
}
"""
PHP 版本
日期 | 参考 | 8.3 |
---|---|---|
23/06/2024 | 1.x,主分支 | × |