X-Git-Url: https://git.pterodactylus.net/?p=Sone.git;a=blobdiff_plain;f=src%2Ftest%2Fjava%2Fnet%2Fpterodactylus%2Fsone%2Ftext%2FSoneTextParserTest.java;h=2ac6db7b6a7cd985ea1215cd19cd4163fcd9f372;hp=f0b0e1bd9464549fb23eb3d2f9530bd99c5b67e9;hb=b9281ba712aac6ea70b7dc217607608ae80b594d;hpb=6b9c7c806fd1fc168e598d6e4eb6ee46ad2aa6fd diff --git a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java index f0b0e1b..2ac6db7 100644 --- a/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java +++ b/src/test/java/net/pterodactylus/sone/text/SoneTextParserTest.java @@ -1,5 +1,5 @@ /* - * Sone - SoneTextParserTest.java - Copyright © 2011 David Roden + * Sone - SoneTextParserTest.java - Copyright © 2011–2013 David Roden * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,15 @@ package net.pterodactylus.sone.text; import java.io.IOException; import java.io.StringReader; +import java.util.Arrays; +import java.util.Collection; +import net.pterodactylus.sone.data.Sone; +import net.pterodactylus.sone.data.impl.IdOnlySone; +import net.pterodactylus.sone.database.SoneProvider; + +import com.google.common.base.Function; +import com.google.common.base.Optional; import junit.framework.TestCase; /** @@ -29,46 +37,193 @@ import junit.framework.TestCase; */ public class SoneTextParserTest extends TestCase { + // + // ACTIONS + // + /** * Tests basic plain-text operation of the parser. * * @throws IOException * if an I/O error occurs */ + @SuppressWarnings("static-method") public void testPlainText() throws IOException { SoneTextParser soneTextParser = new SoneTextParser(null, null); Iterable parts; - StringBuilder text = new StringBuilder(); /* check basic operation. */ - text.setLength(0); parts = soneTextParser.parse(null, new StringReader("Test.")); assertNotNull("Parts", parts); - for (Part part : parts) { - assertTrue("Part is PlainTextPart", part instanceof PlainTextPart); - text.append(((PlainTextPart) part).getText()); - } - assertEquals("Part Text", "Test.", text.toString()); + assertEquals("Part Text", "Test.", convertText(parts, PlainTextPart.class)); /* check empty lines at start and end. */ - text.setLength(0); parts = soneTextParser.parse(null, new StringReader("\nTest.\n\n")); assertNotNull("Parts", parts); - for (Part part : parts) { - assertTrue("Part is PlainTextPart", part instanceof PlainTextPart); - text.append(((PlainTextPart) part).getText()); - } - assertEquals("Part Text", "Test.", text.toString()); + assertEquals("Part Text", "Test.", convertText(parts, PlainTextPart.class)); /* check duplicate empty lines in the text. */ - text.setLength(0); parts = soneTextParser.parse(null, new StringReader("\nTest.\n\n\nTest.")); assertNotNull("Parts", parts); + assertEquals("Part Text", "Test.\n\nTest.", convertText(parts, PlainTextPart.class)); + } + + /** + * Tests parsing of KSK links. + * + * @throws IOException + * if an I/O error occurs + */ + @SuppressWarnings("static-method") + public void testKSKLinks() throws IOException { + SoneTextParser soneTextParser = new SoneTextParser(null, null); + Iterable parts; + + /* check basic links. */ + parts = soneTextParser.parse(null, new StringReader("KSK@gpl.txt")); + assertNotNull("Parts", parts); + assertEquals("Part Text", "[KSK@gpl.txt|gpl.txt|gpl.txt]", convertText(parts, FreenetLinkPart.class)); + + /* check embedded links. */ + parts = soneTextParser.parse(null, new StringReader("Link is KSK@gpl.txt\u200b.")); + assertNotNull("Parts", parts); + assertEquals("Part Text", "Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\u200b.", convertText(parts, PlainTextPart.class, FreenetLinkPart.class)); + + /* check embedded links and line breaks. */ + parts = soneTextParser.parse(null, new StringReader("Link is KSK@gpl.txt\nKSK@test.dat\n")); + assertNotNull("Parts", parts); + assertEquals("Part Text", "Link is [KSK@gpl.txt|gpl.txt|gpl.txt]\n[KSK@test.dat|test.dat|test.dat]", convertText(parts, PlainTextPart.class, FreenetLinkPart.class)); + } + + /** + * Test case for a bug that was discovered in 0.6.7. + * + * @throws IOException + * if an I/O error occurs + */ + @SuppressWarnings({ "synthetic-access", "static-method" }) + public void testEmptyLinesAndSoneLinks() throws IOException { + SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null); + Iterable parts; + + /* check basic links. */ + parts = soneTextParser.parse(null, new StringReader("Some text.\n\nLink to sone://DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU and stuff.")); + assertNotNull("Parts", parts); + assertEquals("Part Text", "Some text.\n\nLink to [Sone|DAxKQzS48mtaQc7sUVHIgx3fnWZPQBz0EueBreUVWrU] and stuff.", convertText(parts, PlainTextPart.class, SonePart.class)); + } + + /** + * Test for a bug discovered in Sone 0.8.4 where a plain “http://” would be + * parsed into a link. + * + * @throws IOException + * if an I/O error occurs + */ + @SuppressWarnings({ "synthetic-access", "static-method" }) + public void testEmpyHttpLinks() throws IOException { + SoneTextParser soneTextParser = new SoneTextParser(new TestSoneProvider(), null); + Iterable parts; + + /* check empty http links. */ + parts = soneTextParser.parse(null, new StringReader("Some text. Empty link: http:// – nice!")); + assertNotNull("Parts", parts); + assertEquals("Part Text", "Some text. Empty link: http:// – nice!", convertText(parts, PlainTextPart.class)); + } + + // + // PRIVATE METHODS + // + + /** + * Converts all given {@link Part}s into a string, validating that the + * part’s classes match only the expected classes. + * + * @param parts + * The parts to convert to text + * @param validClasses + * The valid classes; if no classes are given, all classes are + * valid + * @return The converted text + */ + private static String convertText(Iterable parts, Class... validClasses) { + StringBuilder text = new StringBuilder(); for (Part part : parts) { - assertTrue("Part is PlainTextPart", part instanceof PlainTextPart); - text.append(((PlainTextPart) part).getText()); + assertNotNull("Part", part); + boolean classValid = validClasses.length == 0; + for (Class validClass : validClasses) { + if (validClass.isAssignableFrom(part.getClass())) { + classValid = true; + break; + } + } + if (!classValid) { + fail("Part’s Class (" + part.getClass() + ") is not one of " + Arrays.toString(validClasses)); + } + if (part instanceof PlainTextPart) { + text.append(((PlainTextPart) part).getText()); + } else if (part instanceof FreenetLinkPart) { + FreenetLinkPart freenetLinkPart = (FreenetLinkPart) part; + text.append('[').append(freenetLinkPart.getLink()).append('|').append(freenetLinkPart.isTrusted() ? "trusted|" : "").append(freenetLinkPart.getTitle()).append('|').append(freenetLinkPart.getText()).append(']'); + } else if (part instanceof LinkPart) { + LinkPart linkPart = (LinkPart) part; + text.append('[').append(linkPart.getLink()).append('|').append(linkPart.getTitle()).append('|').append(linkPart.getText()).append(']'); + } else if (part instanceof SonePart) { + SonePart sonePart = (SonePart) part; + text.append("[Sone|").append(sonePart.getSone().getId()).append(']'); + } } - assertEquals("Part Text", "Test.\n\nTest.", text.toString()); + return text.toString(); + } + + /** + * Mock Sone provider. + * + * @author David ‘Bombe’ Roden + */ + private static class TestSoneProvider implements SoneProvider { + + @Override + public Function> soneLoader() { + return new Function>() { + @Override + public Optional apply(String soneId) { + return getSone(soneId); + } + }; + } + + /** + * {@inheritDoc} + */ + @Override + public Optional getSone(final String soneId) { + return Optional.of(new IdOnlySone(soneId)); + } + + /** + * {@inheritDocs} + */ + @Override + public Collection getSones() { + return null; + } + + /** + * {@inheritDocs} + */ + @Override + public Collection getLocalSones() { + return null; + } + + /** + * {@inheritDocs} + */ + @Override + public Collection getRemoteSones() { + return null; + } + } }