Skip to content

Commit 664a647

Browse files
cli: extract from output by regexp
1 parent 0f87cc7 commit 664a647

10 files changed

Lines changed: 126 additions & 14 deletions

File tree

webtau-cli/src/main/java/org/testingisdocumenting/webtau/cli/CliForegroundCommand.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ private CliRunResult cliStep(String command, CliProcessConfig config, Consumer<C
6060

6161
try {
6262
step.execute(StepReportOptions.REPORT_ALL);
63-
return new CliRunResult(validationResult.getExitCode().get(),
63+
return new CliRunResult(command,
64+
validationResult.getExitCode().get(),
6465
validationResult.getOut().get(),
6566
validationResult.getErr().get());
6667
} finally {

webtau-cli/src/main/java/org/testingisdocumenting/webtau/cli/CliRunResult.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,22 @@
1616

1717
package org.testingisdocumenting.webtau.cli;
1818

19+
import org.testingisdocumenting.webtau.reporter.StepReportOptions;
20+
import org.testingisdocumenting.webtau.reporter.WebTauStep;
21+
import org.testingisdocumenting.webtau.utils.RegexpUtils;
22+
23+
import static org.testingisdocumenting.webtau.reporter.IntegrationTestsMessageBuilder.*;
24+
import static org.testingisdocumenting.webtau.reporter.IntegrationTestsMessageBuilder.stringValue;
25+
import static org.testingisdocumenting.webtau.reporter.TokenizedMessage.tokenizedMessage;
26+
1927
public class CliRunResult {
28+
private final String command;
2029
private final int exitCode;
2130
private final String output;
2231
private final String error;
2332

24-
public CliRunResult(int exitCode, String output, String error) {
33+
public CliRunResult(String command, int exitCode, String output, String error) {
34+
this.command = command;
2535
this.exitCode = exitCode;
2636
this.output = output;
2737
this.error = error;
@@ -38,4 +48,33 @@ public String getOutput() {
3848
public String getError() {
3949
return error;
4050
}
51+
52+
public String extractFromOutputByRegexp(String regexp) {
53+
return extractFromSourceByRegexp("stdout", output, regexp);
54+
}
55+
56+
public String extractFromErrorByRegexp(String regexp) {
57+
return extractFromSourceByRegexp("stderr", error, regexp);
58+
}
59+
60+
private String extractFromSourceByRegexp(String sourceLabel, String source, String regexp) {
61+
WebTauStep step = WebTauStep.createStep(null,
62+
tokenizedMessage(action("extracting text"), classifier("by regexp"), stringValue(regexp),
63+
FROM, urlValue(command), classifier(sourceLabel)),
64+
(r) -> tokenizedMessage(action("extracted text"), classifier("by regexp"), stringValue(regexp),
65+
FROM, urlValue(command), classifier(sourceLabel), COLON, stringValue(r)),
66+
() -> extractByRegexpStepImpl(sourceLabel, source, regexp));
67+
68+
return step.execute(StepReportOptions.SKIP_START);
69+
}
70+
71+
private String extractByRegexpStepImpl(String sourceLabel, String source, String regexp) {
72+
String extracted = RegexpUtils.extractByRegexp(source, regexp);
73+
if (extracted == null) {
74+
throw new RuntimeException("can't find content to extract using regexp <" + regexp + "> from " +
75+
sourceLabel + " of " + command);
76+
}
77+
78+
return extracted;
79+
}
4180
}

webtau-docs/znai/cli/foreground-command.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,20 @@ Use the result of `cli.run` if you need to process the output of the command.
4949

5050
Warning: Perform validation inside validation block so webtau can track what was checked.
5151

52+
:include-file: doc-artifacts/snippets/foreground-cli/runResultExtractOutput.groovy {
53+
title: "extract from output by regexp",
54+
startLine: "example",
55+
endLine: "example",
56+
excludeStartEnd: true
57+
}
58+
59+
:include-file: doc-artifacts/snippets/foreground-cli/runResultExtractError.groovy {
60+
title: "extract from error by regexp",
61+
startLine: "example",
62+
endLine: "example",
63+
excludeStartEnd: true
64+
}
65+
5266
# Working Dir
5367

5468
Use `cli.workingDir` as a second parameter to `cli.run` to set a working dir:

webtau-feature-testing/examples/scenarios/cli/foregroundExamples.groovy

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,22 @@ scenario("command run result") {
4040
if (result.exitCode == 1) {
4141
// ...
4242
}
43+
}
44+
45+
scenario("run result extract by regexp from output") {
46+
// example
47+
def result = cli.run('scripts/generate-id')
48+
def id = result.extractFromOutputByRegexp("id=(\\d+)")
49+
// example
50+
51+
id.should == "4321254"
52+
}
53+
54+
scenario("run result extract by regexp from error") {
55+
// example
56+
def result = cli.run('scripts/generate-id')
57+
def id = result.extractFromErrorByRegexp("id=(\\d+)")
58+
// example
59+
60+
id.should == "123457"
4361
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
echo generating id
3+
echo id=4321254
4+
>&2 echo can not create entity with id=123457

webtau-feature-testing/src/test/groovy/org/testingisdocumenting/webtau/featuretesting/WebTauCliFeaturesTest.groovy

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ class WebTauCliFeaturesTest {
5050
'withErrorValidation.groovy': 'command with error validation',
5151
'withExitCodeValidation.groovy': 'command with exit code validation',
5252
'implicitExitCodeBehindScenes.groovy': 'command implicit exit code check explicitly',
53-
'runResult.groovy': 'command run result'
53+
'runResult.groovy': 'command run result',
54+
'runResultExtractOutput.groovy': 'run result extract by regexp from output',
55+
'runResultExtractError.groovy': 'run result extract by regexp from error'
5456
])
5557
}
5658

webtau-feature-testing/test-expectations/scenarios/cli/foregroundExamples/run-details.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,18 @@
3535
"stepsSummary" : {
3636
"numberOfSuccessful" : 2
3737
}
38+
}, {
39+
"scenario" : "run result extract by regexp from output",
40+
"shortContainerId" : "foregroundExamples.groovy",
41+
"stepsSummary" : {
42+
"numberOfSuccessful" : 3
43+
}
44+
}, {
45+
"scenario" : "run result extract by regexp from error",
46+
"shortContainerId" : "foregroundExamples.groovy",
47+
"stepsSummary" : {
48+
"numberOfSuccessful" : 3
49+
}
3850
} ],
3951
"exitCode" : 0
4052
}

webtau-filesystem/src/main/java/org/testingisdocumenting/webtau/fs/FileTextContent.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
import org.testingisdocumenting.webtau.expectation.ActualValueExpectations;
2222
import org.testingisdocumenting.webtau.expectation.ValueMatcher;
2323
import org.testingisdocumenting.webtau.expectation.timer.ExpectationTimer;
24-
import org.testingisdocumenting.webtau.reporter.*;
24+
import org.testingisdocumenting.webtau.reporter.IntegrationTestsMessageBuilder;
25+
import org.testingisdocumenting.webtau.reporter.StepReportOptions;
26+
import org.testingisdocumenting.webtau.reporter.ValueMatcherExpectationSteps;
27+
import org.testingisdocumenting.webtau.reporter.WebTauStep;
2528
import org.testingisdocumenting.webtau.utils.FileUtils;
29+
import org.testingisdocumenting.webtau.utils.RegexpUtils;
2630

2731
import java.nio.file.Path;
28-
import java.util.regex.Matcher;
29-
import java.util.regex.Pattern;
3032

3133
import static org.testingisdocumenting.webtau.reporter.IntegrationTestsMessageBuilder.*;
3234
import static org.testingisdocumenting.webtau.reporter.TokenizedMessage.tokenizedMessage;
@@ -55,9 +57,9 @@ public ActualPath actualPath() {
5557

5658
public String extractByRegexp(String regexp) {
5759
WebTauStep step = WebTauStep.createStep(null,
58-
tokenizedMessage(action("extracting text"), classifier("by regexp"),
59-
FROM, urlValue(path), COLON, stringValue(regexp)),
60-
(r) -> tokenizedMessage(action("extracted text"), classifier("by regexp"),
60+
tokenizedMessage(action("extracting text"), classifier("by regexp"), stringValue(regexp),
61+
FROM, urlValue(path)),
62+
(r) -> tokenizedMessage(action("extracted text"), classifier("by regexp"), stringValue(regexp),
6163
FROM, urlValue(path), COLON, stringValue(r)),
6264
() -> extractByRegexpStepImpl(regexp));
6365

@@ -96,13 +98,11 @@ public String toString() {
9698
}
9799

98100
private String extractByRegexpStepImpl(String regexp) {
99-
Pattern pattern = Pattern.compile(regexp);
100-
Matcher matcher = pattern.matcher(getData());
101-
boolean found = matcher.find();
102-
if (!found) {
101+
String extracted = RegexpUtils.extractByRegexp(getData(), regexp);
102+
if (extracted == null) {
103103
throw new RuntimeException("can't find content to extract using regexp <" + regexp + "> from: " + path);
104104
}
105105

106-
return matcher.group(1);
106+
return extracted;
107107
}
108108
}

webtau-utils/src/main/java/org/testingisdocumenting/webtau/utils/RegexpUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright 2021 webtau maintainers
23
* Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
34
*
45
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -36,4 +37,15 @@ public static String replaceAll(String source, Pattern regexp, Function<Matcher,
3637

3738
return result.toString();
3839
}
40+
41+
public static String extractByRegexp(String source, String regexp) {
42+
Pattern pattern = Pattern.compile(regexp);
43+
Matcher matcher = pattern.matcher(source);
44+
boolean found = matcher.find();
45+
if (!found) {
46+
return null;
47+
}
48+
49+
return matcher.group(1);
50+
}
3951
}

webtau-utils/src/test/groovy/org/testingisdocumenting/webtau/utils/RegexpUtilsTest.groovy

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* Copyright 2021 webtau maintainers
23
* Copyright 2019 TWO SIGMA OPEN SOURCE, LLC
34
*
45
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -25,4 +26,13 @@ class RegexpUtilsTest {
2526
def replaced = RegexpUtils.replaceAll("hello 10 world of 42 numbers", ~/(\d)\d*/, { m -> '"' + m.group(1) + '"' })
2627
Assert.assertEquals('hello "1" world of "4" numbers', replaced)
2728
}
29+
30+
@Test
31+
void "extract value by regexp"() {
32+
Assert.assertEquals("123",
33+
RegexpUtils.extractByRegexp("line 1\nline 2\nhello id=123 ere\n", "id=(\\d+)"))
34+
35+
Assert.assertEquals(null,
36+
RegexpUtils.extractByRegexp("line 1\nline 2\nhello id=123 ere\n", "bid=(\\d+)"))
37+
}
2838
}

0 commit comments

Comments
 (0)