StandardComment.java

1
package pro.verron.officestamper.core;
2
3
import org.docx4j.TextUtils;
4
import org.docx4j.wml.*;
5
import org.docx4j.wml.R.CommentReference;
6
import org.jspecify.annotations.Nullable;
7
import pro.verron.officestamper.api.Comment;
8
import pro.verron.officestamper.api.DocxPart;
9
import pro.verron.officestamper.api.Paragraph;
10
11
import java.math.BigInteger;
12
import java.util.ArrayList;
13
import java.util.List;
14
15
import static java.util.stream.Collectors.joining;
16
import static pro.verron.officestamper.utils.wml.WmlFactory.*;
17
18
/// Standard implementation of the [Comment] interface. Represents a comment in a DOCX document with its associated
19
/// range markers and content.
20
///
21
/// @author Joseph Verron
22
/// @author Tom Hombergs
23
/// @since 1.0.2
24
public class StandardComment
25
        implements Comment {
26
    private final DocxPart part;
27
    private final Comments.Comment comment;
28
    private final CommentRangeStart commentRangeStart;
29
    private final CommentRangeEnd commentRangeEnd;
30
    private final @Nullable CommentReference commentReference;
31
    private final CTSmartTagRun startTagRun;
32
33
    /// Constructs a new [StandardComment] object.
34
    ///
35
    /// @param part              the [DocxPart] representing the document section this comment belongs to.
36
    /// @param startTagRun       the start tag run.
37
    /// @param commentRangeStart the comment range start.
38
    /// @param commentRangeEnd   the comment range end.
39
    /// @param comment           the comment.
40
    /// @param commentReference the comment reference.
41
    public StandardComment(
42
            DocxPart part,
43
            CTSmartTagRun startTagRun,
44
            CommentRangeStart commentRangeStart,
45
            CommentRangeEnd commentRangeEnd,
46
            Comments.Comment comment,
47
            @Nullable CommentReference commentReference
48
    ) {
49
        this.part = part;
50
        this.startTagRun = startTagRun;
51
        this.commentRangeStart = commentRangeStart;
52
        this.commentRangeEnd = commentRangeEnd;
53
        this.comment = comment;
54
        this.commentReference = commentReference;
55
    }
56
57
    /// Creates a new instance of [StandardComment] and initializes it with the given parameters, including a comment,
58
    /// comment range start, comment range end, and a comment reference.
59
    ///
60
    /// @param document the [DocxPart] representing the document to which this comment belongs
61
    /// @param parent the [ContentAccessor] representing the parent content of the comment range
62
    /// @param expression the [String] content to be included in the comment
63
    /// @param id the unique [BigInteger] identifier for the comment
64
    /// @return a [StandardComment] instance initialized with the specified parameters
65
    public static StandardComment create(DocxPart document, ContentAccessor parent, String expression, BigInteger id) {
66
        var start = newCommentRangeStart(id, parent);
67 1 1. create : replaced return value with null for pro/verron/officestamper/core/StandardComment::create → SURVIVED
        return new StandardComment(document,
68
                newSmartTag("officestamper", newCtAttr("type", "processor"), start),
69
                start,
70
                newCommentRangeEnd(id, parent),
71
                newComment(id, expression),
72
                newCommentReference(id, parent));
73
    }
74
75
    /// Generates a string representation of the [StandardComment] object, including its ID, content, and the amount
76
    /// children comment.
77
    ///
78
    /// @return a formatted string describing the [StandardComment]'s properties, including its ID, content, and the
79
    ///         size of its children.
80
    @Override
81
    public String toString() {
82 1 1. toString : replaced return value with "" for pro/verron/officestamper/core/StandardComment::toString → NO_COVERAGE
        return "StandardComment{comment={id=%s, content=%s}}}".formatted(comment.getId(),
83
                comment.getContent()
84
                       .stream()
85
                       .map(TextUtils::getText)
86
                       .collect(joining(",")));
87
    }
88
89
    @Override
90
    public Paragraph getParagraph() {
91
        var parent = commentRangeStart.getParent();
92 1 1. getParagraph : replaced return value with null for pro/verron/officestamper/core/StandardComment::getParagraph → NO_COVERAGE
        return StandardParagraph.from(part, parent);
93
    }
94
95
    @Override
96
    public CTSmartTagRun getStartTagRun() {
97 1 1. getStartTagRun : replaced return value with null for pro/verron/officestamper/core/StandardComment::getStartTagRun → KILLED
        return startTagRun;
98
    }
99
100
    @Override
101
    public CommentRangeStart getCommentRangeStart() {
102 1 1. getCommentRangeStart : replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentRangeStart → KILLED
        return commentRangeStart;
103
    }
104
105
    @Override
106
    public ContentAccessor getParent() {
107 1 1. getParent : replaced return value with null for pro/verron/officestamper/core/StandardComment::getParent → KILLED
        return DocumentUtil.findSmallestCommonParent(commentRangeStart, commentRangeEnd);
108
    }
109
110
    @Override
111
    public List<Object> getElements() {
112
        List<Object> elements = new ArrayList<>();
113
        boolean startFound = false;
114
        boolean endFound = false;
115
        var siblings = getParent().getContent();
116
        for (Object element : siblings) {
117 2 1. getElements : negated conditional → KILLED
2. getElements : negated conditional → KILLED
            startFound = startFound || DocumentUtil.depthElementSearch(commentRangeStart, element);
118 2 1. getElements : negated conditional → KILLED
2. getElements : negated conditional → KILLED
            if (startFound && !endFound) elements.add(element);
119 2 1. getElements : negated conditional → KILLED
2. getElements : negated conditional → KILLED
            endFound = endFound || DocumentUtil.depthElementSearch(commentRangeEnd, element);
120
        }
121 1 1. getElements : replaced return value with Collections.emptyList for pro/verron/officestamper/core/StandardComment::getElements → KILLED
        return elements;
122
    }
123
124
    @Override
125
    public CommentRangeEnd getCommentRangeEnd() {
126 1 1. getCommentRangeEnd : replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentRangeEnd → KILLED
        return commentRangeEnd;
127
    }
128
129
    @Override
130
    public @Nullable CommentReference getCommentReference() {
131 1 1. getCommentReference : replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentReference → NO_COVERAGE
        return commentReference;
132
    }
133
134
    @Override
135
    public Comments.Comment getComment() {
136 1 1. getComment : replaced return value with null for pro/verron/officestamper/core/StandardComment::getComment → KILLED
        return comment;
137
    }
138
139
    @Override
140
    public String expression() {
141 1 1. expression : replaced return value with "" for pro/verron/officestamper/core/StandardComment::expression → KILLED
        return this.getComment()
142
                   .getContent()
143
                   .stream()
144
                   .filter(P.class::isInstance)
145
                   .map(P.class::cast)
146 1 1. lambda$expression$0 : replaced return value with null for pro/verron/officestamper/core/StandardComment::lambda$expression$0 → KILLED
                   .map(p -> StandardParagraph.from(new TextualDocxPart(part.document()), p))
147
                   .map(StandardParagraph::asString)
148
                   .collect(joining());
149
    }
150
151
    @Override
152
    public BigInteger getId() {
153 1 1. getId : replaced return value with null for pro/verron/officestamper/core/StandardComment::getId → KILLED
        return comment.getId();
154
    }
155
}

