• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

evolvedbinary / elemental / 982

29 Apr 2025 08:34PM UTC coverage: 56.409% (+0.007%) from 56.402%
982

push

circleci

adamretter
[feature] Improve README.md badges

28451 of 55847 branches covered (50.94%)

Branch coverage included in aggregate %.

77468 of 131924 relevant lines covered (58.72%)

0.59 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

66.67
/exist-core/src/main/java/org/exist/test/DiffMatcher.java
1
/*
2
 * Elemental
3
 * Copyright (C) 2024, Evolved Binary Ltd
4
 *
5
 * admin@evolvedbinary.com
6
 * https://www.evolvedbinary.com | https://www.elemental.xyz
7
 *
8
 * Use of this software is governed by the Business Source License 1.1
9
 * included in the LICENSE file and at www.mariadb.com/bsl11.
10
 *
11
 * Change Date: 2028-04-27
12
 *
13
 * On the date above, in accordance with the Business Source License, use
14
 * of this software will be governed by the Apache License, Version 2.0.
15
 *
16
 * Additional Use Grant: Production use of the Licensed Work for a permitted
17
 * purpose. A Permitted Purpose is any purpose other than a Competing Use.
18
 * A Competing Use means making the Software available to others in a commercial
19
 * product or service that: substitutes for the Software; substitutes for any
20
 * other product or service we offer using the Software that exists as of the
21
 * date we make the Software available; or offers the same or substantially
22
 * similar functionality as the Software.
23
 */
24
package org.exist.test;
25

26
import org.exist.xquery.value.Item;
27
import org.exist.xquery.value.NodeValue;
28
import org.exist.xquery.value.Sequence;
29
import org.hamcrest.Description;
30
import org.hamcrest.DiagnosingMatcher;
31
import org.w3c.dom.Node;
32
import org.xmlunit.builder.DiffBuilder;
33
import org.xmlunit.builder.Input;
34
import org.xmlunit.diff.Diff;
35
import org.xmlunit.util.Convert;
36

37
import javax.xml.transform.Source;
38

39
/**
40
 * Implementation of a Hamcrest Matcher
41
 * which will compare XML nodes.
42
 *
43
 * @author <a href="mailto:adam@evolvedbinary.com">Adam Retter</a>
44
 */
45
public class DiffMatcher extends DiagnosingMatcher<Sequence> {
46
    private final Source expectedSource;
47
    private final boolean identical;
48

49
    private DiffMatcher(final Source expectedSource) {
50
        this(expectedSource, false);
1✔
51
    }
1✔
52

53
    private DiffMatcher(final Source expectedSource, final boolean identical) {
1✔
54
        this.expectedSource = expectedSource;
1✔
55
        this.identical = identical;
1✔
56
    }
1✔
57

58
    /**
59
     * Compares that the XML sources are similar.
60
     *
61
     * In this context "similar" is defined by {@link DiffBuilder#checkForSimilar()}.
62
     *
63
     * @param expectedSource the expected XML
64
     *
65
     * @return The Hamcrest Matcher
66
     */
67
    public static DiffMatcher hasSimilarXml(final Source expectedSource) {
68
        return new DiffMatcher(expectedSource);
1✔
69
    }
70

71
    /**
72
     * Compares that the XML sources are identical.
73
     *
74
     * In this context "similar" is defined by {@link DiffBuilder#checkForIdentical()} ()}.
75
     *
76
     * @param expectedSource the expected XML
77
     *
78
     * @return The Hamcrest Matcher
79
     */
80
    public static DiffMatcher hasIdenticalXml(final Source expectedSource) {
81
        return new DiffMatcher(expectedSource, true);
1✔
82
    }
83

84
    @Override
85
    public boolean matches(final Object item, final Description mismatch) {
86
        if (item == null) {
1!
87
            mismatch.appendText("null");
×
88
            return false;
×
89
        }
90

91
        final Item actualItem;
92
        if (item instanceof NodeValue) {
1✔
93
            actualItem = (NodeValue) item;
1✔
94

95
        } else if (item instanceof Sequence actual) {
1!
96

97
            if (actual.getItemCount() != 1) {
1!
98
                mismatch.appendText("Sequence does not contain 1 item");
×
99
                return false;
×
100
            }
101

102
            actualItem = actual.itemAt(0);
1✔
103
            if (!(actualItem instanceof NodeValue)) {
1!
104
                mismatch.appendText("Sequence does not contain a Node");
×
105
                return false;
×
106
            }
107
        } else {
108
            mismatch.appendText("is not a Node");
×
109
            return false;
×
110
        }
111

112
        final Source actualSource = Input.fromNode((org.w3c.dom.Node) actualItem).build();
1✔
113

114
        DiffBuilder diffBuilder = DiffBuilder.compare(expectedSource)
1✔
115
                .withTest(actualSource);
1✔
116
        if (identical) {
1✔
117
            diffBuilder = diffBuilder.checkForIdentical();
1✔
118
        } else {
1✔
119
            diffBuilder = diffBuilder.checkForSimilar();
1✔
120
        }
121

122
        final Diff diff = diffBuilder.build();
1✔
123
        if (diff.hasDifferences()) {
1!
124
            mismatch.appendText("differences: " + diff.toString());
×
125
            return false;
×
126
        }
127

128
        return true;
1✔
129
    }
130

131
    @Override
132
    public void describeTo(final Description description) {
133
        description
×
134
                .appendText("nodes match ")
×
135
                .appendValue(expectedSource);
×
136
    }
×
137

138
    /**
139
     * Creates an Document Source form an XML String.
140
     *
141
     * @param str a string representation of XML.
142
     *
143
     * @return a Document Source.
144
     */
145
    public static Source docSource(final String str) {
146
        return Input.fromString(str).build();
1✔
147
    }
148

149
    /**
150
     * Creates an Element Source form an XML String.
151
     *
152
     * @param str a string representation of XML.
153
     *
154
     * @return an Element Source.
155
     */
156
    public static Source elemSource(final String str) {
157
        final Node documentNode = Convert.toNode(docSource(str));
1✔
158
        final Node firstElement = documentNode.getFirstChild();
1✔
159
        return Input.fromNode(firstElement).build();
1✔
160
    }
161
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc