Skip to content
This repository was archived by the owner on Mar 29, 2023. It is now read-only.

Commit 7b42ce7

Browse files
authored
feat: add OR syntax (#17)
1 parent 0f83bf6 commit 7b42ce7

File tree

5 files changed

+70
-18
lines changed

5 files changed

+70
-18
lines changed

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ jobs:
7676
--env grep=-@tag1 \
7777
--expect ./expects/invert-tag1.json
7878
79+
- name: Run tests with hello OR @tag1 🧪
80+
run: |
81+
npx cypress-expect \
82+
--env grep='hello @tag1' \
83+
--expect ./expects/hello-or-tag1.json
84+
7985
- name: Semantic Release 🚀
8086
uses: cycjimmy/semantic-release-action@v2
8187
with:

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,15 @@ You can skip running the tests with specific tag using the invert option: prefix
100100
--env grep=-@slow
101101
```
102102

103+
### OR tags
104+
105+
You can run tests that match one tag or another using spaces. Make sure to quote the grep string!
106+
107+
```
108+
# run tests with tags "@slow" or "@critical" in their names
109+
--env grep='@slow @critical'
110+
```
111+
103112
## Examples
104113

105114
- [cypress-grep-example](https://github.com/bahmutov/cypress-grep-example)

cypress/integration/unit.js

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ describe('utils', () => {
1111
it('creates objects from the grep string', () => {
1212
const parsed = parseGrep('@tag1+@tag2+@tag3')
1313
expect(parsed).to.deep.equal([
14-
{ tag: '@tag1', invert: false },
15-
{ tag: '@tag2', invert: false },
16-
{ tag: '@tag3', invert: false },
14+
// single OR part
15+
[
16+
// with 3 AND parts
17+
{ tag: '@tag1', invert: false },
18+
{ tag: '@tag2', invert: false },
19+
{ tag: '@tag3', invert: false },
20+
],
1721
])
1822
})
1923
})
@@ -52,5 +56,22 @@ describe('utils', () => {
5256
expect(t('has only @tag2 in the name')).to.be.false
5357
expect(t('has @tag1 and @tag2 in the name')).to.be.true
5458
})
59+
60+
it('with OR option', () => {
61+
const t = checkName('@tag1 @tag2')
62+
expect(t('no tag1 here')).to.be.false
63+
expect(t('has only @tag1 in the name')).to.be.true
64+
expect(t('has only @tag2 in the name')).to.be.true
65+
expect(t('has @tag1 and @tag2 in the name')).to.be.true
66+
})
67+
68+
it('OR with AND option', () => {
69+
const t = checkName('@tag1 @tag2+@tag3')
70+
expect(t('no tag1 here')).to.be.false
71+
expect(t('has only @tag1 in the name')).to.be.true
72+
expect(t('has only @tag2 in the name')).to.be.false
73+
expect(t('has only @tag2 in the name and also @tag3')).to.be.true
74+
expect(t('has @tag1 and @tag2 and @tag3 in the name')).to.be.true
75+
})
5576
})
5677
})

expects/hello-or-tag1.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"hello world": "passed",
3+
"works": "pending",
4+
"works 2 @tag1": "passed",
5+
"works 2 @tag1 @tag2": "passed",
6+
"works @tag2": "pending"
7+
}

src/utils.js

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,37 @@
11
function parseGrep(s) {
2-
const parsed = s.split('+').map((tag) => {
3-
if (tag.startsWith('-')) {
2+
// top level split - using space, each part is OR
3+
const ORS = s.split(' ').map((part) => {
4+
// now every part is an AND
5+
const parsed = part.split('+').map((tag) => {
6+
if (tag.startsWith('-')) {
7+
return {
8+
tag: tag.slice(1),
9+
invert: true,
10+
}
11+
}
12+
413
return {
5-
tag: tag.slice(1),
6-
invert: true,
14+
tag,
15+
invert: false,
716
}
8-
}
17+
})
918

10-
return {
11-
tag,
12-
invert: false,
13-
}
19+
return parsed
1420
})
1521

16-
return parsed
22+
return ORS
1723
}
1824

1925
function shouldTestRun(parsedGrep, testName) {
20-
return parsedGrep.every((p) => {
21-
if (p.invert) {
22-
return !testName.includes(p.tag)
23-
}
26+
// top levels are OR
27+
return parsedGrep.some((orPart) => {
28+
return orPart.every((p) => {
29+
if (p.invert) {
30+
return !testName.includes(p.tag)
31+
}
2432

25-
return testName.includes(p.tag)
33+
return testName.includes(p.tag)
34+
})
2635
})
2736
}
2837

0 commit comments

Comments
 (0)