2 * Sone - SoneTextParserTest.java - Copyright © 2011–2016 David Roden
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 package net.pterodactylus.sone.text;
20 import static org.hamcrest.MatcherAssert.assertThat;
21 import static org.hamcrest.Matchers.is;
22 import static org.hamcrest.Matchers.isIn;
23 import static org.hamcrest.Matchers.notNullValue;
25 import java.io.IOException;
26 import java.util.Collection;
28 import net.pterodactylus.sone.data.Sone;
29 import net.pterodactylus.sone.data.impl.IdOnlySone;
30 import net.pterodactylus.sone.database.SoneProvider;
32 import com.google.common.base.Function;
33 import com.google.common.base.Optional;
34 import org.junit.Test;
37 * JUnit test case for {@link SoneTextParser}.
39 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
41 public class SoneTextParserTest {
43 private final SoneTextParser soneTextParser = new SoneTextParser(null, null);
45 @SuppressWarnings("static-method")
47 public void testPlainText() throws IOException {
48 /* check basic operation. */
49 Iterable<Part> parts = soneTextParser.parse("Test.", null);
50 assertThat("Parts", parts, notNullValue());
51 assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test."));
53 /* check empty lines at start and end. */
54 parts = soneTextParser.parse("\nTest.\n\n", null);
55 assertThat("Parts", parts, notNullValue());
56 assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test."));
58 /* check duplicate empty lines in the text. */
59 parts = soneTextParser.parse("\nTest.\n\n\nTest.", null);
60 assertThat("Parts", parts, notNullValue());
61 assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Test.\n\nTest."));
64 @SuppressWarnings("static-method")
66 public void testKSKLinks() throws IOException {
67 /* check basic links. */
68 Iterable<Part> parts = soneTextParser.parse("KSK@gpl.txt", null);
69 assertThat("Parts", parts, notNullValue());
70 assertThat("Part Text", convertText(parts, FreenetLinkPart.class), is("[KSK@gpl.txt|gpl.txt|gpl.txt]"));
72 /* check embedded links. */
73 parts = soneTextParser.parse("Link is KSK@gpl.txt\u200b.", null);
74 assertThat("Parts", parts, notNullValue());
75 assertThat("Part Text", convertText(parts, PlainTextPart.class, FreenetLinkPart.class), is("Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\u200b."));
77 /* check embedded links and line breaks. */
78 parts = soneTextParser.parse("Link is KSK@gpl.txt\nKSK@test.dat\n", null);
79 assertThat("Parts", parts, notNullValue());
80 assertThat("Part Text", convertText(parts, PlainTextPart.class, FreenetLinkPart.class), is("Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\n[KSK@test.dat|test.dat|test.dat]"));
83 @SuppressWarnings({ "synthetic-access", "static-method" })
85 public void testEmptyLinesAndSoneLinks() throws IOException {
86 SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null);
88 /* check basic links. */
89 Iterable<Part> parts = soneTextParser.parse("Some text.\n\nLink to sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU and stuff.", null);
90 assertThat("Parts", parts, notNullValue());
91 assertThat("Part Text", convertText(parts, PlainTextPart.class, SonePart.class), is("Some text.\n\nLink to [Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU] and stuff."));
94 @SuppressWarnings({ "synthetic-access", "static-method" })
96 public void testEmpyHttpLinks() throws IOException {
97 SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null);
99 /* check empty http links. */
100 Iterable<Part> parts = soneTextParser.parse("Some text. Empty link: http:// – nice!", null);
101 assertThat("Parts", parts, notNullValue());
102 assertThat("Part Text", convertText(parts, PlainTextPart.class), is("Some text. Empty link: http:// – nice!"));
106 public void httpLinkWithoutParensEndsAtNextClosingParen() {
107 Iterable<Part> parts = soneTextParser.parse("Some text (and a link: http://example.sone/abc) – nice!", null);
108 assertThat("Parts", parts, notNullValue());
109 assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text (and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]) – nice!"));
113 public void httpLinkWithOpenedAndClosedParensEndsAtNextClosingParen() {
114 Iterable<Part> parts = soneTextParser.parse("Some text (and a link: http://example.sone/abc_(def)) – nice!", null);
115 assertThat("Parts", parts, notNullValue());
116 assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text (and a link: [http://example.sone/abc_(def)|example.sone/abc_(def)|example.sone/abc_(def)]) – nice!"));
120 public void punctuationIsIgnoredAtEndOfLinkBeforeWhitespace() {
121 SoneTextParser soneTextParser = new SoneTextParser(null, null);
122 Iterable<Part> parts = soneTextParser.parse("Some text and a link: http://example.sone/abc. Nice!", null);
123 assertThat("Parts", parts, notNullValue());
124 assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]. Nice!"));
128 public void multiplePunctuationCharactersAreIgnoredAtEndOfLinkBeforeWhitespace() {
129 Iterable<Part> parts = soneTextParser.parse("Some text and a link: http://example.sone/abc... Nice!", null);
130 assertThat("Parts", parts, notNullValue());
131 assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc]... Nice!"));
135 public void commasAreIgnoredAtEndOfLinkBeforeWhitespace() {
136 SoneTextParser soneTextParser = new SoneTextParser(null, null);
137 Iterable<Part> parts = soneTextParser.parse("Some text and a link: http://example.sone/abc, nice!", null);
138 assertThat("Parts", parts, notNullValue());
139 assertThat("Part Text", convertText(parts, PlainTextPart.class, LinkPart.class), is("Some text and a link: [http://example.sone/abc|example.sone/abc|example.sone/abc], nice!"));
143 * Converts all given {@link Part}s into a string, validating that the
144 * part’s classes match only the expected classes.
147 * The parts to convert to text
148 * @param validClasses
149 * The valid classes; if no classes are given, all classes are
151 * @return The converted text
153 private static String convertText(Iterable<Part> parts, Class<?>... validClasses) {
154 StringBuilder text = new StringBuilder();
155 for (Part part : parts) {
156 assertThat("Part", part, notNullValue());
157 if (validClasses.length != 0) {
158 assertThat("Part’s class", part.getClass(), isIn(validClasses));
160 if (part instanceof PlainTextPart) {
161 text.append(((PlainTextPart) part).getText());
162 } else if (part instanceof FreenetLinkPart) {
163 FreenetLinkPart freenetLinkPart = (FreenetLinkPart) part;
164 text.append('[').append(freenetLinkPart.getLink()).append('|').append(freenetLinkPart.isTrusted() ? "trusted|" : "").append(freenetLinkPart.getTitle()).append('|').append(freenetLinkPart.getText()).append(']');
165 } else if (part instanceof LinkPart) {
166 LinkPart linkPart = (LinkPart) part;
167 text.append('[').append(linkPart.getLink()).append('|').append(linkPart.getTitle()).append('|').append(linkPart.getText()).append(']');
168 } else if (part instanceof SonePart) {
169 SonePart sonePart = (SonePart) part;
170 text.append("[Sone|").append(sonePart.getSone().getId()).append(']');
173 return text.toString();
177 * Mock Sone provider.
179 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
181 private static class TestSoneProvider implements SoneProvider {
184 public Function<String, Optional<Sone>> soneLoader() {
185 return new Function<String, Optional<Sone>>() {
187 public Optional<Sone> apply(String soneId) {
188 return getSone(soneId);
197 public Optional<Sone> getSone(final String soneId) {
198 return Optional.<Sone>of(new IdOnlySone(soneId));
205 public Collection<Sone> getSones() {
213 public Collection<Sone> getLocalSones() {
221 public Collection<Sone> getRemoteSones() {