AsciiDocModel.java

1
package pro.verron.officestamper.asciidoc;
2
3
import java.util.ArrayList;
4
import java.util.List;
5
import java.util.Objects;
6
7
/// Represents a minimal in-memory model of an AsciiDoc document.
8
///
9
/// This model intentionally supports a compact subset sufficient for rendering to WordprocessingML and JavaFX Scene: -
10
/// Headings (levels 1..6) using leading '=' markers - Paragraphs separated by blank lines - Inline emphasis for bold
11
/// and italic using AsciiDoc-like markers: *bold*, _italic_
12
public final class AsciiDocModel {
13
    private final List<Block> blocks;
14
15
    private AsciiDocModel(List<Block> blocks) {
16
        this.blocks = List.copyOf(blocks);
17
    }
18
19
    /// Creates a new {@link AsciiDocModel} from the provided blocks.
20
    ///
21
    /// @param blocks ordered content blocks
22
    ///
23
    /// @return immutable AsciiDocModel
24
    public static AsciiDocModel of(List<Block> blocks) {
25
        Objects.requireNonNull(blocks, "blocks");
26 1 1. of : replaced return value with null for pro/verron/officestamper/asciidoc/AsciiDocModel::of → KILLED
        return new AsciiDocModel(new ArrayList<>(blocks));
27
    }
28
29
    /// Returns the ordered list of blocks comprising the document.
30
    ///
31
    /// @return immutable list of blocks
32
    public List<Block> getBlocks() {
33 1 1. getBlocks : replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/AsciiDocModel::getBlocks → KILLED
        return blocks;
34
    }
35
36
    /// Marker interface for document blocks.
37
    public sealed interface Block
38
            permits Heading, Paragraph, Table {}
39
40
    /// Inline fragment inside a paragraph/heading.
41
    public sealed interface Inline
42
            permits Text, Bold, Italic, Tab {
43
        /// Returns the text of the inline fragment.
44
        ///
45
        /// @return text
46
        String text();
47
    }
48
49
    /// Heading block (levels 1..6).
50
    ///
51
    /// @param level heading level
52
    /// @param inlines inline fragments
53
    public record Heading(int level, List<Inline> inlines)
54
            implements Block {
55
        /// Constructor.
56
        ///
57
        /// @param level heading level
58
        /// @param inlines inline fragments
59
        public Heading(int level, List<Inline> inlines) {
60
            if (level < 1 || level > 6) {
61
                throw new IllegalArgumentException("Heading level must be between 1 and 6");
62
            }
63
            this.level = level;
64
            this.inlines = List.copyOf(inlines);
65
        }
66
    }
67
68
    /// Paragraph block.
69
    ///
70
    /// @param inlines inline fragments
71
    public record Paragraph(List<Inline> inlines)
72
            implements Block {
73
        /// Constructor.
74
        ///
75
        /// @param inlines inline fragments
76
        public Paragraph(List<Inline> inlines) {
77
            this.inlines = List.copyOf(inlines);
78
        }
79
    }
80
81
    /// Text fragment.
82
    ///
83
    /// @param text text
84
    public record Text(String text)
85
            implements Inline {
86
    }
87
88
    /// Bold inline that can contain nested inlines.
89
    ///
90
    /// @param children nested inline fragments
91
    public record Bold(List<Inline> children)
92
            implements Inline {
93
        /// Constructor.
94
        ///
95
        /// @param children nested inline fragments
96
        public Bold(List<Inline> children) {
97
            this.children = List.copyOf(children);
98
        }
99
100
        @Override
101
        public String text() {
102
            StringBuilder sb = new StringBuilder();
103
            for (Inline in : children) sb.append(in.text());
104 1 1. text : replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Bold::text → NO_COVERAGE
            return sb.toString();
105
        }
106
    }
107
108
    /// Italic inline that can contain nested inlines.
109
    ///
110
    /// @param children nested inline fragments
111
    public record Italic(List<Inline> children)
112
            implements Inline {
113
        /// Constructor.
114
        ///
115
        /// @param children nested inline fragments
116
        public Italic(List<Inline> children) {
117
            this.children = List.copyOf(children);
118
        }
119
120
        @Override
121
        public String text() {
122
            StringBuilder sb = new StringBuilder();
123
            for (Inline in : children) sb.append(in.text());
124 1 1. text : replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Italic::text → NO_COVERAGE
            return sb.toString();
125
        }
126
    }
127
128
    /// Inline tab marker to be rendered as a DOCX tab stop.
129
    public record Tab()
130
            implements Inline {
131
        @Override
132
        public String text() {
133 1 1. text : replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Tab::text → NO_COVERAGE
            return "\t";
134
        }
135
    }
136
137
    /// Simple table block: list of rows; each row is a list of cells; each cell contains inline content.
138
    ///
139
    /// @param rows table rows
140
    public record Table(List<Row> rows)
141
            implements Block {
142
        /// Constructor.
143
        ///
144
        /// @param rows table rows
145
        public Table(List<Row> rows) {
146
            this.rows = List.copyOf(rows);
147
        }
148
    }
149
150
    /// Table row.
151
    ///
152
    /// @param cells table cells
153
    public record Row(List<Cell> cells) {
154
        /// Constructor.
155
        ///
156
        /// @param cells table cells
157
        public Row(List<Cell> cells) {
158
            this.cells = List.copyOf(cells);
159
        }
160
    }
161
162
    /// Table cell.
163
    ///
164
    /// @param inlines inline fragments
165
    public record Cell(List<Inline> inlines) {
166
        /// Constructor.
167
        ///
168
        /// @param inlines inline fragments
169
        public Cell(List<Inline> inlines) {
170
            this.inlines = List.copyOf(inlines);
171
        }
172
    }
173
}

Mutations

26

1.1
Location : of
Killed by : pro.verron.officestamper.asciidoc.test.AsciiDocParserTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.asciidoc.test.AsciiDocParserTest]/[test-template:parse_shouldReturnEmptyModel_whenInputIsNull(java.lang.String)]/[test-template-invocation:#3]
replaced return value with null for pro/verron/officestamper/asciidoc/AsciiDocModel::of → KILLED

33

1.1
Location : getBlocks
Killed by : pro.verron.officestamper.asciidoc.test.AsciiDocParserTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.asciidoc.test.AsciiDocParserTest]/[method:parse_shouldParseMultipleHeadings()]
replaced return value with Collections.emptyList for pro/verron/officestamper/asciidoc/AsciiDocModel::getBlocks → KILLED

104

1.1
Location : text
Killed by : none
replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Bold::text → NO_COVERAGE

124

1.1
Location : text
Killed by : none
replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Italic::text → NO_COVERAGE

133

1.1
Location : text
Killed by : none
replaced return value with "" for pro/verron/officestamper/asciidoc/AsciiDocModel$Tab::text → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.22.0