Skip to content

Commit

Permalink
Add test fixture for KGCLWriter.
Browse files Browse the repository at this point in the history
Add a test fixture for the KGCLWriter class. We only test using a
string-backed writer object, so that we do not have to actually write
any file anywhere.

Also slightly rearrange the KGCLReader test to use a callback-based
method as the main helper method, and add a test for the use of a prefix
manager derived from a OWL ontology.
  • Loading branch information
gouttegd committed Feb 20, 2024
1 parent 1151abc commit a537432
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 22 deletions.
10 changes: 10 additions & 0 deletions core/src/main/java/org/incenp/obofoundry/kgcl/KGCLWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.List;

import org.incenp.obofoundry.kgcl.model.Change;
Expand All @@ -50,6 +51,15 @@ public KGCLWriter(OutputStream kgclOutput) {
output = new BufferedWriter(new OutputStreamWriter(kgclOutput));
}

/**
* Creates a new instance to write to a character stream writer.
*
* @param kgclOutput The character stream to write to.
*/
public KGCLWriter(Writer kgclOutput) {
output = new BufferedWriter(kgclOutput);
}

/**
* Creates a new instance to write to a file.
*
Expand Down
70 changes: 48 additions & 22 deletions core/src/test/java/org/incenp/obofoundry/kgcl/KGCLReaderTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@

package org.incenp.obofoundry.kgcl;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import org.incenp.obofoundry.kgcl.model.Change;
import org.incenp.obofoundry.kgcl.model.ClassCreation;
Expand All @@ -50,6 +48,10 @@
import org.incenp.obofoundry.kgcl.model.TextDefinitionReplacement;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;
import org.semanticweb.owlapi.vocab.OWLRDFVocabulary;

class KGCLReaderTest {
Expand All @@ -60,8 +62,8 @@ class KGCLReaderTest {
void testFileParser() throws IOException {
KGCLReader reader = new KGCLReader("src/test/resources/sample1.kgcl");
reader.setPrefixManager(util.getPrefixManager());
assertTrue(reader.read());
assertEquals(5, reader.getChangeSet().size());
Assertions.assertTrue(reader.read());
Assertions.assertEquals(5, reader.getChangeSet().size());

NodeRename c1 = new NodeRename();
c1.setAboutNode(util.getNode("0001"));
Expand Down Expand Up @@ -172,9 +174,24 @@ void testUnknownPrefixIsOBOStyleID() {
testParse("obsolete PFX:0001", change);

// Same with no prefix manager at all
KGCLReader reader = new KGCLReader();
reader.read("obsolete PFX:0001");
Assertions.assertEquals(change, reader.getChangeSet().get(0));
testParse(r -> r.read("obsolete PFX:0001"), change);
}

@Test
void testUsingOntologyDerivedPrefixManager() {
NodeObsoletion change = new NodeObsoletion();
change.setAboutNode(util.getForeignNode("http://www.co-ode.org/ontologies/pizza/pizza.owl#LaReine"));

OWLOntologyManager mgr = OWLManager.createOWLOntologyManager();
try {
OWLOntology ont = mgr.loadOntologyFromOntologyDocument(new File("src/test/resources/pizza.ofn"));
testParse(r -> {
r.setPrefixManager(ont);
r.read("obsolete pizza:LaReine");
}, change);
} catch ( OWLOntologyCreationException e ) {
Assertions.fail(e);
}
}

@Test
Expand Down Expand Up @@ -411,33 +428,42 @@ void testAnnotationChange() {
}

/*
* Try parsing a KGCL string and check that there is no error. If 'expected' is
* not null, check that the change effectively parsed matches what was expected;
* otherwise, check that no changes at all have been parsed.
* Helper method to test the KGCLReader. It initialises a non-file-based reader,
* calls the specified callback with the reader, then checks that the change
* parsed by the reader matches what was expected.
*/
void testParse(String kgcl, Change expected) {
void testParse(Consumer<KGCLReader> c, Change expected) {
KGCLReader reader = new KGCLReader();
reader.setPrefixManager(util.getPrefixManager());
c.accept(reader);

assertTrue(reader.read(kgcl));
assertTrue(reader.getErrors().isEmpty());
Assertions.assertTrue(reader.getErrors().isEmpty());

List<Change> changes = reader.getChangeSet();
if ( expected == null ) {
// The parser should always return an empty list
assertTrue(changes.isEmpty());
// The parser should always return an empty list.
Assertions.assertTrue(changes.isEmpty());
} else {
assertEquals(1, changes.size());
assertEquals(expected, changes.get(0));
Assertions.assertEquals(1, changes.size());
Assertions.assertEquals(expected, changes.get(0));
}
}

/*
* Variant of the previous method to test parsing a single string.
*/
void testParse(String kgcl, Change expected) {
testParse(r -> {
r.setPrefixManager(util.getPrefixManager());
Assertions.assertTrue(r.read(kgcl));
}, expected);
}

/*
* Try parsing a known bogus KGCL string and check that it fails as expected.
*/
void testParseFail(String kgcl) {
KGCLReader reader = new KGCLReader();
assertFalse(reader.read(kgcl));
assertTrue(reader.getErrors().size() > 0);
Assertions.assertFalse(reader.read(kgcl));
Assertions.assertTrue(reader.getErrors().size() > 0);
}
}
135 changes: 135 additions & 0 deletions core/src/test/java/org/incenp/obofoundry/kgcl/KGCLWriterTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
* KGCL-Java - KGCL library for Java
* Copyright © 2024 Damien Goutte-Gattat
*
* 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
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the Gnu General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package org.incenp.obofoundry.kgcl;

