-
Notifications
You must be signed in to change notification settings - Fork 92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added round-trip tests #49
Changes from all commits
c132ec0
64847e2
073c343
cd34a99
52929c2
20a3eba
266c3f0
24476c2
72e37df
c79d212
4a1bcb4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
package ezvcard.io.roundtrip; | ||
|
||
import java.io.*; | ||
|
||
import org.junit.Test; | ||
|
||
import ezvcard.VCardVersion; | ||
import ezvcard.io.StreamReader; | ||
import ezvcard.io.StreamWriter; | ||
import ezvcard.io.json.JCardReader; | ||
import ezvcard.io.json.JCardWriter; | ||
|
||
/* | ||
Copyright (c) 2012-2016, Michael Angstadt | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
|
||
1. Redistributions of source code must retain the above copyright notice, this | ||
list of conditions and the following disclaimer. | ||
2. Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
|
||
The views and conclusions contained in the software and documentation are those | ||
of the authors and should not be interpreted as representing official policies, | ||
either expressed or implied, of the FreeBSD Project. | ||
*/ | ||
|
||
/** | ||
* @author Buddy Gorven | ||
*/ | ||
public class JCardRoundTripTest extends RoundTripTestBase { | ||
|
||
public JCardRoundTripTest() throws Throwable { | ||
updateSamples(VCardVersion.V4_0); | ||
} | ||
|
||
@Test | ||
public void convert_to_jcard() throws Throwable { | ||
convertAllFromVCard(VCardVersion.V4_0, true, true, | ||
"outlook" // newline conversion on linux | ||
); | ||
} | ||
|
||
@Test | ||
public void convert_from_jcard() throws Throwable { | ||
convertAllToVCard(VCardVersion.V4_0, true, true, | ||
"outlook" // newline conversion on linux | ||
); | ||
} | ||
|
||
@Override | ||
protected StreamWriter getTargetWriter(Writer sw) { | ||
JCardWriter writer = new JCardWriter(sw); | ||
writer.setPrettyPrint(true); | ||
return writer; | ||
} | ||
|
||
@Override | ||
protected StreamReader getTargetReader(File file) throws FileNotFoundException { | ||
return new JCardReader(file); | ||
} | ||
|
||
@Override | ||
protected String getTargetExtension() { | ||
return "json"; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
package ezvcard.io.roundtrip; | ||
|
||
import static org.junit.Assert.*; | ||
|
||
import java.io.*; | ||
import java.util.List; | ||
|
||
import ezvcard.VCard; | ||
import ezvcard.VCardVersion; | ||
import ezvcard.io.StreamReader; | ||
import ezvcard.io.StreamWriter; | ||
import ezvcard.io.text.VCardReader; | ||
import ezvcard.io.text.VCardWriter; | ||
import ezvcard.property.VCardProperty; | ||
import ezvcard.util.IOUtils; | ||
|
||
public abstract class RoundTripTestBase { | ||
|
||
static final class Filter implements FilenameFilter { | ||
private final String extension; | ||
private final String[] excludes; | ||
|
||
private Filter(String extension, String... excludes) { | ||
this.extension = "." + extension; | ||
for (int i = 0; i < excludes.length; i++) { | ||
excludes[i] = excludes[i].toLowerCase(); | ||
} | ||
this.excludes = excludes; | ||
} | ||
|
||
public boolean accept(File dir, String name) { | ||
name = name.toLowerCase(); | ||
if (!name.endsWith(extension)) { | ||
return false; | ||
} else { | ||
for (String exclude : excludes) { | ||
if (name.contains(exclude)) { | ||
return false; | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
private static final String VCF_EXTENSION = "vcf"; | ||
|
||
protected RoundTripTestBase() { | ||
getSampleDir().mkdirs(); | ||
for (File existing : getSampleDir().listFiles()) { | ||
existing.delete(); | ||
} | ||
} | ||
|
||
/** | ||
* Run this if there are new vcard samples added to | ||
* src/test/resources/ezvcard/io/text/, or if the output format changes. | ||
* | ||
* @param version the version of VCard to roundtrip to | ||
* @param excludes files to exclude (i.e. files that are known to fail | ||
* roundtrip testing). Files will be excluded if the exclude string is found | ||
* anywhere in the file name (case-insensitive) | ||
*/ | ||
public void updateSamples(VCardVersion version, String... excludes) throws Exception { | ||
// Convert source files to target type | ||
File[] sourceFiles = listFiles(new File("src/test/resources/ezvcard/io/text"), VCF_EXTENSION, excludes); | ||
for (File sourceFile : sourceFiles) { | ||
String file = sourceFile.getName().toString(); | ||
StringWriter sw = new StringWriter(); | ||
try { | ||
convert(getVCardReader(sourceFile), getTargetWriter(sw), version); | ||
} catch (Exception e) { | ||
throw new Exception("Error converting " + file, e); | ||
} | ||
write(file.replaceAll("vcf$", "v" + version.getVersion() + "." + getTargetExtension()), sw.toString()); | ||
} | ||
|
||
// Convert files from target type back to vcard | ||
for (File targetFile : listFiles(version, getTargetExtension())) { | ||
String file = targetFile.getName().toString(); | ||
StringWriter sw = new StringWriter(); | ||
try { | ||
convert(getTargetReader(targetFile), getVCardWriter(sw, version), version); | ||
} catch (Exception e) { | ||
throw new Exception("Error converting " + file, e); | ||
} | ||
write(file.replace(getTargetExtension(), VCF_EXTENSION), sw.toString()); | ||
} | ||
} | ||
|
||
/** | ||
* Converts all files in {@link #getSampleDir()} with names ending in | ||
* {@link #VCF_EXTENSION} using {@link #getTargetWriter(StringWriter)} , and | ||
* asserts that the content matches the file with the corresponding target | ||
* extension. | ||
* | ||
* @param excludes source files to exclude from this test | ||
* @throws IOException | ||
*/ | ||
public void convertAllFromVCard(VCardVersion version, boolean equals, boolean content, String... excludes) throws Exception { | ||
for (File vcf : listFiles(version, VCF_EXTENSION, excludes)) { | ||
String vcardFile = vcf.getName().toString(); | ||
String targetFile = vcardFile.replace(VCF_EXTENSION, getTargetExtension()); | ||
StringWriter vcardSW = new StringWriter(); | ||
try { | ||
List<VCard> vcard = convert(getVCardReader(vcf), getTargetWriter(vcardSW), version); | ||
List<VCard> card = convert(getTargetReader(new File(getSampleDir(), targetFile)), null, version); | ||
if (equals) { | ||
assertEquals(vcardFile, card, vcard); | ||
} | ||
} catch (Exception e) { | ||
throw new Exception("Error converting " + vcardFile, e); | ||
} | ||
if (content) { | ||
assertEquals(vcardFile, read(targetFile), vcardSW.toString()); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Converts all files in {@link #getSampleDir()} with names ending in | ||
* {@link #getTargetExtension()} using | ||
* {@link #getVCardWriter(StringWriter, VCardVersion)}, and asserts that the | ||
* content matches the file with the corresponding vcard extension. | ||
*/ | ||
public void convertAllToVCard(VCardVersion version, boolean equals, boolean content, String... excludes) throws Exception { | ||
for (File target : listFiles(version, getTargetExtension(), excludes)) { | ||
String targetFile = target.getName().toString(); | ||
String vcardFile = targetFile.replace(getTargetExtension(), VCF_EXTENSION); | ||
StringWriter targetSW = new StringWriter(); | ||
try { | ||
List<VCard> card = convert(getTargetReader(target), getVCardWriter(targetSW, version), version); | ||
List<VCard> vcard = convert(getVCardReader(new File(getSampleDir(), vcardFile)), null, version); | ||
if (equals) { | ||
assertEquals(vcardFile, vcard, card); | ||
} | ||
} catch (Exception e) { | ||
throw new Exception("Error converting " + targetFile, e); | ||
} | ||
if (content) { | ||
assertEquals(targetFile, read(vcardFile), targetSW.toString()); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* @return The extension of the file type under test, not including the "." | ||
*/ | ||
protected abstract String getTargetExtension(); | ||
|
||
/** | ||
* @return A writer for the file type under test | ||
*/ | ||
protected abstract StreamWriter getTargetWriter(Writer sw); | ||
|
||
/** | ||
* @return A reader for the file type under test | ||
*/ | ||
protected abstract StreamReader getTargetReader(File file) throws FileNotFoundException; | ||
|
||
protected File getSampleDir() { | ||
return new File("src/test/resources/ezvcard/io/" + getTargetExtension() + "/roundtrip/"); | ||
} | ||
|
||
protected StreamWriter getVCardWriter(Writer sw, VCardVersion version) { | ||
return new VCardWriter(sw, version); | ||
} | ||
|
||
protected StreamReader getVCardReader(File file) throws FileNotFoundException { | ||
return new VCardReader(file); | ||
} | ||
|
||
public File[] listFiles(VCardVersion version, String extension, String... excludes) { | ||
return listFiles(getSampleDir(), "v" + version + "." + extension, excludes); | ||
} | ||
|
||
public static File[] listFiles(File dir, String extension, String... excludes) { | ||
return dir.listFiles(new Filter(extension, excludes)); | ||
} | ||
|
||
private static List<VCard> convert(StreamReader reader, StreamWriter writer, VCardVersion version) throws IOException { | ||
try { | ||
List<VCard> result = reader.readAll(); | ||
for (VCard vcard : result) { | ||
// Remove any property that is not supported by the version of VCard to be round-tripped to | ||
for (VCardProperty prop : vcard.getProperties()) { | ||
if (!prop.isSupportedBy(version)) { | ||
vcard.removeProperty(prop); | ||
} | ||
} | ||
vcard.setVersion(version); | ||
if (writer != null) { | ||
writer.write(vcard); | ||
} | ||
} | ||
return result; | ||
} finally { | ||
if (writer != null) { | ||
writer.close(); | ||
} | ||
reader.close(); | ||
} | ||
} | ||
|
||
private String read(String fileName) throws IOException { | ||
return IOUtils.getFileContents(new File(getSampleDir(), fileName)); | ||
} | ||
|
||
private void write(String fileName, String converted) throws IOException { | ||
Writer writer = IOUtils.utf8Writer(new File(getSampleDir(), fileName)); | ||
try { | ||
writer.write(converted); | ||
} finally { | ||
writer.close(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package ezvcard.io.roundtrip; | ||
|
||
import java.io.*; | ||
|
||
import org.junit.Test; | ||
|
||
import ezvcard.VCardVersion; | ||
import ezvcard.io.StreamReader; | ||
import ezvcard.io.StreamWriter; | ||
import ezvcard.io.xml.XCardReader; | ||
import ezvcard.io.xml.XCardWriter; | ||
|
||
public class XCardRoundTripTest extends RoundTripTestBase { | ||
|
||
public XCardRoundTripTest() throws Exception { | ||
updateSamples(VCardVersion.V4_0, | ||
"outlook-2003" //  in fburl is not valid xml | ||
); | ||
updateSamples(VCardVersion.V3_0); | ||
} | ||
|
||
@Test | ||
public void equals_compare_vcard_4_to_xcard() throws Exception { | ||
convertAllFromVCard(VCardVersion.V4_0, true, false, | ||
"outlook" // newlines not preserved on linux | ||
); | ||
} | ||
|
||
@Test | ||
public void content_compare_vcard_4_to_xcard() throws Exception { | ||
convertAllFromVCard(VCardVersion.V4_0, false, true, | ||
"outlook", // newlines not preserved on linux | ||
"iphone", "lotus_notes" // groups are reordered | ||
); | ||
} | ||
|
||
@Test | ||
public void compare_xcard_to_vcard_4() throws Exception { | ||
convertAllToVCard(VCardVersion.V4_0, true, true, | ||
"outlook" // newline conversion on linux | ||
); | ||
} | ||
|
||
@Test | ||
public void compare_vcard_3_to_xcard() throws Exception { | ||
convertAllFromVCard(VCardVersion.V3_0, false, true, | ||
"android", // <pref><integer>1</integer></pref> removed from the ÑÑÑÑÑÑÑÑÑÑÑÑ email | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
vCard versions 2.1 and 3.0 do not have a PREF parameter. Instead, they have a TYPE=PREF parameter. ez-vcard converts between the two. |
||
"ms_outlook", // newlines not preserved on linux | ||
"iphone", "lotus_notes", // groups are reordered | ||
"outlook-2007", "rfc6350", // tel uri cannot round trip through VCard V3 (is converted to text type) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yep. |
||
"outlook-2003", "thunderbird" // TYPE parameters converted to lowercase | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I've only observed this on TYPE parameters that belong to properties that hold binary data (PHOTO and KEY). This is due to the way ez-vcard parses these properties. All other TYPE parameters keep their case. TYPE properties are case-insensitive, so no data is lost. |
||
); | ||
} | ||
|
||
@Test | ||
public void content_compare_xcard_to_vcard_3() throws Exception { | ||
convertAllToVCard(VCardVersion.V3_0, false, true); | ||
} | ||
|
||
@Override | ||
protected String getTargetExtension() { | ||
return "xml"; | ||
} | ||
|
||
@Override | ||
protected StreamWriter getTargetWriter(Writer sw) { | ||
return new XCardWriter(sw); | ||
} | ||
|
||
@Override | ||
protected StreamReader getTargetReader(File file) throws FileNotFoundException { | ||
return new XCardReader(file); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
groups are reordered
This has do to with the fact that ez-vcard does not preserve property order in all cases when parsing vCards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might just need to leave this exclude in then; there's still the equals_compare test to verify that the data from these vcards makes it through the round-trip correctly.