Objects of this class are immutable and thread-safe.
18 | *
19 | * @since 1.3
20 | */
21 | @Immutable
22 | @ToString
23 | @EqualsAndHashCode(callSuper = false, of = "pattern")
24 | final class RegexMatchingPatternMatcher extends TypeSafeMatcher {
25 |
26 | /**
27 | * The Regex pattern.
28 | */
29 | private final transient String pattern;
30 |
31 | /**
32 | * Public ctor.
33 | * @param regex The regular expression to match against.
34 | */
35 | RegexMatchingPatternMatcher(final String regex) {
36 | super();
37 | this.pattern = regex;
38 | }
39 |
40 | @Override
41 | public void describeTo(final Description description) {
42 | description.appendText("a String matching the regular expression ")
43 | .appendText(this.pattern);
44 | }
45 |
46 | @Override
47 | public boolean matchesSafely(final String item) {
48 | return item.matches(this.pattern);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/com/jcabi/matchers/RegexContainingPatternMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3 | * SPDX-License-Identifier: MIT
4 | */
5 | package com.jcabi.matchers;
6 |
7 | import java.util.regex.Pattern;
8 | import lombok.EqualsAndHashCode;
9 | import lombok.ToString;
10 | import org.hamcrest.Description;
11 | import org.hamcrest.TypeSafeMatcher;
12 |
13 | /**
14 | * Checks if a given string contains a subsequence matching the given pattern,
15 | * similar to {@link java.util.regex.Matcher#find()}.
16 | *
17 | *
Objects of this class are immutable and thread-safe.
18 | *
19 | * @since 1.3
20 | */
21 | @ToString
22 | @EqualsAndHashCode(callSuper = false, of = "pattern")
23 | final class RegexContainingPatternMatcher extends TypeSafeMatcher {
24 |
25 | /**
26 | * The Regex pattern.
27 | */
28 | private final transient Pattern pattern;
29 |
30 | /**
31 | * Public ctor.
32 | * @param regex The regular expression to match against.
33 | */
34 | RegexContainingPatternMatcher(final String regex) {
35 | super();
36 | this.pattern = Pattern.compile(regex);
37 | }
38 |
39 | @Override
40 | public void describeTo(final Description description) {
41 | description.appendText("a String containing the regular expression ")
42 | .appendText(this.pattern.toString());
43 | }
44 |
45 | @Override
46 | public boolean matchesSafely(final String item) {
47 | return this.pattern.matcher(item).find();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2025 Yegor Bugayenko
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met: 1) Redistributions of source code must retain the above
7 | copyright notice, this list of conditions and the following
8 | disclaimer. 2) Redistributions in binary form must reproduce the above
9 | copyright notice, this list of conditions and the following
10 | disclaimer in the documentation and/or other materials provided
11 | with the distribution. 3) Neither the name of the jcabi.com nor
12 | the names of its contributors may be used to endorse or promote
13 | products derived from this software without specific prior written
14 | permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
18 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 | THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 | OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/LICENSES/MIT.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011-2025 Yegor Bugayenko
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met: 1) Redistributions of source code must retain the above
7 | copyright notice, this list of conditions and the following
8 | disclaimer. 2) Redistributions in binary form must reproduce the above
9 | copyright notice, this list of conditions and the following
10 | disclaimer in the documentation and/or other materials provided
11 | with the distribution. 3) Neither the name of the jcabi.com nor
12 | the names of its contributors may be used to endorse or promote
13 | products derived from this software without specific prior written
14 | permission.
15 |
16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
18 | NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 | THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 | OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/src/main/java/com/jcabi/matchers/W3CMatchers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3 | * SPDX-License-Identifier: MIT
4 | */
5 | package com.jcabi.matchers;
6 |
7 | import com.jcabi.w3c.ValidatorBuilder;
8 | import lombok.EqualsAndHashCode;
9 | import lombok.ToString;
10 | import org.hamcrest.Matcher;
11 |
12 | /**
13 | * Matchers for validating HTML and CSS content.
14 | *
15 | * @since 0.1
16 | */
17 | @ToString
18 | @EqualsAndHashCode
19 | @SuppressWarnings("PMD.ProhibitPublicStaticMethods")
20 | public final class W3CMatchers {
21 |
22 | /**
23 | * Default HTML online validator.
24 | */
25 | private static final W3CValidatorMatcher HTML =
26 | new W3CValidatorMatcher(ValidatorBuilder.HTML);
27 |
28 | /**
29 | * Default online CSS validator.
30 | */
31 | private static final W3CValidatorMatcher CSS =
32 | new W3CValidatorMatcher(ValidatorBuilder.CSS);
33 |
34 | /**
35 | * Private ctor, it's a utility class.
36 | */
37 | private W3CMatchers() {
38 | // intentionally empty
39 | }
40 |
41 | /**
42 | * Matcher for validating HTML content against W3C validation servers.
43 | * @return Matcher for validating HTML content.
44 | */
45 | public static Matcher validHtml() {
46 | return W3CMatchers.HTML;
47 | }
48 |
49 | /**
50 | * Matcher for validating CSS content against W3C validation servers.
51 | * @return Matcher for validating CSS content.
52 | */
53 | public static Matcher validCss() {
54 | return W3CMatchers.CSS;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/jcabi/matchers/XPathMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3 | * SPDX-License-Identifier: MIT
4 | */
5 | package com.jcabi.matchers;
6 |
7 | import com.jcabi.xml.XMLDocument;
8 | import javax.xml.namespace.NamespaceContext;
9 | import lombok.EqualsAndHashCode;
10 | import lombok.ToString;
11 | import org.hamcrest.Description;
12 | import org.hamcrest.TypeSafeMatcher;
13 |
14 | /**
15 | * Matcher of XPath against a plain string.
16 | *
17 | *
Objects of this class are immutable and thread-safe.
18 | *
19 | * @param Type of param
20 | * @since 0.3.7
21 | */
22 | @ToString
23 | @EqualsAndHashCode(callSuper = false, of = "xpath")
24 | public final class XPathMatcher extends TypeSafeMatcher {
25 |
26 | /**
27 | * The XPath to use.
28 | */
29 | private final transient String xpath;
30 |
31 | /**
32 | * The context to use.
33 | */
34 | private final transient NamespaceContext context;
35 |
36 | /**
37 | * Public ctor.
38 | * @param query The query
39 | * @param ctx The context
40 | */
41 | public XPathMatcher(final String query, final NamespaceContext ctx) {
42 | super();
43 | this.xpath = query;
44 | this.context = ctx;
45 | }
46 |
47 | @Override
48 | public boolean matchesSafely(final T input) {
49 | return !new XMLDocument(XhtmlMatchers.xhtml(input))
50 | .merge(this.context)
51 | .nodes(this.xpath)
52 | .isEmpty();
53 | }
54 |
55 | @Override
56 | public void describeTo(final Description description) {
57 | description.appendText("an XML document with XPath ")
58 | .appendText(this.xpath);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/com/jcabi/matchers/W3CValidatorMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3 | * SPDX-License-Identifier: MIT
4 | */
5 | package com.jcabi.matchers;
6 |
7 | import com.jcabi.aspects.Immutable;
8 | import com.jcabi.log.Logger;
9 | import com.jcabi.w3c.Validator;
10 | import java.io.IOException;
11 | import lombok.EqualsAndHashCode;
12 | import lombok.ToString;
13 | import org.hamcrest.Description;
14 | import org.hamcrest.TypeSafeMatcher;
15 |
16 | /**
17 | * Matcher for checking HTML and CSS documents against W3C validation services.
18 | *
19 | *
Objects of this class are immutable and thread-safe.
23 | *
24 | * @since 0.1
25 | */
26 | @EqualsAndHashCode(callSuper = false, of = "xml")
27 | @SuppressWarnings(
28 | {
29 | "PMD.OnlyOneConstructorShouldDoInitialization",
30 | "PMD.ConstructorOnlyInitializesOrCallOtherConstructors"
31 | }
32 | )
33 | final class StringSource extends DOMSource {
34 |
35 | /**
36 | * The XML itself.
37 | */
38 | private final transient String xml;
39 |
40 | /**
41 | * Public ctor.
42 | * @param text The content of the document
43 | */
44 | StringSource(final String text) {
45 | super();
46 | this.xml = text;
47 | super.setNode(new XMLDocument(text).deepCopy());
48 | }
49 |
50 | /**
51 | * Public ctor.
52 | * @param node The node
53 | */
54 | StringSource(final Node node) {
55 | super();
56 | final StringWriter writer = new StringWriter();
57 | try {
58 | final Transformer transformer =
59 | TransformerFactory.newInstance().newTransformer();
60 | final String yes = "yes";
61 | transformer.setOutputProperty(
62 | OutputKeys.OMIT_XML_DECLARATION, yes
63 | );
64 | transformer.setOutputProperty(OutputKeys.INDENT, yes);
65 | transformer.transform(
66 | new DOMSource(node),
67 | new StreamResult(writer)
68 | );
69 | } catch (final TransformerException ex) {
70 | throw new IllegalStateException(ex);
71 | }
72 | this.xml = writer.toString();
73 | this.setNode(node);
74 | }
75 |
76 | @Override
77 | public String toString() {
78 | final StringBuilder buf = new StringBuilder();
79 | final int length = this.xml.length();
80 | for (int pos = 0; pos < length; ++pos) {
81 | final char chr = this.xml.charAt(pos);
82 | // @checkstyle MagicNumber (1 line)
83 | if (chr > 0x7f) {
84 | buf.append("").append(
85 | Integer.toHexString(chr).toUpperCase(Locale.ENGLISH)
86 | ).append(';');
87 | } else {
88 | buf.append(chr);
89 | }
90 | }
91 | return buf.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/site/apt/broken-links.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | Broken Links Matcher
3 | ------
4 | Yegor Bugayenko
5 | ------
6 | 2014-05-05
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | Broken Links Matchers
40 |
41 | {{{./apidocs-${project.version}/com/jcabi/matchers/NoBrokenLinks.html}<<>>}}
42 | is a Hamcrest matchers that checks your XML/HTML document
43 | and catches links that point to incorrect locations, for example:
44 |
45 | +--
46 | import com.jcabi.matchers.NoBrokenLinks;
47 | import org.hamcrest.MatcherAssert;
48 | public class FooTest {
49 | @Test
50 | public void htmlHasNoBrokenLinks() {
51 | MatcherAssert.assertThat(
52 | "hey",
53 | new NoBrokenLinks()
54 | );
55 | }
56 | }
57 | +--
58 |
59 | These dependencies you will need in your <<>>:
60 |
61 | +--
62 |
63 | org.hamcrest
64 | hamcrest-library
65 | 1.3
66 | test
67 |
68 |
69 | org.hamcrest
70 | hamcrest-core
71 | 1.3
72 | test
73 |
74 |
75 | com.jcabi
76 | jcabi-http
77 | 1.0
78 | test
79 |
80 |
81 | com.sun.jersey
82 | jersey-client
83 | 1.18.1
84 | test
85 |
86 | +--
87 |
--------------------------------------------------------------------------------
/src/site/apt/regex-matchers.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | Regular Expression Hamcrest Matchers
3 | ------
4 | Carlos Miranda
5 | ------
6 | 2014-10-07
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | Regular Expression Hamcrest Matchers
40 |
41 | {{{./apidocs-${project.version}/com/jcabi/matchers/RegexMatchers.html}<<>>}}
42 | is a utility class with static methods that create Hamcrest matchers that can
43 | check Strings against regular expressions, as used in unit tests.
44 |
45 | You can check if an entire string matches a certain regular expression in the
46 | following manner:
47 |
48 | +--
49 | import com.jcabi.matchers.RegexMatchers;
50 | import org.hamcrest.MatcherAssert;
51 | public class FooTest {
52 | @Test
53 | public void stringMatchesPattern() {
54 | MatcherAssert.assert(
55 | "abc123",
56 | RegexMatchers.matchesPattern("[a-c]+\\d{3}")
57 | );
58 | }
59 | }
60 | +--
61 |
62 | You may also check if a string contains a substring matching a regular
63 | expression, as shown below:
64 |
65 | +--
66 | import com.jcabi.matchers.RegexMatchers;
67 | import org.hamcrest.MatcherAssert;
68 | public class FooTest {
69 | @Test
70 | public void stringContainsPattern() {
71 | MatcherAssert.assert(
72 | "foobar456",
73 | RegexMatchers.containsPattern("ar45")
74 | );
75 | }
76 | }
77 | +--
78 |
79 | These dependencies you will need in your <<>>:
80 |
81 | +--
82 |
83 | org.hamcrest
84 | hamcrest-library
85 | 1.3
86 | test
87 |
88 |
89 | org.hamcrest
90 | hamcrest-core
91 | 1.3
92 | test
93 |
94 | +--
95 |
--------------------------------------------------------------------------------
/src/site/site.xml:
--------------------------------------------------------------------------------
1 |
2 |
31 |
32 |
33 | com.jcabi
34 | jcabi-maven-skin
35 | 1.7.1
36 |
37 |
38 | jcabi
39 | https://www.jcabi.com/logo-square.svg
40 | https://www.jcabi.com/
41 | 64
42 | 64
43 |
44 | UA-1963507-23
45 |
46 |
47 | <link href="https://www.jcabi.com/logo-square.svg" rel="shortcut icon"/>
48 | <link href="https://plus.google.com/u/0/114792568016408327418?rel=author" rel="author"/>
49 |
50 |
56 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/src/site/apt/xhtml-matchers.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | XHTML Hamcrest Matchers
3 | ------
4 | Yegor Bugayenko
5 | ------
6 | 2014-04-27
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | XHTML Hamcrest Matchers
40 |
41 | {{{./apidocs-${project.version}/com/jcabi/matchers/XhtmlMatchers.html}<<>>}}
42 | is a utility class with static methods that create
43 | XHTML Hamcrest matchers, to be used in unit tests, for example:
44 |
45 | +--
46 | import com.jcabi.matchers.XhtmlMatchers;
47 | import org.hamcrest.MatcherAssert;
48 | public class FooTest {
49 | @Test
50 | public void buildsValidXml() {
51 | MatcherAssert.assertThat(
52 | "Jeff",
53 | XhtmlMatchers.hasXPath("/data/employee[@id=33]/name")
54 | );
55 | }
56 | }
57 | +--
58 |
59 | Besides that, there is a convenient static method that
60 | converts its input to XML, that correctly renders itself
61 | in unit test output:
62 |
63 | +--
64 | import com.jcabi.matchers.XhtmlMatchers;
65 | import org.hamcrest.MatcherAssert;
66 | public class FooTest {
67 | @Test
68 | public void buildsValidXml() {
69 | Source source = // ... get it somewhere
70 | MatcherAssert.assertThat(
71 | XhtmlMatchers.xhtml(source),
72 | XhtmlMatchers.hasXPath("/data/employee[@id=33]/name")
73 | );
74 | }
75 | }
76 | +--
77 |
78 | These dependencies you will need in your <<>>:
79 |
80 | +--
81 |
82 | org.hamcrest
83 | hamcrest-library
84 | 1.3
85 | test
86 |
87 |
88 | org.hamcrest
89 | hamcrest-core
90 | 1.3
91 | test
92 |
93 |
94 | com.jcabi
95 | jcabi-xml
96 | 0.7.8
97 | test
98 |
99 | +--
100 |
--------------------------------------------------------------------------------
/src/site/apt/w3c-matchers.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | W3C Hamcrest Matchers
3 | ------
4 | Yegor Bugayenko
5 | ------
6 | 2014-05-05
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | W3C Hamcrest Matchers
40 |
41 | {{{./apidocs-${project.version}/com/jcabi/matchers/W3CMatchers.html}<<>>}}
42 | is a utility class with static methods that create
43 | W3C Hamcrest matchers, to be used in unit tests, for example:
44 |
45 | +--
46 | import com.jcabi.matchers.W3CMatchers;
47 | import org.hamcrest.MatcherAssert;
48 | public class FooTest {
49 | @Test
50 | public void htmlIsValidAccordingToW3C() {
51 | MatcherAssert.assertThat(
52 | "Hello",
53 | W3CMatchers.validHtml()
54 | );
55 | }
56 | }
57 | +--
58 |
59 | The same for CSS:
60 |
61 | +--
62 | import com.jcabi.matchers.W3CMatchers;
63 | import org.hamcrest.MatcherAssert;
64 | public class FooTest {
65 | @Test
66 | public void htmlIsValidAccordingToW3C() {
67 | MatcherAssert.assertThat(
68 | "body { color: red; }",
69 | W3CMatchers.validCss()
70 | );
71 | }
72 | }
73 | +--
74 |
75 | These dependencies you will need in your <<>>:
76 |
77 | +--
78 |
79 | org.hamcrest
80 | hamcrest-library
81 | 1.3
82 | test
83 |
84 |
85 | org.hamcrest
86 | hamcrest-core
87 | 1.3
88 | test
89 |
90 |
91 | com.jcabi
92 | jcabi-w3c
93 | 1.0
94 | test
95 |
96 |
97 | com.jcabi
98 | jcabi-w3c
99 | 1.0
100 | test
101 |
102 |
103 | org.glassfish
104 | javax.json
105 | 1.0.4
106 | test
107 |
108 | +--
109 |
--------------------------------------------------------------------------------
/src/site/apt/index.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | Hamcrest Matchers
3 | ------
4 | Yegor Bugayenko
5 | ------
6 | 2014-04-27
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | Hamcrest Matchers
40 |
41 | This library contains a few convenient utils for Hamcrest matching, including:
42 |
43 | * {{{./xhtml-matchers.html}<<>>}} -
44 | matches XML and XHTML with XPath;
45 |
46 | * {{{./regex-matchers.html}<<>>}} -
47 | matches Strings with Regular Expressions;
48 |
49 | * {{{./jaxb-converter.html}<<>>}} -
50 | converts JAXB-annotated objects into XML.
51 |
52 | The only dependency you need is
53 | (you can also download
54 | {{{http://repo1.maven.org/maven2/com/jcabi/jcabi-matchers/${project.version}/jcabi-matchers-${project.version}.jar}<<>>}}
55 | and add it to the classpath):
56 |
57 | +--
58 |
59 | com.jcabi
60 | jcabi-matchers
61 | ${project.version}
62 |
63 | +--
64 |
65 | Don't forget to add these two dependencies to your classpath:
66 |
67 | +--
68 |
69 | org.hamcrest
70 | hamcrest-core
71 | 1.3
72 | test
73 |
74 |
75 | org.hamcrest
76 | hamcrest-library
77 | 1.3
78 | test
79 |
80 | +--
81 |
82 | * Cutting Edge Version
83 |
84 | If you want to use current version of the product, you can do it with
85 | this configuration in your <<>>:
86 |
87 | +--
88 |
89 |
90 | oss.sonatype.org
91 | https://oss.sonatype.org/content/repositories/snapshots/
92 |
93 |
94 |
95 |
96 | com.jcabi
97 | jcabi-matchers
98 | 2.0-SNAPSHOT
99 |
100 |
101 | +--
102 |
--------------------------------------------------------------------------------
/src/site/apt/jaxb-converter.apt.vm:
--------------------------------------------------------------------------------
1 | ------
2 | JAXB Converter
3 | ------
4 | Yegor Bugayenko
5 | ------
6 | 2014-04-27
7 | ------
8 |
9 | ~~
10 | ~~ Copyright (c) 2014-2025 Yegor Bugayenko
11 | ~~ All rights reserved.
12 | ~~
13 | ~~ Redistribution and use in source and binary forms, with or without
14 | ~~ modification, are permitted provided that the following conditions
15 | ~~ are met: 1) Redistributions of source code must retain the above
16 | ~~ copyright notice, this list of conditions and the following
17 | ~~ disclaimer. 2) Redistributions in binary form must reproduce the above
18 | ~~ copyright notice, this list of conditions and the following
19 | ~~ disclaimer in the documentation and/or other materials provided
20 | ~~ with the distribution. 3) Neither the name of the jcabi.com nor
21 | ~~ the names of its contributors may be used to endorse or promote
22 | ~~ products derived from this software without specific prior written
23 | ~~ permission.
24 | ~~
25 | ~~ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ~~ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
27 | ~~ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
28 | ~~ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
29 | ~~ THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
30 | ~~ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 | ~~ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32 | ~~ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 | ~~ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
34 | ~~ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 | ~~ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
36 | ~~ OF THE POSSIBILITY OF SUCH DAMAGE.
37 | ~~
38 |
39 | JAXB Converter
40 |
41 | The object has to be annotated with JAXB annotations
42 | in order to be convertible.
43 | Let's consider an example JAXB-annotated class:
44 |
45 | +--
46 | import javax.xml.bind.annotation.XmlAccessType;
47 | import javax.xml.bind.annotation.XmlAccessorType;
48 | import javax.xml.bind.annotation.XmlElement;
49 | import javax.xml.bind.annotation.XmlRootElement;
50 | @XmlRootElement(name = "employee")
51 | @XmlAccessorType(XmlAccessType.NONE)
52 | public class Employee {
53 | @XmlElement(name = "name")
54 | public String getName() {
55 | return "John Doe";
56 | }
57 | }
58 | +--
59 |
60 | Now you want to test how it works with real data after conversion
61 | to XML (in a unit test):
62 |
63 | +--
64 | import com.jcabi.matchers.JaxbConverter;
65 | import com.jcabi.matchers.XhtmlMatchers;
66 | import org.hamcrest.MatcherAssert;
67 | import org.junit.Test;
68 | public class EmployeeTest {
69 | @Test
70 | public void testObjectToXmlConversion() throws Exception {
71 | final Object object = new Employee();
72 | MatcherAssert.assertThat(
73 | JaxbConverter.the(object),
74 | XhtmlMatchers.hasXPath("/employee/name[.='John Doe']")
75 | );
76 | }
77 | }
78 | +--
79 |
80 | These dependencies you will need in your <<>>:
81 |
82 | +--
83 |
84 | org.hamcrest
85 | hamcrest-library
86 | 1.3
87 | test
88 |
89 |
90 | org.hamcrest
91 | hamcrest-core
92 | 1.3
93 | test
94 |
95 |
96 | com.jcabi
97 | jcabi-xml
98 | 0.7.8
99 | test
100 |
101 |
102 | javax.xml.bind
103 | jaxb-api
104 | 2.2.11
105 | provided
106 |
107 | +--
108 |
--------------------------------------------------------------------------------
/src/main/java/com/jcabi/matchers/RegexMatchers.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-FileCopyrightText: Copyright (c) 2011-2025 Yegor Bugayenko
3 | * SPDX-License-Identifier: MIT
4 | */
5 | package com.jcabi.matchers;
6 |
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import lombok.EqualsAndHashCode;
10 | import lombok.ToString;
11 | import org.hamcrest.CoreMatchers;
12 | import org.hamcrest.Matcher;
13 |
14 | /**
15 | * Convenient matchers for checking Strings against regular expressions.
16 | *
17 | * @since 1.3
18 | */
19 | @ToString
20 | @EqualsAndHashCode
21 | @SuppressWarnings("PMD.ProhibitPublicStaticMethods")
22 | public final class RegexMatchers {
23 |
24 | /**
25 | * Private ctor, it's a utility class.
26 | */
27 | private RegexMatchers() {
28 | // Utility class, shouldn't be instantiated.
29 | }
30 |
31 | /**
32 | * Checks whether a String matches at lease one of given regular
33 | * expressions.
34 | * @param patterns Regular expression patterns
35 | * @return Matcher suitable for JUnit/Hamcrest matching
36 | */
37 | @SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
38 | public static Matcher matchesAnyPattern(final String... patterns) {
39 | final Collection> matchers =
40 | new ArrayList<>(patterns.length);
41 | for (final String pattern : patterns) {
42 | matchers.add(new RegexMatchingPatternMatcher(pattern));
43 | }
44 | return CoreMatchers.anyOf(matchers);
45 | }
46 |
47 | /**
48 | * Checks whether a String matches the given regular expression. Works in a
49 | * similar manner to {@link String#matches(String)}. For example:
50 | *
51 | *
55 | *
56 | * @param pattern The pattern to match against
57 | * @return Matcher suitable for JUnit/Hamcrest matching
58 | */
59 | public static Matcher matchesPattern(final String pattern) {
60 | return new RegexMatchingPatternMatcher(pattern);
61 | }
62 |
63 | /**
64 | * Checks whether a String contains a subsequence matching the given regular
65 | * expression. Works in a similar manner to
66 | * {@link java.util.regex.Matcher#find()}. For example:
67 | *
68 | *
56 | *
57 | * @since 0.1
58 | */
59 | @ToString
60 | @EqualsAndHashCode
61 | @SuppressWarnings("PMD.ProhibitPublicStaticMethods")
62 | public final class JaxbConverter {
63 |
64 | /**
65 | * Private ctor, to avoid direct instantiation of the class.
66 | */
67 | private JaxbConverter() {
68 | // intentionally empty
69 | }
70 |
71 | /**
72 | * Convert an object to XML.
73 | *
74 | *
The method will throw {@link AssertionError} if marshalling of
75 | * provided object fails for some reason.
76 | *
77 | *
The name of the method is motivated by
78 | * xmlatchers project
79 | * and their {@code XmlMatchers.the(String)} method. Looks like this name
80 | * is short enough and convenient for unit tests.
81 | *
82 | * @param object The object to convert
83 | * @param deps Dependencies that we should take into account
84 | * @return DOM source/document
85 | * @throws JAXBException If an exception occurs inside
86 | */
87 | public static Source the(final Object object, final Class>... deps)
88 | throws JAXBException {
89 | final Class>[] classes = new Class>[deps.length + 1];
90 | classes[0] = object.getClass();
91 | System.arraycopy(deps, 0, classes, 1, deps.length);
92 | final JAXBContext ctx;
93 | try {
94 | ctx = JAXBContext.newInstance(classes);
95 | } catch (final JAXBException ex) {
96 | throw new IllegalArgumentException(ex);
97 | }
98 | final JAXBIntrospector intro = ctx.createJAXBIntrospector();
99 | Object subject = object;
100 | if (intro.getElementName(object) == null) {
101 | @SuppressWarnings("unchecked")
102 | final Class