import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;

import org.incenp.obofoundry.kgcl.model.Change;
import org.incenp.obofoundry.kgcl.model.ClassCreation;
import org.incenp.obofoundry.kgcl.model.NodeObsoletion;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.semanticweb.owlapi.apibinding.OWLManager;
import org.semanticweb.owlapi.model.OWLOntology;
import org.semanticweb.owlapi.model.OWLOntologyCreationException;
import org.semanticweb.owlapi.model.OWLOntologyManager;

public class KGCLWriterTest {

private static final TestUtils util = new TestUtils();

@Test
void testWriteSingleChange() {
NodeObsoletion change = new NodeObsoletion();
change.setAboutNode(util.getNode("0001"));
testSimpleWrite(w -> w.write(change), "obsolete <https://example.org/0001>\n");
}

@Test
void testWriteChangeset() {
NodeObsoletion c1 = new NodeObsoletion();
c1.setAboutNode(util.getNode("0001"));

ClassCreation c2 = new ClassCreation();
c2.setAboutNode(util.getNode("0002"));
c2.setNewValue("new class");

ArrayList<Change> changeset = new ArrayList<Change>();
changeset.add(c1);
changeset.add(c2);

testSimpleWrite(w -> w.write(changeset),
"obsolete <https://example.org/0001>\ncreate class <https://example.org/0002> \"new class\"\n");
}

@Test
void testWriteComment() {
testSimpleWrite(w -> w.write("a comment"), "# a comment\n");
}

@Test
void testMultipleWrite() {
NodeObsoletion c1 = new NodeObsoletion();
c1.setAboutNode(util.getNode("0001"));

ClassCreation c2 = new ClassCreation();
c2.setAboutNode(util.getNode("0002"));
c2.setNewValue("new class");

testSimpleWrite(w -> {
w.write(c1);
w.write("a comment");
w.write(c2);
}, "obsolete <https://example.org/0001>\n# a comment\ncreate class <https://example.org/0002> \"new class\"\n");
}

@Test
void testWriteWithPrefixManager() {
NodeObsoletion change = new NodeObsoletion();
change.setAboutNode(util.getNode("0001"));

testSimpleWrite(w -> {
w.setPrefixManager(util.getPrefixManager());
w.write(change);
}, "obsolete EX:0001\n");
}

@Test
void testWriteWithOntologyDerivedPrefixManager() {
NodeObsoletion change = new NodeObsoletion();
change.setAboutNode(util.getForeignNode("http://www.co-ode.org/ontologies/pizza/pizza.owl#LaReine"));

OWLOntologyManager mgr = OWLManager.createOWLOntologyManager();
try {
OWLOntology ont = mgr.loadOntologyFromOntologyDocument(new File("src/test/resources/pizza.ofn"));
testSimpleWrite(w -> {
w.setPrefixManager(ont);
w.write(change);
}, "obsolete pizza:LaReine\n");
} catch ( OWLOntologyCreationException e ) {
Assertions.fail(e);
}
}

/*
* Helper method to test the KGCLWriter. This creates a string-backed writer,
* calls the provided callback with the writer, then checks that the writer
* wrote what was expected.
*/
private void testSimpleWrite(IKGCLWriterConsumer c, String expected) {
StringWriter writer = new StringWriter();
KGCLWriter kgclWriter = new KGCLWriter(writer);
try {
c.accept(kgclWriter);
kgclWriter.close();
} catch ( IOException ioe ) {
Assertions.fail(ioe);
}

Assertions.assertEquals(expected, writer.toString());
}
}

/* The callback passed to the testSimpleWrite method above. */
interface IKGCLWriterConsumer {
void accept(KGCLWriter writer) throws IOException;
}

0 comments on commit a537432

Please sign in to comment.