diff --git a/pom.xml b/pom.xml index fcb11a7e..b6624c75 100644 --- a/pom.xml +++ b/pom.xml @@ -130,7 +130,7 @@ OF THE POSSIBILITY OF SUCH DAMAGE. com.jcabi jcabi-matchers - 1.7.0 + 1.8.0 test @@ -194,6 +194,18 @@ OF THE POSSIBILITY OF SUCH DAMAGE. 3.0 test + + org.yaml + snakeyaml + 2.3 + test + + + org.eolang + jucs + 0.2.0 + test + org.cactoos cactoos diff --git a/src/main/java/org/xembly/Directives.java b/src/main/java/org/xembly/Directives.java index 5f2c7160..abb90fe6 100644 --- a/src/main/java/org/xembly/Directives.java +++ b/src/main/java/org/xembly/Directives.java @@ -75,16 +75,13 @@ * @since 0.1 * @checkstyle ClassFanOutComplexity (500 lines) */ -@EqualsAndHashCode(callSuper = false, of = "all") -@SuppressWarnings - ( - { - "PMD.TooManyMethods", - "PMD.CyclomaticComplexity", - "PMD.GodClass", - "PMD.StdCyclomaticComplexity" - } - ) +@EqualsAndHashCode(of = "all") +@SuppressWarnings({ + "PMD.TooManyMethods", + "PMD.CyclomaticComplexity", + "PMD.GodClass", + "PMD.StdCyclomaticComplexity" +}) public final class Directives implements Iterable { /** diff --git a/src/test/java/org/xembly/XemblerTest.java b/src/test/java/org/xembly/XemblerTest.java index 991b3652..02c4390a 100644 --- a/src/test/java/org/xembly/XemblerTest.java +++ b/src/test/java/org/xembly/XemblerTest.java @@ -29,20 +29,33 @@ */ package org.xembly; +import com.jcabi.matchers.XPathMatcher; import com.jcabi.matchers.XhtmlMatchers; +import com.jcabi.xml.XML; import com.jcabi.xml.XMLDocument; +import com.jcabi.xml.XPathContext; +import java.util.Collection; +import java.util.Map; import javax.xml.parsers.DocumentBuilderFactory; import net.jqwik.api.ForAll; import net.jqwik.api.Property; import org.apache.commons.lang3.StringUtils; import org.cactoos.experimental.Threads; +import org.cactoos.iterable.Mapped; +import org.cactoos.list.ListOf; import org.cactoos.scalar.LengthOf; import org.cactoos.scalar.Repeated; +import org.eolang.jucs.ClasspathSource; +import org.hamcrest.BaseMatcher; +import org.hamcrest.Description; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; +import org.hamcrest.core.AllOf; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; import org.w3c.dom.Document; import org.w3c.dom.Node; +import org.yaml.snakeyaml.Yaml; /** * Test case for {@link Xembler}. @@ -261,4 +274,49 @@ void printsNamespaces() { Matchers.containsString("x:color=\"green\"") ); } + + @ParameterizedTest + @ClasspathSource(value = "org/xembly/stories/", glob = "**.yml") + void checksYamlStories(final String story) { + MatcherAssert.assertThat( + "modifies XML document with a few directives", + story, + new XemblerTest.StoryMatcher() + ); + } + + /** + * Matcher for stories. + * + * @since 0.33.0 + */ + private static final class StoryMatcher extends BaseMatcher { + @Override + @SuppressWarnings("unchecked") + public boolean matches(final Object item) { + final Map yaml = new Yaml().load( + String.class.cast(item.toString()) + ); + final Directives directives = new Directives(); + for (final String dir : (Iterable) yaml.get("directives")) { + directives.append(new Directives(dir)); + } + final XML xml = new XMLDocument(yaml.get("before").toString()); + new Xembler(directives).applyQuietly(xml.inner()); + return new AllOf<>( + new ListOf<>( + new Mapped<>( + str -> new XPathMatcher<>(str, new XPathContext()), + (Collection) yaml.get("xpaths") + ) + ) + ).matches(XhtmlMatchers.xhtml(xml.inner())); + } + + @Override + public void describeTo(final Description description) { + description.appendText("matches"); + } + } + } diff --git a/src/test/resources/org/xembly/stories/simple.yml b/src/test/resources/org/xembly/stories/simple.yml new file mode 100644 index 00000000..a2cda8f0 --- /dev/null +++ b/src/test/resources/org/xembly/stories/simple.yml @@ -0,0 +1,37 @@ +# Copyright (c) 2013-2025, Yegor Bugayenko +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: 1) Redistributions of source code must retain the above +# copyright notice, this list of conditions and the following +# disclaimer. 2) Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. 3) Neither the name of the xembly.org nor +# the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT +# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +--- +before: | + +directives: + - XPATH "/root"; + - ADD "hello"; + - ATTR "foo", "bar"; +xpaths: + - /root/hello + - /root/hello[@foo='bar']