From f0ac588d32b4381c55a169d7659e46a1a933b582 Mon Sep 17 00:00:00 2001 From: Mark DePristo Date: Sun, 20 Nov 2011 18:28:01 -0500 Subject: [PATCH] Extensive unit test for GenotypeContextUnitTest -- Currently only tests base class. Adding subclass testing in a bit --- build.xml | 4 +- .../GenotypesContextUnitTest.java | 290 ++++++++++++++++++ 2 files changed, 292 insertions(+), 2 deletions(-) create mode 100644 public/java/test/org/broadinstitute/sting/utils/variantcontext/GenotypesContextUnitTest.java diff --git a/build.xml b/build.xml index 66d99ac67..232b074f6 100644 --- a/build.xml +++ b/build.xml @@ -927,8 +927,8 @@ - - + + diff --git a/public/java/test/org/broadinstitute/sting/utils/variantcontext/GenotypesContextUnitTest.java b/public/java/test/org/broadinstitute/sting/utils/variantcontext/GenotypesContextUnitTest.java new file mode 100644 index 000000000..a65051fae --- /dev/null +++ b/public/java/test/org/broadinstitute/sting/utils/variantcontext/GenotypesContextUnitTest.java @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2011, The Broad Institute + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +// our package +package org.broadinstitute.sting.utils.variantcontext; + + +// the imports for unit testing. + + +import org.broad.tribble.util.ParsingUtils; +import org.broadinstitute.sting.BaseTest; +import org.broadinstitute.sting.utils.Utils; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.*; + + +public class GenotypesContextUnitTest extends BaseTest { + Allele Aref, C, T; + Genotype AA, AT, TT, AC, CT, CC, MISSING; + List allGenotypes; + + @BeforeSuite + public void before() { + C = Allele.create("C"); + Aref = Allele.create("A", true); + T = Allele.create("T"); + AA = new Genotype("AA", Arrays.asList(Aref, Aref)); + AT = new Genotype("AT", Arrays.asList(Aref, T)); + TT = new Genotype("TT", Arrays.asList(T, T)); + AC = new Genotype("AC", Arrays.asList(Aref, C)); + CT = new Genotype("CT", Arrays.asList(C, T)); + CC = new Genotype("CC", Arrays.asList(C, C)); + MISSING = new Genotype("MISSING", Arrays.asList(C, C)); + + allGenotypes = Arrays.asList(AA, AT, TT, AC, CT, CC); + } + + // -------------------------------------------------------------------------------- + // + // Provider + // + // -------------------------------------------------------------------------------- + + private interface ContextMaker { + public GenotypesContext make(List initialSamples); + } + + private ContextMaker baseMaker = new ContextMaker() { + @Override + public GenotypesContext make(final List initialSamples) { + return GenotypesContext.copy(initialSamples); + } + }; + + private Collection allMakers = + Arrays.asList(baseMaker); + + private class GenotypesContextProvider extends TestDataProvider { + ContextMaker maker; + final List initialSamples; + + private GenotypesContextProvider(ContextMaker maker, List initialSamples) { + super(GenotypesContextProvider.class); + this.maker = maker; + this.initialSamples = initialSamples; + } + + public GenotypesContext makeContext() { + return maker.make(initialSamples); + } + } + + @DataProvider(name = "GenotypesContextProvider") + public Object[][] MakeSampleNamesTest() { + for ( ContextMaker maker : allMakers ) { + for ( int i = 0; i < allGenotypes.size(); i++ ) { + List samples = allGenotypes.subList(0, i); + // sorted + new GenotypesContextProvider(maker, samples); + // unsorted + new GenotypesContextProvider(maker, Utils.reverse(samples)); + } + } + + return GenotypesContextProvider.getTests(GenotypesContextProvider.class); + } + + private final static void testIterable(Iterable genotypeIterable, Set expectedNames) { + int count = 0; + for ( final Genotype g : genotypeIterable ) { + Assert.assertTrue(expectedNames.contains(g.getSampleName())); + count++; + } + Assert.assertEquals(count, expectedNames.size(), "Iterable returned unexpected number of genotypes"); + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testInitialSamplesAreAsExpected(GenotypesContextProvider cfg) { + testGenotypesContextContainsExpectedSamples(cfg.makeContext(), cfg.initialSamples); + } + + private final void testGenotypesContextContainsExpectedSamples(GenotypesContext gc, List expectedSamples) { + Assert.assertEquals(gc.isEmpty(), expectedSamples.isEmpty()); + Assert.assertEquals(gc.size(), expectedSamples.size()); + + // get(index) is doing the right thing + for ( int i = 0; i < expectedSamples.size(); i++ ) { + Assert.assertEquals(gc.get(i), expectedSamples.get(i)); + } + Assert.assertFalse(gc.containsSample(MISSING.getSampleName())); + + // we can fetch samples by name + final Set genotypeNames = VariantContextUtils.genotypeNames(expectedSamples); + for ( final String name : genotypeNames ) { + Assert.assertTrue(gc.containsSample(name)); + } + Assert.assertFalse(gc.containsSample(MISSING.getSampleName())); + + // all of the iterators are working + testIterable(gc.iterateInSampleNameOrder(), genotypeNames); + testIterable(gc, genotypeNames); + testIterable(gc.iterateInSampleNameOrder(genotypeNames), genotypeNames); + if ( ! genotypeNames.isEmpty() ) { + Set first = Collections.singleton(genotypeNames.iterator().next()); + testIterable(gc.iterateInSampleNameOrder(first), first); + } + + // misc. utils are working as expected + Assert.assertEquals(gc.getSampleNames(), genotypeNames); + Assert.assertTrue(ParsingUtils.isSorted(gc.getSampleNamesOrderedByName())); + Assert.assertTrue(ParsingUtils.isSorted(gc.iterateInSampleNameOrder())); + Assert.assertTrue(gc.containsSamples(genotypeNames)); + + final Set withMissing = new HashSet(Arrays.asList(MISSING.getSampleName())); + withMissing.addAll(genotypeNames); + Assert.assertFalse(gc.containsSamples(withMissing)); + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testImmutable(GenotypesContextProvider cfg) { + GenotypesContext gc = cfg.makeContext(); + Assert.assertEquals(gc.isMutable(), true); + gc.immutable(); + Assert.assertEquals(gc.isMutable(), false); + } + + @Test(dataProvider = "GenotypesContextProvider", expectedExceptions = Throwable.class ) + public void testImmutableCall1(GenotypesContextProvider cfg) { + GenotypesContext gc = cfg.makeContext(); + gc.immutable(); + gc.add(MISSING); + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testClear(GenotypesContextProvider cfg) { + GenotypesContext gc = cfg.makeContext(); + gc.clear(); + testGenotypesContextContainsExpectedSamples(gc, Collections.emptyList()); + } + + private static final List with(List genotypes, Genotype ... add) { + List l = new ArrayList(genotypes); + l.addAll(Arrays.asList(add)); + return l; + } + + private static final List without(List genotypes, Genotype ... remove) { + List l = new ArrayList(genotypes); + l.removeAll(Arrays.asList(remove)); + return l; + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testAdds(GenotypesContextProvider cfg) { + Genotype add1 = new Genotype("add1", Arrays.asList(Aref, Aref)); + Genotype add2 = new Genotype("add2", Arrays.asList(Aref, Aref)); + + GenotypesContext gc = cfg.makeContext(); + gc.add(add1); + testGenotypesContextContainsExpectedSamples(gc, with(cfg.initialSamples, add1)); + + gc = cfg.makeContext(); + gc.add(add1); + gc.add(add2); + testGenotypesContextContainsExpectedSamples(gc, with(cfg.initialSamples, add1, add2)); + + gc = cfg.makeContext(); + gc.add(add1, add2); + testGenotypesContextContainsExpectedSamples(gc, with(cfg.initialSamples, add1, add2)); + + gc = cfg.makeContext(); + gc.addAll(Arrays.asList(add1, add2)); + testGenotypesContextContainsExpectedSamples(gc, with(cfg.initialSamples, add1, add2)); + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testRemoves(GenotypesContextProvider cfg) { + Genotype rm1 = AA; + Genotype rm2 = AC; + + GenotypesContext gc = cfg.makeContext(); + if (gc.size() > 1) { + Genotype rm = gc.get(0); + gc.remove(rm); + testGenotypesContextContainsExpectedSamples(gc, without(cfg.initialSamples, rm)); + } + + gc = cfg.makeContext(); + gc.remove(rm1); + testGenotypesContextContainsExpectedSamples(gc, without(cfg.initialSamples, rm1)); + + gc = cfg.makeContext(); + gc.remove(rm1); + gc.remove(rm2); + testGenotypesContextContainsExpectedSamples(gc, without(cfg.initialSamples, rm1, rm2)); + + gc = cfg.makeContext(); + gc.removeAll(Arrays.asList(rm1, rm2)); + testGenotypesContextContainsExpectedSamples(gc, without(cfg.initialSamples, rm1, rm2)); + + gc = cfg.makeContext(); + HashSet expected = new HashSet(); + if ( gc.contains(rm1) ) expected.add(rm1); + if ( gc.contains(rm2) ) expected.add(rm2); + gc.retainAll(Arrays.asList(rm1, rm2)); + + // ensure that the two lists are the same + Assert.assertEquals(new HashSet(gc.getGenotypes()), expected); + // because the list order can change, we use the gc's list itself + testGenotypesContextContainsExpectedSamples(gc, gc.getGenotypes()); + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testSet(GenotypesContextProvider cfg) { + Genotype set = new Genotype("replace", Arrays.asList(Aref, Aref)); + int n = cfg.makeContext().size(); + for ( int i = 0; i < n; i++ ) { + GenotypesContext gc = cfg.makeContext(); + Genotype setted = gc.set(i, set); + Assert.assertNotNull(setted); + ArrayList l = new ArrayList(cfg.initialSamples); + l.set(i, set); + testGenotypesContextContainsExpectedSamples(gc, l); + } + } + + @Test(dataProvider = "GenotypesContextProvider") + public void testReplace(GenotypesContextProvider cfg) { + int n = cfg.makeContext().size(); + for ( int i = 0; i < n; i++ ) { + GenotypesContext gc = cfg.makeContext(); + Genotype toReplace = gc.get(i); + Genotype replacement = new Genotype(toReplace.getSampleName(), Arrays.asList(Aref, Aref)); + gc.replace(replacement); + ArrayList l = new ArrayList(cfg.initialSamples); + l.set(i, replacement); + Assert.assertEquals(replacement, gc.get(i)); + testGenotypesContextContainsExpectedSamples(gc, l); + } + } + + // subset to samples tested in VariantContextUnitTest +} \ No newline at end of file