package org.genedb.web.gui;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.genedb.db.domain.objects.Chromosome;
import org.genedb.db.domain.objects.LocatedFeature;
import org.genedb.db.domain.objects.TranscriptComponent;
import org.genedb.db.domain.objects.Transcript;
import org.genedb.db.domain.services.BasicGeneService;
import org.genedb.db.domain.test.MockBasicGeneService;
import org.junit.Test;
/**
* Test that the {@link ContextMapDiagram} class works as intended.
*
* @author rh11
*/
@SuppressWarnings("deprecation")
public class ContextMapDiagramTest {
// Tests on the "isolated" genes, to make sure the basics are working
private BasicGeneService simple () {
MockBasicGeneService mockBasicGeneService = new MockBasicGeneService("cat", "chr1", 1);
mockBasicGeneService.addSimpleGene("isolated", 90, 110, 2);
mockBasicGeneService.setChromosome("chr2");
mockBasicGeneService.setStrand(-1);
mockBasicGeneService.addSimpleGene("isolated2", 90, 110, 2);
mockBasicGeneService.setChromosome(new Chromosome("chr3", 103, 1000));
mockBasicGeneService.addSimpleGene("lhs", 20, 30, 3);
mockBasicGeneService.addSimpleGene("rhs", 950, 990, 3);
mockBasicGeneService.setChromosome("chr4");
mockBasicGeneService.addSimpleGene("large", 1000, 100000, 4);
return mockBasicGeneService;
}
/**
* Test that <code>ContextMapDiagram.forRegion</code> does something plausible-looking
* in a simple case.
*/
@Test public void simpleRegion() {
ContextMapDiagram diagram = ContextMapDiagram.forRegion(simple(), "cat", "chr1", 101, 0, 1000);
assertNotNull(diagram);
assertEquals(0, diagram.getStart());
assertEquals(1000, diagram.getEnd());
List<LocatedFeature> track = diagram.getTrack(1);
assertNotNull(track);
assertEquals(1, track.size());
}
/**
* Test that the diagram is centred about the gene of interest
*/
@Test public void diagramPosition() {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "isolated", 100);
assertEquals(diagram.getStart(), 50);
assertEquals(diagram.getEnd(), 150);
}
/**
* Test that a single gene is correctly placed in track 1,
* and that (a reasonable sample of) the other tracks are unassigned.
*/
@Test public void correctTracks() {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "isolated", 100);
assertEquals(diagram.numberOfPositiveTracks(), 1);
assertEquals(diagram.numberOfNegativeTracks(), 0);
assertNotNull(diagram.getTrack(1));
assertNull (diagram.getTrack(2));
assertNull (diagram.getTrack(3));
assertNull (diagram.getTrack(-1));
assertNull (diagram.getTrack(-2));
assertNull (diagram.getTrack(-3));
}
/**
* Test that a single gene on the reverse strand is correctly placed in track -1,
* and that (a reasonable sample of) the other tracks are unassigned.
*/
@Test public void correctTracksNegative() {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "isolated2", 100);
assertEquals(diagram.numberOfPositiveTracks(), 0);
assertEquals(diagram.numberOfNegativeTracks(), 1);
assertNull (diagram.getTrack(1));
assertNull (diagram.getTrack(2));
assertNull (diagram.getTrack(3));
assertNotNull(diagram.getTrack(-1));
assertNull (diagram.getTrack(-2));
assertNull (diagram.getTrack(-3));
}
/**
* Test that centring on a gene near the left-hand end of the chromosome
* correctly begins the diagram at zero.
*/
@Test
public void nearLeftEnd () {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "lhs", 100);
assertEquals(0, diagram.getStart());
assertEquals(100, diagram.getEnd());
}
/**
* Test that centring on a gene near the left-hand end of the chromosome
* correctly begins the diagram at zero.
*/
@Test
public void nearRightEnd () {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "rhs", 100);
assertEquals(900, diagram.getStart());
assertEquals(1000, diagram.getEnd());
}
/**
* Test that having a gene larger than the diagram works as expected.
*/
@Test
public void largeGene() {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "large", 100);
int expectedCentre = (1000 + 100000) / 2;
assertEquals(expectedCentre - 50, diagram.getStart());
assertEquals(expectedCentre + 50, diagram.getEnd());
}
/**
* Test that the track contains a single transcript with the correct
* colour, and that the transcript contains a single exon at the correct
* location.
*/
@Test public void transcript() {
ContextMapDiagram diagram = ContextMapDiagram.forGene(simple(), "isolated", 100);
List<LocatedFeature> track = diagram.getTrack(1);
assertNotNull(track);
assertEquals(track.size(), 1);
LocatedFeature transcriptFeature = track.get(0);
assertNotNull(transcriptFeature);
assertEquals(90, transcriptFeature.getFmin());
assertEquals(110, transcriptFeature.getFmax());
assertTrue("The features of this diagram should be transcripts", transcriptFeature instanceof Transcript);
Transcript transcript = (Transcript) transcriptFeature;
assertNotNull(transcript.getColourId());
assertEquals(2, transcript.getColourId().intValue());
Set<TranscriptComponent> exons = transcript.getComponents();
assertNotNull(exons);
assertEquals(exons.size(), 1);
for (TranscriptComponent exon: exons) {
assertNotNull(exon);
assertEquals(90, exon.getStart());
assertEquals(110, exon.getEnd());
}
}
private void assertTrackAllocation (ContextMapDiagram diagram, String[][] expectedAssignments) {
List<List<LocatedFeature>> tracks = new ArrayList<List<LocatedFeature>>();
for (int i=1; i<=diagram.numberOfPositiveTracks(); i++)
tracks.add(diagram.getTrack(i));
for (int i=0; i<expectedAssignments.length; i++) {
List<LocatedFeature> track = diagram.getTrack(i+1);
String[] expected = expectedAssignments[i];
if (expected == null) {
assertNull(track);
continue;
}
assertEquals(expected.length, track.size());
for (int j=0; j < expected.length; j++) {
String expectedGeneName = expected[j];
LocatedFeature transcriptFeature = track.get(j);
assertTrue("The features of this diagram should be transcripts", transcriptFeature instanceof Transcript);
Transcript transcript = (Transcript) transcriptFeature;
if (expectedGeneName.contains("/")) {
// gene/transcript
int slashLoc = expectedGeneName.indexOf('/');
String expectedTranscriptName = expectedGeneName.substring(slashLoc+1);
expectedGeneName = expectedGeneName.substring(0, slashLoc);
assertEquals(expectedTranscriptName, transcript.getUniqueName());
}
assertEquals(expectedGeneName, transcript.getGene().getDisplayName());
}
}
}
// Tests for simple genes with overlaps
private BasicGeneService simpleOverlaps () {
MockBasicGeneService mockBasicGeneService = new MockBasicGeneService("dog", "chr1", 1);
mockBasicGeneService.addSimpleGene("one", 10, 30);
mockBasicGeneService.addSimpleGene("two", 20, 40);
mockBasicGeneService.addSimpleGene("three", 30, 50);
mockBasicGeneService.addSimpleGene("four", 40, 60);
mockBasicGeneService.addSimpleGene("five", 50, 70);
return mockBasicGeneService;
}
/**
* Test that track-allocation works correctly with some overlapping genes.
*/
@Test public void overlappingTrackAllocation() {
ContextMapDiagram diagram = ContextMapDiagram.forRegion(simpleOverlaps(), "dog", "chr1", 101, 0, 100);
String[][] expectedTracks = new String[][] {
new String[] {"one", "four"},
new String[] {"two", "five"},
new String[] {"three"},
null
};
assertEquals(3, diagram.numberOfPositiveTracks());
assertTrackAllocation(diagram, expectedTracks);
}
// Tests for alternative splicing
private BasicGeneService altSimple (int strand) {
MockBasicGeneService mockBasicGeneService = new MockBasicGeneService("dog", "chr1", strand);
mockBasicGeneService.addAltGene("one", 10, 50)
.transcript("t1", 10, 30)
.transcript("t2", 30, 50);
return mockBasicGeneService;
}
@Test public void altSimpleTrackAllocationPositive() {
ContextMapDiagram diagram = ContextMapDiagram.forRegion(altSimple(1), "dog", "chr1", 101, 0, 100);
assertEquals(0, diagram.numberOfNegativeTracks());
assertEquals(2, diagram.numberOfPositiveTracks());
assertEquals(2, diagram.numberOfTracks());
}
@Test public void altSimpleTrackAllocationNegative() {
ContextMapDiagram diagram = ContextMapDiagram.forRegion(altSimple(-1), "dog", "chr1", 101, 0, 100);
assertEquals(2, diagram.numberOfNegativeTracks());
assertEquals(0, diagram.numberOfPositiveTracks());
assertEquals(2, diagram.numberOfTracks());
}
private BasicGeneService altOverlaps () {
MockBasicGeneService mockBasicGeneService = new MockBasicGeneService("dog", "chr1", 1);
mockBasicGeneService.addAltGene("one", 10, 50)
.transcript("t1", 10, 30)
.transcript("t2", 30, 50);
mockBasicGeneService.addSimpleGene("two", 20, 40);
mockBasicGeneService.addSimpleGene("four", 40, 60);
mockBasicGeneService.addSimpleGene("five", 50, 70);
mockBasicGeneService.addSimpleGene("six", 60, 80);
mockBasicGeneService.addSimpleGene("seven", 70, 90);
return mockBasicGeneService;
}
/**
* Test that track-allocation works correctly in the presence of alternative splicing.
*/
@Test public void altOverlapTrackAllocation() {
ContextMapDiagram diagram = ContextMapDiagram.forRegion(altOverlaps(), "dog", "chr1", 101, 0, 100);
String[][] expectedTracks = new String[][] {
new String[] {"one/t1", "six"},
new String[] {"one/t2", "seven"},
new String[] {"two", "five"},
new String[] {"four"},
null
};
assertEquals(4, diagram.numberOfPositiveTracks());
assertTrackAllocation(diagram, expectedTracks);
}
}