5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | work/
2 | target/
3 | test-output/
4 | .classpath
5 | .settings/
6 | .project
7 | **/*~
8 | .idea
9 | *.iml
10 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue16647/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests for issue JENKINS-16647.
3 | */
4 | package org.tap4j.plugin.issue16647;
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue16964/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests for issue JENKINS-16964.
3 | */
4 | package org.tap4j.plugin.issue16964;
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue17947/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests for issue JENKINS-17947.
3 | */
4 | package org.tap4j.plugin.issue17947;
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue21456/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests for issue JENKINS-21456.
3 | */
4 | package org.tap4j.plugin.issue21456;
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/stripsingleparent/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests stripping single parent feature.
3 | */
4 | package org.tap4j.plugin.stripsingleparent;
--------------------------------------------------------------------------------
/src/test/resources/org/tap4j/plugin/TapPublisherTest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/judovana/tap-plugin/master/src/test/resources/org/tap4j/plugin/TapPublisherTest.zip
--------------------------------------------------------------------------------
/src/test/resources/org/tap4j/plugin/tap-master-files/sample.tap:
--------------------------------------------------------------------------------
1 | 1..3
2 | ok 1
3 | not ok 2
4 | # some IO error
5 | # and more text here
6 | ok 3 # SKIP error in test 2
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/flattentapfeature/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests flatten TAP result feature feature.
3 | */
4 | package org.tap4j.plugin.flattentapfeature;
--------------------------------------------------------------------------------
/src/test/resources/org/tap4j/plugin/util/GraphHelperTest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/judovana/tap-plugin/master/src/test/resources/org/tap4j/plugin/util/GraphHelperTest.zip
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/removeyamlifcorrupted/package-info.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Tests corrupted YAML removal feature feature.
3 | */
4 | package org.tap4j.plugin.removeyamlifcorrupted;
--------------------------------------------------------------------------------
/src/test/resources/org/tap4j/plugin/PublishersCombinationTest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/judovana/tap-plugin/master/src/test/resources/org/tap4j/plugin/PublishersCombinationTest.zip
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | - fix performance issues
2 | - TapTestResultResult and TapResult could be merged?
3 | - look for code duplication
4 | - remove TapStreamResult#getFailedTests2()
5 | - look for open tasks
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/TapProjectAction/nodata.properties:
--------------------------------------------------------------------------------
1 | header=TAP Results
2 | description=No TAP results available yet!
3 | content=Run a build with TAP plugin enabled to see results here
4 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/TapResult/contents.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
${it.getContents(request.getParameter("f"))}
4 |
--------------------------------------------------------------------------------
/Jenkinsfile:
--------------------------------------------------------------------------------
1 | // Build the plugin using https://github.com/jenkins-infra/pipeline-library
2 | buildPlugin(useContainerAgent: true, failFast: false, forkCount: '1C', configurations: [
3 | [platform: 'linux', jdk: 17],
4 | ])
5 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/TapProjectAction/nodata_es.properties:
--------------------------------------------------------------------------------
1 | header=Resultados TAP
2 | description=Todavia no hay resultados TAP disponibles!
3 | content=Ejecute una build con el plugin TAP habilitado para ver los resultados ac\ufffd
4 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/TapProjectAction/nodata_pt.properties:
--------------------------------------------------------------------------------
1 | header=Resultados TAP
2 | description=Sem resultados TAP dispon\ufffdveis ainda.
3 | content=Execute uma constru\ufffd\ufffdo com o plugin TAP habilitado para ver os resultados aqui
4 |
--------------------------------------------------------------------------------
/src/main/webapp/help/TapPublisher/help-skipIfBuildNotOk.html:
--------------------------------------------------------------------------------
1 |
2 | If checked, the TAP post build step will be skipped if the build result status
3 | is not equal or better than UNSTABLE. i.e. if checked and a build step failed,
4 | the TAP publisher will be skipped.
5 |
2 | This HTML fragment will be injected into the configuration screen
3 | when the user clicks the 'help' icon. See global.jelly for how the
4 | form decides which page to load.
5 | You can have any HTML fragment here.
6 |
2 | Help file for fields are discovered through a file name convention. This file is
3 | help for the "name" field. You can have arbitrary HTML here. You can write
4 | this file as a Jelly script if you need a dynamic content (but if you do so, change
5 | the extension to .jelly).
6 |
2 | This option fails the build when no test results (files) are found. So if your job is
3 | configured to look for *.tap files, but when the plug-in looks at the workspace it
4 | cannot find any .tap file, and this option is checked, then your build will be marked
5 | as failure. If you have empty .tap, they still count, and the plug-in will not fail the build.
6 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.github/workflows/jenkins-security-scan.yml:
--------------------------------------------------------------------------------
1 | name: Jenkins Security Scan
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | types: [ opened, synchronize, reopened ]
9 | workflow_dispatch:
10 |
11 | permissions:
12 | security-events: write
13 | contents: read
14 | actions: read
15 |
16 | jobs:
17 | security-scan:
18 | uses: jenkins-infra/jenkins-security-scan/.github/workflows/jenkins-security-scan.yaml@v2
19 | with:
20 | java-cache: 'maven' # Optionally enable use of a build dependency cache. Specify 'maven' or 'gradle' as appropriate.
21 | # java-version: 21 # Optionally specify what version of Java to set up for the build, or remove to use a recent default.
22 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/tags/comments.jelly:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | # ${entry.text}
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue17947/TestIssue17947.java:
--------------------------------------------------------------------------------
1 | package org.tap4j.plugin.issue17947;
2 |
3 | import junit.framework.TestCase;
4 |
5 | import org.tap4j.model.TestSet;
6 | import org.tap4j.parser.Tap13Parser;
7 |
8 | public class TestIssue17947 extends TestCase {
9 |
10 | public void testSubtestsIssue17947() {
11 | // tap stream provided by issue reporter
12 | String tap = "1..3\n" +
13 | " 1..1\n" +
14 | " ok 1 - subtest 1\n" +
15 | "ok 1 - test 1\n" +
16 | " 1..4\n" +
17 | " ok 1 - subtest 1\n" +
18 | " ok 2 - subtest 2\n" +
19 | " ok 3 - subtest 3\n" +
20 | " ok 4 - subtest 4\n" +
21 | "ok 2 - test 2\n" +
22 | " 1..15\n" +
23 | " Bail out!\n" +
24 | " not ok 1 - test 3";
25 |
26 | Tap13Parser parser = new Tap13Parser(true);
27 | TestSet ts = parser.parseTapStream(tap);
28 | System.out.println(ts.getNumberOfTestResults());
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2011-2023, Bruno P. Kinoshita
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/tags/status.jelly:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/main/webapp/css/tap.css:
--------------------------------------------------------------------------------
1 | /* TAP Plug-in CSS styles */
2 |
3 | .cyan { background-color: #00FFFF; }
4 | .cyan_text { color: #00FFFF; }
5 | .green { background-color: #97f477; }
6 | .green_text { color: #97f477; }
7 | .red { background-color: #f88676; }
8 | .red_text { color: #B40404; }
9 | .yellow { background-color: #FFBF00 }
10 | .yellow_text { color: #FFBF00 }
11 | .center { text-align: center; }
12 | .underline { text-decoration: underline; }
13 | .bold {font-weight: 700;}
14 |
15 | table.tap
16 | {
17 | border: 0px solid;
18 | border-collapse:collapse;
19 | }
20 |
21 | table.tap th
22 | {
23 | border: 1px solid #999;
24 | padding: 2px 4px;
25 | background-color: #eee;
26 | color: #000;
27 | }
28 |
29 | table.tap td
30 | {
31 | border: 1px solid #999;
32 | padding: 2px 4px;
33 | }
34 |
35 | table.tap td.yaml
36 | {
37 | border: 1px solid #999;
38 | padding: 0px 0px;
39 | }
40 |
41 | table.yaml
42 | {
43 | border: 0px solid;
44 | border-collapse:collapse;
45 | }
46 |
47 | table.yaml td.hidden
48 | {
49 | background-color: white;
50 | border: 0px solid;
51 | color: white;
52 | padding: 0px;
53 | }
54 |
55 | table.yaml td
56 | {
57 | border: 1px solid #ccc;
58 | padding: 2px 4px;
59 | }
60 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/util/GraphHelperTest.java:
--------------------------------------------------------------------------------
1 | package org.tap4j.plugin.util;
2 |
3 |
4 | import hudson.model.TopLevelItem;
5 | import org.htmlunit.html.HtmlPage;
6 | import org.junit.Rule;
7 | import org.junit.Test;
8 | import org.jvnet.hudson.test.Issue;
9 | import org.jvnet.hudson.test.JenkinsRule;
10 | import org.jvnet.hudson.test.recipes.LocalData;
11 |
12 | import static org.junit.Assert.assertTrue;
13 |
14 |
15 | public class GraphHelperTest {
16 |
17 | @Rule
18 | public JenkinsRule rule = new JenkinsRule();
19 |
20 | @Issue("JENKINS-37623")
21 | @LocalData
22 | @Test
23 | public void renderTooltipsWithFailedBuilds() throws Exception {
24 |
25 | TopLevelItem project = rule.jenkins.getItem("testPipeline-randomly-no-data");
26 | try (JenkinsRule.WebClient wc = rule.createWebClient()) {
27 | HtmlPage page = wc.getPage(project);
28 |
29 | // there should be a TAP result trend graph
30 | rule.assertXPath(page, "//img[@src='tapResults/graph']");
31 |
32 | // check that tooltip is rendered for the last build
33 | rule.assertXPath(page, "//area[@title='1 Failure(s)' and @href='16/tapResults/']");
34 |
35 | // check that build without TAP action recorded is excluded from graph
36 | assertTrue(page.getByXPath("//area[@href='7/tapResults/']").isEmpty());
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/org/tap4j/plugin/util/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2013 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.util;
25 |
26 | public final class Constants {
27 |
28 | public static final String TAP_DIR_NAME = "tap-master-files";
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/tags/directive.jelly:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/main/resources/org/tap4j/plugin/TapPublisher/config.jelly:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/src/main/java/org/tap4j/plugin/util/Util.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2013 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.util;
25 |
26 | import org.tap4j.model.Directive;
27 | import org.tap4j.model.TestResult;
28 | import org.tap4j.util.DirectiveValues;
29 | import org.tap4j.util.StatusValues;
30 |
31 | /**
32 | * Utility methods used by tap-plugin.
33 | */
34 | public final class Util {
35 |
36 | private Util() {}
37 |
38 | /**
39 | * Normalizes a folder path in relation to the workspace path.
40 | *
41 | * A folder that is subdirectory of workspace will return only the difference.
42 | * It means that if the workspace is /home/workspace and the folder we want
43 | * to normalize is /home/workspace/job-1/test.txt, then the return will be
44 | * job-1/test.txt.
45 | *
46 | * @param workspace workspace path
47 | * @param relative relative path
48 | * @return normalized path
49 | */
50 | public static String normalizeFolders(String workspace, String relative) {
51 | workspace = workspace.replaceAll("\\\\", "\\/");
52 | relative = relative.replaceAll("\\\\", "\\/");
53 | if (relative.length() > workspace.length() && relative.contains(workspace)) {
54 | String temp = relative.substring(workspace.length());
55 | if (temp.startsWith("/") || temp.startsWith("\\"))
56 | temp = temp.substring(1);
57 | return temp;
58 | }
59 | return relative;
60 | }
61 |
62 | public static boolean isSkipped(TestResult testResult) {
63 | boolean r = false;
64 | Directive directive = testResult.getDirective();
65 | if (directive != null
66 | && directive.getDirectiveValue() == DirectiveValues.SKIP) {
67 | r = true;
68 | }
69 | return r;
70 | }
71 |
72 | public static boolean isTodo(TestResult testResult) {
73 | boolean r = false;
74 | Directive directive = testResult.getDirective();
75 | if (directive != null
76 | && directive.getDirectiveValue() == DirectiveValues.TODO) {
77 | r = true;
78 | }
79 | return r;
80 | }
81 |
82 | public static boolean isFailure(TestResult testResult, Boolean todoIsFailure) {
83 | boolean r = false;
84 | Directive directive = testResult.getDirective();
85 | StatusValues status = testResult.getStatus();
86 | if (directive != null) {
87 | if(directive.getDirectiveValue() == DirectiveValues.TODO && todoIsFailure != null && todoIsFailure) {
88 | r = true;
89 | }
90 | } else if (status == StatusValues.NOT_OK) {
91 | r = true;
92 | }
93 | return r;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/org/tap4j/plugin/model/TapAttachment.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2012 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.model;
25 |
26 | import java.util.Map;
27 |
28 | /**
29 | * @since 0.1
30 | */
31 | public class TapAttachment {
32 |
33 | private final String fileName;
34 | private final byte[] content;
35 | private final int size;
36 | private final String fileType;
37 |
38 | /**
39 | * @param fileName TAP file name
40 | * @param content byte content
41 | * @param size attachment size
42 | * @param fileType file mime type
43 | */
44 | public TapAttachment(String fileName, byte[] content, int size, String fileType) {
45 | super();
46 | this.fileName = fileName;
47 | this.content = content;
48 | this.size = size;
49 | this.fileType = fileType;
50 | }
51 |
52 | /**
53 | * @param content byte content
54 | * @param diagnostics TAP diagnostics
55 | */
56 | public TapAttachment(byte[] content, Map diagnostics) {
57 | super();
58 | this.content = content;
59 | int size = -1;
60 | String fileType = "";
61 | String fileName = "tapAttachment";
62 | for (Map.Entry entry : diagnostics.entrySet()) {
63 | final String key = entry.getKey();
64 | final Object value = entry.getValue();
65 | if (value instanceof Map, ?> == Boolean.FALSE) {
66 | if (key.equalsIgnoreCase("file-size")) {
67 | try {
68 | size = (int) Long.parseLong(diagnostics.get(key).toString());
69 | } catch (NumberFormatException nfe) {
70 | // Do nothing
71 | }
72 | } else if (key.equalsIgnoreCase("file-type")) {
73 | fileType = (String) diagnostics.get(key);
74 | } else if (key.equalsIgnoreCase("file-name")) {
75 | fileName = (String) diagnostics.get(key);
76 | }
77 | }
78 | }
79 | this.size = size;
80 | this.fileType = fileType;
81 | this.fileName = fileName;
82 | }
83 |
84 | /**
85 | * @return the fileName
86 | */
87 | public String getFileName() {
88 | return fileName;
89 | }
90 |
91 | /**
92 | * @return the content
93 | */
94 | public byte[] getContent() {
95 | return content;
96 | }
97 |
98 | /**
99 | * @return the size
100 | */
101 | public int getSize() {
102 | return size;
103 | }
104 |
105 | /**
106 | * @return the fileType
107 | */
108 | public String getFileType() {
109 | return fileType;
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/stripsingleparent/TestStripSingleParent.java:
--------------------------------------------------------------------------------
1 | package org.tap4j.plugin.stripsingleparent;
2 |
3 | import hudson.Launcher;
4 | import hudson.model.BuildListener;
5 | import hudson.model.FreeStyleBuild;
6 | import hudson.model.AbstractBuild;
7 | import hudson.model.FreeStyleProject;
8 |
9 | import static org.junit.Assert.assertEquals;
10 |
11 | import java.io.IOException;
12 | import java.util.concurrent.ExecutionException;
13 |
14 | import org.junit.Rule;
15 | import org.junit.Test;
16 | import org.jvnet.hudson.test.JenkinsRule;
17 | import org.jvnet.hudson.test.TestBuilder;
18 | import org.tap4j.plugin.TapPublisher;
19 | import org.tap4j.plugin.TapResult;
20 | import org.tap4j.plugin.TapTestResultAction;
21 |
22 | /**
23 | * At least basic tests for strip single parent configuration option.
24 | *
25 | * @author Jakub Podlesak
26 | */
27 | public class TestStripSingleParent {
28 |
29 | @Rule
30 | public JenkinsRule jenkins = new JenkinsRule();
31 |
32 | @Test
33 | public void testNoEffect() throws IOException, InterruptedException, ExecutionException {
34 |
35 | final String tap = "1..2\n" +
36 | " 1..3\n" +
37 | " ok 1 1.1\n" +
38 | " ok 2 1.2\n" +
39 | " ok 3 1.3\n" +
40 | "ok 1 - 1\n" +
41 | "ok 2 - 1\n";
42 |
43 | _test(tap, 2);
44 | }
45 |
46 | @Test
47 | public void testStripFirstLevel() throws IOException, InterruptedException, ExecutionException {
48 |
49 | final String tap = "1..1\n" +
50 | " 1..3\n" +
51 | " ok 1 1.1\n" +
52 | " ok 2 1.2\n" +
53 | " ok 3 1.3\n" +
54 | "ok 1 - 1\n";
55 |
56 | _test(tap, 3);
57 | }
58 |
59 | @Test
60 | public void testStripSecondLevel() throws IOException, InterruptedException, ExecutionException {
61 |
62 | final String tap =
63 | "1..1\n" +
64 | " 1..1\n" +
65 | " 1..3\n" +
66 | " ok 1 1.1.1\n" +
67 | " ok 2 1.1.2\n" +
68 | " ok 3 1.1.3\n" +
69 | " ok 1.1 - 1\n" +
70 | "ok 1 - 1\n";
71 |
72 | _test(tap, 3);
73 | }
74 |
75 | private void _test(final String tap, int expectedTotal) throws IOException, InterruptedException, ExecutionException {
76 | FreeStyleProject project = jenkins.createProject(FreeStyleProject.class, "strip-single-parents");
77 |
78 | project.getBuildersList().add(new TestBuilder() {
79 | @Override
80 | public boolean perform(AbstractBuild, ?> build, Launcher arg1,
81 | BuildListener arg2) throws InterruptedException, IOException {
82 | build.getWorkspace().child("result.tap").write(tap,"UTF-8");
83 | return true;
84 | }
85 | });
86 |
87 | TapPublisher publisher = new TapPublisher(
88 | "result.tap", // test results
89 | true, // failIfNoResults
90 | true, // failedTestsMarkBuildAsFailure
91 | false, // outputTapToConsole
92 | true, // enableSubtests
93 | true, // discardOldReports
94 | true, // todoIsFailure
95 | true, // includeCommentDiagnostics
96 | true, // validateNumberOfTests
97 | true, // planRequired
98 | false, // verbose
99 | true, // showOnlyFailures
100 | true, // stripSingleParents
101 | false, // flattenTapResult
102 | false,
103 | false);
104 |
105 | project.getPublishersList().add(publisher);
106 | project.save();
107 | FreeStyleBuild build = (FreeStyleBuild) project.scheduleBuild2(0).get();
108 |
109 | TapTestResultAction action = build.getAction(TapTestResultAction.class);
110 | TapResult testResult = action.getTapResult();
111 |
112 | assertEquals(expectedTotal, testResult.getPassed());
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/main/java/org/tap4j/plugin/TapBuildAction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2011 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin;
25 |
26 | import hudson.model.Action;
27 | import hudson.model.Run;
28 | import org.kohsuke.stapler.StaplerProxy;
29 |
30 | import javax.annotation.Nullable;
31 | import java.io.Serializable;
32 |
33 | /**
34 | * TAP Build action with TAP results.
35 | *
36 | * @since 1.0
37 | */
38 | public class TapBuildAction implements Action, Serializable, StaplerProxy {
39 |
40 | private static final long serialVersionUID = 520981690971849654L;
41 | public static final String URL_NAME = "tapResults";
42 | public static final String ICON_NAME = "/plugin/tap/icons/tap-24.png";
43 | public static final String DISPLAY_NAME = "TAP Extended Test Results";
44 |
45 | private final transient Run, ?> build;
46 |
47 | private TapResult result;
48 |
49 | public TapBuildAction(Run, ?> build, TapResult result) {
50 | super();
51 | this.build = build;
52 | this.result = result;
53 | }
54 |
55 | /*
56 | * (non-Javadoc)
57 | *
58 | * @see org.kohsuke.stapler.StaplerProxy#getTarget()
59 | */
60 | public Object getTarget() {
61 | return this.result;
62 | }
63 |
64 | /*
65 | * (non-Javadoc)
66 | *
67 | * @see hudson.model.Action#getDisplayName()
68 | */
69 | public String getDisplayName() {
70 | return DISPLAY_NAME;
71 | }
72 |
73 | /*
74 | * (non-Javadoc)
75 | *
76 | * @see hudson.model.Action#getIconFileName()
77 | */
78 | public String getIconFileName() {
79 | return ICON_NAME;
80 | }
81 |
82 | /*
83 | * (non-Javadoc)
84 | *
85 | * @see hudson.model.Action#getUrlName()
86 | */
87 | public String getUrlName() {
88 | return URL_NAME;
89 | }
90 |
91 | /**
92 | * @return the build
93 | */
94 | @Nullable
95 | public Run, ?> getBuild() {
96 | return this.build;
97 | }
98 |
99 | public TapResult getResult() {
100 | return this.result;
101 | }
102 |
103 | public TapResult getPreviousResult() {
104 | TapResult previousResult = null;
105 |
106 | TapBuildAction previousAction = this.getPreviousAction();
107 |
108 | if (previousAction != null) {
109 | previousResult = previousAction.getResult();
110 | }
111 |
112 | return previousResult;
113 | }
114 |
115 | public TapBuildAction getPreviousAction() {
116 | TapBuildAction previousAction = null;
117 |
118 | if (this.build != null) {
119 | Run, ?> previousBuild = this.build.getPreviousBuild();
120 | if (previousBuild != null) {
121 | previousAction = previousBuild.getAction(TapBuildAction.class);
122 | }
123 | }
124 |
125 | return previousAction;
126 | }
127 |
128 | public void mergeResult(TapResult other) {
129 | result = result.copyWithExtraTestSets(other.getTestSets());
130 | result.tally();
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/PublishersCombinationTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2009, Yahoo!, Inc.
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin;
25 |
26 | import hudson.model.Project;
27 | import hudson.model.TopLevelItem;
28 | import org.htmlunit.html.HtmlPage;
29 | import org.junit.Rule;
30 | import org.junit.Test;
31 | import org.junit.jupiter.api.Disabled;
32 | import org.jvnet.hudson.test.Issue;
33 | import org.jvnet.hudson.test.JenkinsRule;
34 | import org.jvnet.hudson.test.recipes.LocalData;
35 |
36 | @Disabled("Failing on newer versions of Jenkins, 2.414+, but working when ran locally. TODO: fix it.")
37 | public class PublishersCombinationTest {
38 |
39 | // @Rule
40 | public JenkinsRule rule = new JenkinsRule();
41 |
42 | // @Issue("JENKINS-29649")
43 | // @LocalData
44 | // @Test
45 | public void combinedWithJunitBasic() throws Exception {
46 |
47 | Project, ?> project = (Project, ?>) rule.jenkins.getItem("multiPublish");
48 |
49 | // Validate that there are test results where I expect them to be:
50 | try (JenkinsRule.WebClient wc = rule.createWebClient()) {
51 | // On the project page:
52 | HtmlPage projectPage = wc.getPage(project);
53 |
54 | assertJunitPart(projectPage, 3, 4);
55 | assertTapPart(projectPage, 3);
56 | }
57 | }
58 |
59 | // @Issue("JENKINS-29649")
60 | // @LocalData
61 | // @Test
62 | public void combinedWithJunitPipeline() throws Exception {
63 |
64 | TopLevelItem project = rule.jenkins.getItem("testPipeline");
65 |
66 | // Validate that there are test results where I expect them to be:
67 | try (JenkinsRule.WebClient wc = rule.createWebClient()) {
68 | // On the project page:
69 | HtmlPage projectPage = wc.getPage(project);
70 |
71 | assertJunitPart(projectPage, 15, 7);
72 | assertTapPart(projectPage, 15);
73 | }
74 | }
75 |
76 | private void assertJunitPart(HtmlPage page, int buildNumber, int testsTotal) {
77 |
78 | // we should have a link that reads "Latest Test Result"
79 | // that link should go to http://localhost:8080/job/breakable/lastBuild/testReport/
80 | rule.assertXPath(page, "//a[@href='lastCompletedBuild/testReport/']");
81 | rule.assertXPathValue(page, "//a[@href='lastCompletedBuild/testReport/']", "Latest Test Result");
82 | rule.assertXPathValueContains(page, "//a[@href='lastCompletedBuild/testReport/']", "Latest Test Result");
83 |
84 | // there should be a test result trend graph
85 | rule.assertXPath(page, "//img[@src='test/trend']");
86 |
87 | // superficially assert that the number of tests was correct
88 | rule.assertXPath(
89 | page,
90 | String.format("//area[@title='#%1$s: %2$s tests' and @href='%1$s/testReport/']", buildNumber, testsTotal)
91 | );
92 | }
93 |
94 | private void assertTapPart(HtmlPage page, int buildNumber) {
95 |
96 | // there should be a TAP result trend graph
97 | rule.assertXPath(page, "//img[@src='tapResults/graph']");
98 |
99 | // superficially assert that the number of tests was correct
100 | rule.assertXPath(page, String.format("//area[@title='1 Skip(s)' and @href='%s/tapResults/']", buildNumber));
101 | }
102 | }
103 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/issue21456/TestIssue21456.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2010-2023 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.issue21456;
25 |
26 | import hudson.Launcher;
27 | import hudson.model.AbstractBuild;
28 | import hudson.model.BuildListener;
29 | import hudson.model.FreeStyleProject;
30 | import hudson.tasks.Shell;
31 | import org.junit.Rule;
32 | import org.junit.Test;
33 | import org.jvnet.hudson.test.JenkinsRule;
34 | import org.jvnet.hudson.test.TestBuilder;
35 | import org.tap4j.plugin.TapPublisher;
36 | import org.tap4j.plugin.TapTestResultAction;
37 |
38 | import java.io.IOException;
39 | import java.util.Objects;
40 | import java.util.concurrent.ExecutionException;
41 |
42 | import static org.junit.Assert.assertNull;
43 |
44 | /**
45 | * Tests that Jenkins can be configured to skip using the TAP Plug-in
46 | * when the build fails.
47 | */
48 | public class TestIssue21456 {
49 |
50 | public @Rule JenkinsRule jenkins = new JenkinsRule();
51 |
52 | @Test
53 | public void testDurationMs() throws IOException, InterruptedException, ExecutionException {
54 | final FreeStyleProject project = jenkins.createFreeStyleProject("tap-bug-21456");
55 |
56 | final String tap = String.join("\n",
57 | "1..2",
58 | "ok 1 - Input file opened",
59 | "not ok 2 - First line of the input valid",
60 | " ---",
61 | " duration_ms: 100660.00",
62 | " ...");
63 |
64 | project
65 | .getBuildersList()
66 | .add(new TestBuilder() {
67 | @Override
68 | public boolean perform(AbstractBuild, ?> build, Launcher arg1,
69 | BuildListener arg2) throws InterruptedException, IOException {
70 | Objects.requireNonNull(build.getWorkspace()).child("result.tap").write(tap, "UTF-8");
71 | return true;
72 | }
73 | });
74 |
75 | project.getBuildersList().add(new Shell("exit 255"));
76 |
77 | final TapPublisher publisher = new TapPublisher(
78 | "result.tap", // testResults
79 | true, // failIfNoResults
80 | true, // failedTestsMarkBuildAsFailure
81 | true, // outputTapToConsole
82 | true, // enableSubtests
83 | true, // discardOldReports
84 | true, // todoIsFailure
85 | true, // includeCommentDiagnostics
86 | true, // validateNumberOfTests
87 | false, // planRequired
88 | true, // verbose
89 | false, // showOnlyFailures
90 | false, // stripSingleParents
91 | false, // flattenTapResult
92 | true, // removeYamlIfCorrupted
93 | true); //skipIfBuildNotOk <-- that's the one we are testing here
94 | project.getPublishersList().add(publisher);
95 | project.save();
96 |
97 | TapTestResultAction action = project
98 | .scheduleBuild2(0)
99 | .get()
100 | .getAction(TapTestResultAction.class);
101 |
102 | assertNull(
103 | "Not supposed to have a TAP action. Should have skipped a failed build!",
104 | action);
105 | }
106 |
107 | }
108 |
--------------------------------------------------------------------------------
/src/test/java/org/tap4j/plugin/jenkins_cert_3190/TestXssTapFile.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2023 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.jenkins_cert_3190;
25 |
26 | import hudson.model.FreeStyleProject;
27 | import hudson.model.Run;
28 | import hudson.tasks.Shell;
29 | import org.htmlunit.CollectingAlertHandler;
30 | import org.junit.Rule;
31 | import org.junit.Test;
32 | import org.jvnet.hudson.test.Issue;
33 | import org.jvnet.hudson.test.JenkinsRule;
34 | import org.tap4j.plugin.TapPublisher;
35 | import org.xml.sax.SAXException;
36 |
37 | import java.io.IOException;
38 | import java.util.List;
39 | import java.util.concurrent.ExecutionException;
40 | import java.util.concurrent.Future;
41 |
42 | import static org.junit.Assert.assertEquals;
43 |
44 | /**
45 | * Prevent a case where TAP files with JavaScript code are
46 | * evaluated by the plug-in.
47 | *
48 | * @since 2.4.1
49 | */
50 | @Issue("3190")
51 | public class TestXssTapFile {
52 |
53 | @Rule
54 | public JenkinsRule j = new JenkinsRule();
55 |
56 | @Test
57 | public void testTapFileXss() throws IOException, SAXException, ExecutionException, InterruptedException {
58 | final FreeStyleProject project = j.createFreeStyleProject();
59 |
60 | // We can add more scenarios where XSS must be prevented in
61 | // the TAP stream. Just modify the file below, trying to use
62 | // the next N in `alert(N)` so that it is easier to detect
63 | // where it is coming from.
64 | final Shell shell = new Shell("echo \"\n" +
65 | "1..4 # \n" +
66 | "ok 1 - OK # \n" +
67 | " ---\n" +
68 | " extensions:\n" +
69 | " injected\n" +
70 | " ...\n" +
71 | "# \n" +
72 | "not ok 2 - failed! \n" +
73 | "ok 3 - # SKIP \n" +
74 | "ok 4 # TODO \n" +
75 | "\" > payload.tap\n");
76 | project.getBuildersList().add(shell);
77 |
78 | final TapPublisher tapPublisher = new TapPublisher(
79 | "**/*.tap",
80 | true,
81 | true,
82 | true,
83 | true,
84 | true,
85 | true,
86 | true,
87 | true,
88 | true,
89 | true,
90 | false,
91 | true,
92 | true,
93 | true,
94 | true
95 | );
96 | project.getPublishersList().add(tapPublisher);
97 |
98 | project.save();
99 |
100 | final CollectingAlertHandler alertHandler = new CollectingAlertHandler();
101 | try (final JenkinsRule.WebClient wc = j.createWebClient()) {
102 | wc.setThrowExceptionOnFailingStatusCode(false);
103 | wc.setAlertHandler(alertHandler);
104 |
105 | Future> f = project.scheduleBuild2(0);
106 | Run, ?> build = (Run, ?>) f.get();
107 |
108 | wc.goTo("job/" + project.getName() + "/" + build.getNumber() + "/tapResults/");
109 |
110 | final List alerts = alertHandler.getCollectedAlerts();
111 |
112 | assertEquals("You got a JS alert, look out for XSS!", 0, alerts.size());
113 | }
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/test/resources/org/tap4j/plugin/tap-master-files/subtest-sample.tap:
--------------------------------------------------------------------------------
1 | TAP version 13
2 | # Subtest: test/tap/access.js
3 | # Subtest: setup
4 | ok 1 - /workdir/npm-module/test/tap/access made successfully
5 | ok 2 - registry mocked successfully
6 | ok 3 - wrote package.json
7 | 1..3
8 | ok 1 - setup # time=68.43ms
9 |
10 | # Subtest: npm access public on current package
11 | ok 1 - npm access
12 | ok 2 - exited OK
13 | ok 3 - no error output
14 | 1..3
15 | ok 2 - npm access public on current package # time=543.472ms
16 |
17 | # Subtest: npm access public when no package passed and no package.json
18 | ok 1 - npm access
19 | ok 2 - should match pattern provided
20 | 1..2
21 | ok 3 - npm access public when no package passed and no package.json # time=457.195ms
22 |
23 | # Subtest: npm access public when no package passed and invalid package.json
24 | ok 1 - npm access
25 | ok 2 - should match pattern provided
26 | 1..2
27 | ok 4 - npm access public when no package passed and invalid package.json # time=458.715ms
28 |
29 | # Subtest: npm access restricted on current package
30 | ok 1 - npm access
31 | ok 2 - exited OK
32 | ok 3 - no error output
33 | 1..3
34 | ok 5 - npm access restricted on current package # time=548.049ms
35 |
36 | # Subtest: npm access on named package
37 | ok 1 - npm access
38 | ok 2 - exited OK
39 | ok 3 - no error output
40 | 1..3
41 | ok 6 - npm access on named package # time=519.159ms
42 |
43 | # Subtest: npm change access on unscoped package
44 | ok 1 - exited with Error
45 | ok 2 - should match pattern provided
46 | 1..2
47 | ok 7 - npm change access on unscoped package # time=461.458ms
48 |
49 | # Subtest: npm access grant read-only
50 | ok 1 - npm access grant
51 | ok 2 - exited with Error
52 | 1..2
53 | ok 8 - npm access grant read-only # time=517.935ms
54 |
55 | # Subtest: npm access grant read-write
56 | ok 1 - npm access grant
57 | ok 2 - exited with Error
58 | 1..2
59 | ok 9 - npm access grant read-write # time=525.574ms
60 |
61 | # Subtest: npm access grant others
62 | ok 1 - exited with Error
63 | ok 2 - should match pattern provided
64 | ok 3 - should match pattern provided
65 | 1..3
66 | ok 10 - npm access grant others # time=473.668ms
67 |
68 | # Subtest: npm access revoke
69 | ok 1 - npm access grant
70 | ok 2 - exited with Error
71 | 1..2
72 | ok 11 - npm access revoke # time=529.943ms
73 |
74 | # Subtest: npm access ls-packages with no team
75 | ok 1 - npm access ls-packages
76 | ok 2 - should be equivalent
77 | 1..2
78 | ok 12 - npm access ls-packages with no team # time=512.118ms
79 |
80 | # Subtest: npm access ls-packages on team
81 | ok 1 - npm access ls-packages
82 | ok 2 - should be equivalent
83 | 1..2
84 | ok 13 - npm access ls-packages on team # time=530.445ms
85 |
86 | # Subtest: npm access ls-packages on org
87 | ok 1 - npm access ls-packages
88 | ok 2 - should be equivalent
89 | 1..2
90 | ok 14 - npm access ls-packages on org # time=538.885ms
91 |
92 | # Subtest: npm access ls-packages on user
93 | ok 1 - npm access ls-packages
94 | ok 2 - should be equivalent
95 | 1..2
96 | ok 15 - npm access ls-packages on user # time=509.704ms
97 |
98 | # Subtest: npm access ls-packages with no package specified or package.json
99 | ok 1 - npm access ls-packages
100 | ok 2 - should be equivalent
101 | 1..2
102 | ok 16 - npm access ls-packages with no package specified or package.json # time=506.721ms
103 |
104 | # Subtest: npm access ls-collaborators on current
105 | ok 1 - npm access ls-collaborators
106 | ok 2 - should be equivalent
107 | 1..2
108 | ok 17 - npm access ls-collaborators on current # time=516.851ms
109 |
110 | # Subtest: npm access ls-collaborators on package
111 | ok 1 - npm access ls-collaborators
112 | ok 2 - should be equivalent
113 | 1..2
114 | ok 18 - npm access ls-collaborators on package # time=508.724ms
115 |
116 | # Subtest: npm access ls-collaborators on current w/user filter
117 | ok 1 - npm access ls-collaborators
118 | ok 2 - should be equivalent
119 | 1..2
120 | ok 19 - npm access ls-collaborators on current w/user filter # time=501.361ms
121 |
122 | # Subtest: npm access edit
123 | ok 1 - exited with Error
124 | ok 2 - should match pattern provided
125 | 1..2
126 | ok 20 - npm access edit # time=444.677ms
127 |
128 | # Subtest: npm access blerg
129 | ok 1 - exited with Error
130 | ok 2 - should match pattern provided
131 | 1..2
132 | ok 21 - npm access blerg # time=443.858ms
133 |
134 | # Subtest: cleanup
135 | ok 1 - cleaned up
136 | 1..1
137 | ok 22 - cleanup # time=3.574ms
138 |
139 | 1..22
140 | # time=10166.406ms
141 | ok 1 - test/tap/access.js # time=10398.064ms
142 |
143 | 1..1
144 | # time=10431.957ms
--------------------------------------------------------------------------------
/src/main/java/org/tap4j/plugin/util/DiagnosticUtil.java:
--------------------------------------------------------------------------------
1 | /*
2 | * The MIT License
3 | *
4 | * Copyright (c) 2010 Bruno P. Kinoshita
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | package org.tap4j.plugin.util;
25 |
26 | import hudson.Functions;
27 | import org.apache.commons.lang.StringEscapeUtils;
28 |
29 | import java.util.Arrays;
30 | import java.util.List;
31 | import java.util.Locale;
32 | import java.util.Map;
33 | import java.util.Map.Entry;
34 | import java.util.Set;
35 |
36 | /**
37 | * Used to create YAML view. FIXME: Figure out another way to write HTML (send JSON to Stapler/Groovy/etc.?).
38 | *
39 | * @since 1.0
40 | * @deprecated To be soon removed by something easier to maintain (return JSON to JS?).
41 | */
42 | public class DiagnosticUtil {
43 |
44 | private enum RENDER_TYPE {
45 | TEXT, IMAGE
46 | }
47 |
48 | private static final String INNER_TABLE_HEADER = "