Mutations

67

1.1
Location : create
Killed by : none
replaced return value with null for pro/verron/officestamper/core/StandardComment::create → SURVIVED
Covering tests

82

1.1
Location : toString
Killed by : none
replaced return value with "" for pro/verron/officestamper/core/StandardComment::toString → NO_COVERAGE

92

1.1
Location : getParagraph
Killed by : none
replaced return value with null for pro/verron/officestamper/core/StandardComment::getParagraph → NO_COVERAGE

97

1.1
Location : getStartTagRun
Killed by : pro.verron.officestamper.test.ProcessorReplaceWithTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.ProcessorReplaceWithTest]/[method:notWorking1()]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getStartTagRun → KILLED

102

1.1
Location : getCommentRangeStart
Killed by : pro.verron.officestamper.test.ProcessorDisplayIfTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.ProcessorDisplayIfTest]/[test-template:conditionalDisplayOfEndnotes(pro.verron.officestamper.test.utils.ContextFactory)]/[test-template-invocation:#1]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentRangeStart → KILLED

107

1.1
Location : getParent
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getParent → KILLED

117

1.1
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

2.2
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

118

1.1
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

2.2
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

119

1.1
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

2.2
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

121

1.1
Location : getElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
replaced return value with Collections.emptyList for pro/verron/officestamper/core/StandardComment::getElements → KILLED

126

1.1
Location : getCommentRangeEnd
Killed by : pro.verron.officestamper.test.ProcessorReplaceWithTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.ProcessorReplaceWithTest]/[method:notWorking1()]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentRangeEnd → KILLED

131

1.1
Location : getCommentReference
Killed by : none
replaced return value with null for pro/verron/officestamper/core/StandardComment::getCommentReference → NO_COVERAGE

136

1.1
Location : getComment
Killed by : pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest]/[test-template:fails(pro.verron.officestamper.test.utils.ContextFactory)]/[test-template-invocation:#2]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getComment → KILLED

141

1.1
Location : expression
Killed by : pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest]/[test-template:fails(pro.verron.officestamper.test.utils.ContextFactory)]/[test-template-invocation:#2]
replaced return value with "" for pro/verron/officestamper/core/StandardComment::expression → KILLED

146

1.1
Location : lambda$expression$0
Killed by : pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.FailOnUnresolvedPlaceholderTest]/[test-template:fails(pro.verron.officestamper.test.utils.ContextFactory)]/[test-template-invocation:#2]
replaced return value with null for pro/verron/officestamper/core/StandardComment::lambda$expression$0 → KILLED

153

1.1
Location : getId
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#3]
replaced return value with null for pro/verron/officestamper/core/StandardComment::getId → KILLED

Active mutators

Tests examined


Report generated by PIT 1.25.5 support